mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-11-07 02:38:08 +01:00
Merge branch 'master' into fix/sonar-reliability-security
This commit is contained in:
@@ -20,7 +20,8 @@ class TLPT;
|
||||
class TKeyTrans
|
||||
{ // przekodowanie kodu naciśnięcia i zwolnienia klawisza
|
||||
public:
|
||||
short int iDown, iUp;
|
||||
short int iDown;
|
||||
short int iUp;
|
||||
};
|
||||
|
||||
class Console
|
||||
|
||||
116
McZapkie/MOVER.h
116
McZapkie/MOVER.h
@@ -764,7 +764,7 @@ enum class TLocalBrake
|
||||
HydraulicBrake
|
||||
};
|
||||
/// <summary>Brake delay parameter table (apply/release for passenger and freight).</summary>
|
||||
typedef double TBrakeDelayTable[4];
|
||||
using TBrakeDelayTable = double[4];
|
||||
|
||||
/// <summary>One row of the brake pressure / pipe pressure / flow-speed table for a brake handle position.</summary>
|
||||
struct TBrakePressure
|
||||
@@ -780,7 +780,7 @@ struct TBrakePressure
|
||||
};
|
||||
|
||||
/// <summary>Brake pressure table indexed by handle position.</summary>
|
||||
typedef std::map<int, TBrakePressure> TBrakePressureTable;
|
||||
using TBrakePressureTable = std::map<int, TBrakePressure>;
|
||||
|
||||
/// <summary>Engine / drive type.</summary>
|
||||
enum class TEngineType
|
||||
@@ -989,11 +989,11 @@ struct TTransducer
|
||||
struct TPowerParameters
|
||||
{
|
||||
/// <summary>Maximum source voltage [V].</summary>
|
||||
double MaxVoltage;
|
||||
double MaxVoltage{0.0};
|
||||
/// <summary>Maximum source current [A].</summary>
|
||||
double MaxCurrent;
|
||||
double MaxCurrent{0.0};
|
||||
/// <summary>Internal resistance [Ω].</summary>
|
||||
double IntR;
|
||||
double IntR{0.001};
|
||||
/// <summary>Type of source (selects which union member is meaningful).</summary>
|
||||
TPowerSource SourceType;
|
||||
union
|
||||
@@ -1029,9 +1029,6 @@ struct TPowerParameters
|
||||
};
|
||||
inline TPowerParameters()
|
||||
{
|
||||
MaxVoltage = 0.0;
|
||||
MaxCurrent = 0.0;
|
||||
IntR = 0.001;
|
||||
SourceType = TPowerSource::NotDefined;
|
||||
PowerType = TPowerType::NoPower;
|
||||
RPowerCable.PowerTrans = TPowerType::NoPower;
|
||||
@@ -1048,7 +1045,7 @@ struct TScheme
|
||||
bool AutoSwitch = false; /*czy dana pozycja nastawniana jest recznie czy autom.*/
|
||||
int ScndAct = 0; /*jesli ma bocznik w nastawniku, to ktory bocznik na ktorej pozycji*/
|
||||
};
|
||||
typedef TScheme TSchemeTable[ResArraySize + 1]; /*tablica rezystorow rozr.*/
|
||||
using TSchemeTable = TScheme[ResArraySize + 1]; /*tablica rezystorow rozr.*/
|
||||
struct TDEScheme
|
||||
{
|
||||
double RPM = 0.0; /*obroty diesla*/
|
||||
@@ -1056,13 +1053,13 @@ struct TDEScheme
|
||||
double Umax = 0.0; /*napiecie maksymalne*/
|
||||
double Imax = 0.0; /*prad maksymalny*/
|
||||
};
|
||||
typedef TDEScheme TDESchemeTable[33]; /*tablica WWList dla silnikow spalinowych*/
|
||||
using TDESchemeTable = TDEScheme[33]; /*tablica WWList dla silnikow spalinowych*/
|
||||
struct TFFScheme
|
||||
{
|
||||
double v = 0.0; // parametr wejsciowy
|
||||
double freq = 0.0; // wyjscie: czestotliwosc falownika
|
||||
};
|
||||
typedef TFFScheme TFFSchemeTable[33];
|
||||
using TFFSchemeTable = TFFScheme[33];
|
||||
|
||||
struct TWiperScheme
|
||||
{
|
||||
@@ -1071,7 +1068,7 @@ struct TWiperScheme
|
||||
double interval = 0.0; // interwal pracy wycieraczki
|
||||
double outBackDelay = 0.0; // czas po jakim wycieraczka zacznie wracac z konca do poczatku
|
||||
};
|
||||
typedef TWiperScheme TWiperSchemeTable[16];
|
||||
using TWiperSchemeTable = TWiperScheme[16];
|
||||
|
||||
struct TShuntScheme
|
||||
{
|
||||
@@ -1080,33 +1077,23 @@ struct TShuntScheme
|
||||
double Pmin = 0.0;
|
||||
double Pmax = 0.0;
|
||||
};
|
||||
typedef TShuntScheme TShuntSchemeTable[33];
|
||||
using TShuntSchemeTable = TShuntScheme[33];
|
||||
struct TMPTRelay
|
||||
{ /*lista przekaznikow bocznikowania*/
|
||||
double Iup = 0.0;
|
||||
double Idown = 0.0;
|
||||
};
|
||||
typedef TMPTRelay TMPTRelayTable[MotorParametersArraySize + 1]; // indexed like MotorParam
|
||||
using TMPTRelayTable = TMPTRelay[MotorParametersArraySize + 1]; // indexed like MotorParam
|
||||
|
||||
struct TMotorParameters
|
||||
{
|
||||
double mfi;
|
||||
double mIsat;
|
||||
double mfi0; // aproksymacja M(I) silnika} {dla dizla mIsat=przekladnia biegu
|
||||
double fi;
|
||||
double Isat;
|
||||
double fi0; // aproksymacja E(n)=fi*n} {dla dizla fi, mfi: predkosci przelozenia biegu <->
|
||||
bool AutoSwitch;
|
||||
TMotorParameters()
|
||||
{
|
||||
mfi = 0.0;
|
||||
mIsat = 0.0;
|
||||
mfi0 = 0.0;
|
||||
fi = 0.0;
|
||||
Isat = 0.0;
|
||||
fi0 = 0.0;
|
||||
AutoSwitch = false;
|
||||
}
|
||||
double mfi{0.0};
|
||||
double mIsat{0.0};
|
||||
double mfi0{0.0}; // aproksymacja M(I) silnika} {dla dizla mIsat=przekladnia biegu
|
||||
double fi{0.0};
|
||||
double Isat{0.0};
|
||||
double fi0{0.0}; // aproksymacja E(n)=fi*n} {dla dizla fi, mfi: predkosci przelozenia biegu <->
|
||||
bool AutoSwitch{false};
|
||||
};
|
||||
|
||||
struct TUniversalCtrl
|
||||
@@ -1240,7 +1227,7 @@ struct TCoupling
|
||||
{
|
||||
return adapter_type != TCouplerType::NoCoupler;
|
||||
}
|
||||
inline TCouplerType const type() const
|
||||
inline TCouplerType type() const
|
||||
{
|
||||
return adapter_type == TCouplerType::NoCoupler ? CouplerType : adapter_type;
|
||||
}
|
||||
@@ -1465,7 +1452,8 @@ class TMoverParameters
|
||||
{
|
||||
float temp_min{-1}; // lowest accepted temperature
|
||||
float temp_max{-1}; // highest accepted temperature
|
||||
} config;
|
||||
};
|
||||
heater_config_t config;
|
||||
// ld inputs
|
||||
bool breaker{false}; // device is allowed to operate
|
||||
bool is_enabled{false}; // device is requested to operate
|
||||
@@ -1500,12 +1488,17 @@ class TMoverParameters
|
||||
float temp_cooling{-1}; // active cooling activation point
|
||||
float temp_flow{-1}; // fluid flow activation point
|
||||
bool shutters{false}; // the radiator has shutters to assist the cooling
|
||||
} config;
|
||||
};
|
||||
circuit_config_t config;
|
||||
bool is_cold{false}; // fluid is too cold
|
||||
bool is_warm{false}; // fluid is too hot
|
||||
bool is_hot{false}; // fluid temperature crossed cooling threshold
|
||||
bool is_flowing{false}; // fluid is being pushed through the circuit
|
||||
} water, water_aux, oil, engine;
|
||||
};
|
||||
fluid_circuit_t water;
|
||||
fluid_circuit_t water_aux;
|
||||
fluid_circuit_t oil;
|
||||
fluid_circuit_t engine;
|
||||
// output, state of affected devices
|
||||
bool PA{false}; // malfunction flag
|
||||
float rpmw{0.0}; // current main circuit fan revolutions
|
||||
@@ -1889,9 +1882,9 @@ class TMoverParameters
|
||||
double MED_Vmin = 0; // predkosc minimalna dla obliczen chwilowej sily hamowania EP w MED
|
||||
double MED_Vref = 0; // predkosc referencyjna dla obliczen dostepnej sily hamowania EP w MED
|
||||
double MED_amax{9.81}; // maksymalne opoznienie hamowania sluzbowego MED
|
||||
bool MED_EPVC = 0; // czy korekcja sily hamowania EP, gdy nie ma dostepnego ED
|
||||
bool MED_EPVC = false; // 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
|
||||
bool MED_Ncor = false; // czy korekcja sily hamowania z uwzglednieniem nacisku
|
||||
double MED_MinBrakeReqED = 0; // minimalne zadanie sily hamowania uruchamiajace ED - ponizej tylko EP
|
||||
double MED_FrED_factor = 1; // mnoznik sily hamowania ED do korekty blendingu
|
||||
double MED_ED_Delay1 = 0; // opoznienie wdrazania hamowania ED (pierwszy raz)
|
||||
@@ -2099,7 +2092,7 @@ class TMoverParameters
|
||||
int CabActive = 0; // numer kabiny, z której jest sterowanie: 1 lub -1; w przeciwnym razie brak sterowania - rozrzad
|
||||
int CabOccupied = 0; // numer kabiny, w ktorej jest obsada (zwykle jedna na skład) // TODO: move to TController
|
||||
bool CabMaster = false; // czy pojazd jest nadrzędny w składzie
|
||||
inline bool IsCabMaster()
|
||||
inline bool IsCabMaster() const
|
||||
{
|
||||
return CabActive == CabOccupied && CabMaster;
|
||||
} // czy aktualna kabina jest na pewno tą, z której można sterować
|
||||
@@ -2294,8 +2287,7 @@ class TMoverParameters
|
||||
bool AIHintPantUpIfIdle{true}; // whether raise both pantographs if idling for a while
|
||||
double AIHintLocalBrakeAccFactor{1.05}; // suggested acceleration weight for local brake operation
|
||||
|
||||
public:
|
||||
TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab);
|
||||
TMoverParameters(double VelInitial, std::string const &TypeNameInit, std::string const &NameInit, int Cab);
|
||||
// obsługa sprzęgów
|
||||
static double CouplerDist(TMoverParameters const *Left, TMoverParameters const *Right);
|
||||
static double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
||||
@@ -2307,7 +2299,7 @@ class TMoverParameters
|
||||
bool DirectionForward();
|
||||
bool DirectionBackward(void); /*! kierunek ruchu*/
|
||||
bool EIMDirectionChangeAllow(void) const;
|
||||
inline double IsVehicleEIMBrakingFactor()
|
||||
inline double IsVehicleEIMBrakingFactor() const
|
||||
{
|
||||
return DynamicBrakeFlag && ResistorsFlag ? 0.0 : eimv[eimv_Ipoj] < 0 ? -1.0 : 1.0;
|
||||
}
|
||||
@@ -2319,32 +2311,32 @@ class TMoverParameters
|
||||
bool CurrentSwitch(bool const State);
|
||||
bool IsMotorOverloadRelayHighThresholdOn() const;
|
||||
void UpdateBatteryVoltage(double dt);
|
||||
double ComputeMovement(double dt, double dt1, const TTrackShape &Shape, TTrackParam &Track, TTractionParam &ElectricTraction, TLocation const &NewLoc,
|
||||
double ComputeMovement(double dt, double dt1, const TTrackShape &Shape, TTrackParam const &Track, TTractionParam const &ElectricTraction, TLocation const &NewLoc,
|
||||
TRotation const &NewRot); // oblicza przesuniecie pojazdu
|
||||
double FastComputeMovement(double dt, const TTrackShape &Shape, TTrackParam &Track, TLocation const &NewLoc, TRotation const &NewRot); // oblicza przesuniecie pojazdu - wersja zoptymalizowana
|
||||
void compute_movement_(double const Deltatime);
|
||||
double ShowEngineRotation(int VehN);
|
||||
double ShowEngineRotation(int VehN) const;
|
||||
|
||||
// Q *******************************************************************************************
|
||||
double GetTrainsetVoltage(int const Coupling = coupling::heating | coupling::highvoltage) const;
|
||||
double GetTrainsetHighVoltage() const;
|
||||
bool switch_physics(bool const State);
|
||||
double LocalBrakeRatio(void);
|
||||
double ManualBrakeRatio(void);
|
||||
double PipeRatio(void); /*ile napelniac*/
|
||||
double RealPipeRatio(void); /*jak szybko*/
|
||||
double LocalBrakeRatio(void) const;
|
||||
double ManualBrakeRatio(void) const;
|
||||
double PipeRatio(void) const; /*ile napelniac*/
|
||||
double RealPipeRatio(void) const; /*jak szybko*/
|
||||
double BrakeVP(void) const;
|
||||
double EngineRPMRatio() const; // returns current engine revolutions as percentage of max engine revolutions, in range 0-1
|
||||
double EngineIdleRPM() const;
|
||||
double EngineMaxRPM() const;
|
||||
|
||||
/*! przesylanie komend sterujacych*/
|
||||
bool SendCtrlToNext(std::string const CtrlCommand, double const ctrlvalue, double const dir, int const Couplertype = coupling::control);
|
||||
bool SetInternalCommand(std::string NewCommand, double NewValue1, double NewValue2, int const Couplertype = coupling::control);
|
||||
double GetExternalCommand(std::string &Command);
|
||||
bool RunCommand(std::string Command, double CValue1, double CValue2, int const Couplertype = coupling::control);
|
||||
bool SendCtrlToNext(std::string const &CtrlCommand, double const ctrlvalue, double const dir, int const Couplertype = coupling::control);
|
||||
bool SetInternalCommand(std::string const &NewCommand, double NewValue1, double NewValue2, int const Couplertype = coupling::control);
|
||||
double GetExternalCommand(std::string &Command) const;
|
||||
bool RunCommand(std::string const &Command, double CValue1, double CValue2, int const Couplertype = coupling::control);
|
||||
bool RunInternalCommand();
|
||||
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation);
|
||||
void PutCommand(std::string const &NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation);
|
||||
bool CabActivisation(bool const Enforce = false);
|
||||
bool CabDeactivisation(bool const Enforce = false);
|
||||
bool CabActivisationAuto(bool const Enforce = false);
|
||||
@@ -2363,7 +2355,7 @@ class TMoverParameters
|
||||
/*! pomocniczy nastawnik:*/
|
||||
bool IncScndCtrl(int CtrlSpeed);
|
||||
bool DecScndCtrl(int CtrlSpeed);
|
||||
int GetVirtualScndPos();
|
||||
int GetVirtualScndPos() const;
|
||||
bool IsScndCtrlNoPowerPos() const;
|
||||
bool IsScndCtrlMaxPowerPos() const;
|
||||
|
||||
@@ -2430,7 +2422,7 @@ class TMoverParameters
|
||||
double TractionForce(double dt);
|
||||
double FrictionForce() const;
|
||||
double BrakeForceR(double ratio, double velocity);
|
||||
double BrakeForceP(double press, double velocity);
|
||||
double BrakeForceP(double press, double velocity) const;
|
||||
double BrakeForce(const TTrackParam &Track);
|
||||
double CouplerForce(int const End, double dt);
|
||||
void CollisionDetect(int const End, double const dt);
|
||||
@@ -2488,8 +2480,8 @@ class TMoverParameters
|
||||
/*funkcje uzalezniajace sile pociagowa od predkosci: v2n, n2r, current, momentum*/
|
||||
double v2n(void);
|
||||
double Current(double n, double U);
|
||||
double Momentum(double I);
|
||||
double MomentumF(double I, double Iw, int SCP);
|
||||
double Momentum(double I) const;
|
||||
double MomentumF(double I, double Iw, int SCP) const;
|
||||
|
||||
bool CutOffEngine(void); // odlaczenie udszkodzonych silnikow
|
||||
/*funkcje automatycznego rozruchu np EN57*/
|
||||
@@ -2526,7 +2518,7 @@ class TMoverParameters
|
||||
|
||||
/* funckje dla wagonow*/
|
||||
bool AssignLoad(std::string const &Name, float const Amount = 0.f);
|
||||
bool LoadingDone(double LSpeed, std::string const &Loadname);
|
||||
bool LoadingDone(double LSpeed, std::string_view Loadname);
|
||||
bool PermitDoors(side const Door, bool const State = true, range_t const Notify = range_t::consist);
|
||||
void PermitDoors_(side const Door, bool const State = true);
|
||||
bool ChangeDoorPermitPreset(int const Change, range_t const Notify = range_t::consist);
|
||||
@@ -2541,7 +2533,7 @@ class TMoverParameters
|
||||
bool ChangeOffsetH(double DeltaOffset);
|
||||
|
||||
/*funkcje ladujace pliki opisujace pojazd*/
|
||||
bool LoadFIZ(std::string chkpath); // Q 20160717 bool LoadChkFile(std::string chkpath);
|
||||
bool LoadFIZ(std::string const &chkpath); // Q 20160717 bool LoadChkFile(std::string chkpath);
|
||||
bool CheckLocomotiveParameters(bool ReadyFlag, int Dir);
|
||||
std::string EngineDescription(int what) const;
|
||||
|
||||
@@ -2577,10 +2569,10 @@ class TMoverParameters
|
||||
void LoadFIZ_LightsList(std::string const &Input);
|
||||
void LoadFIZ_DimmerList(std::string const &Input);
|
||||
void LoadFIZ_CompressorList(std::string const &Input);
|
||||
void LoadFIZ_PowerParamsDecode(TPowerParameters &Powerparameters, std::string const Prefix, std::string const &Input);
|
||||
TPowerType LoadFIZ_PowerDecode(std::string const &Power);
|
||||
TPowerSource LoadFIZ_SourceDecode(std::string const &Source);
|
||||
TEngineType LoadFIZ_EngineDecode(std::string const &Engine);
|
||||
void LoadFIZ_PowerParamsDecode(TPowerParameters &Powerparameters, std::string const &Prefix, std::string const &Input);
|
||||
TPowerType LoadFIZ_PowerDecode(std::string const &Power) const;
|
||||
TPowerSource LoadFIZ_SourceDecode(std::string const &Source) const;
|
||||
TEngineType LoadFIZ_EngineDecode(std::string const &Engine) const;
|
||||
bool readMPT0(std::string const &line);
|
||||
bool readMPT(std::string const &line); // Q 20160717
|
||||
bool readMPTElectricSeries(std::string const &line);
|
||||
|
||||
1758
McZapkie/Mover.cpp
1758
McZapkie/Mover.cpp
File diff suppressed because it is too large
Load Diff
@@ -211,7 +211,7 @@ double TNESt3::GetPF( double const PP, double const dt, double const Vel ) // pr
|
||||
double dV{ 0.0 };
|
||||
double dV1{ 0.0 };
|
||||
|
||||
double const nastG = static_cast<double>(BrakeDelayFlag & bdelay_G);
|
||||
auto const nastG = static_cast<double>(BrakeDelayFlag & bdelay_G);
|
||||
|
||||
// sprawdzanie stanu
|
||||
CheckState(BCP, dV1);
|
||||
@@ -294,8 +294,9 @@ double TNESt3::GetPF( double const PP, double const dt, double const Vel ) // pr
|
||||
return dV - dV1;
|
||||
}
|
||||
|
||||
void TNESt3::EStParams( double const i_crc ) // parametry charakterystyczne dla ESt
|
||||
void TNESt3::EStParams( double const /*i_crc*/ ) const // parametry charakterystyczne dla ESt
|
||||
{
|
||||
// no effect for this device type
|
||||
}
|
||||
|
||||
void TNESt3::Init( double const PP, double const HPP, double const LPP, double const BP, int const BDF )
|
||||
@@ -318,7 +319,9 @@ void TNESt3::Init( double const PP, double const HPP, double const LPP, double c
|
||||
|
||||
Zamykajacy = false;
|
||||
|
||||
if ( typeid(*FM) == typeid(TDisk1) || typeid(*FM) == typeid(TDisk2) ) // jesli zeliwo to schodz
|
||||
auto const &frictionmaterial { *FM };
|
||||
auto const &frictionmaterialtype { typeid( frictionmaterial ) };
|
||||
if ( frictionmaterialtype == typeid(TDisk1) || frictionmaterialtype == typeid(TDisk2) ) // jesli zeliwo to schodz
|
||||
RapidStaly = true;
|
||||
else
|
||||
RapidStaly = false;
|
||||
@@ -331,9 +334,8 @@ double TNESt3::GetCRP()
|
||||
// return Miedzypoj.P;
|
||||
}
|
||||
|
||||
void TNESt3::CheckState(double const BCP, double &dV1) // glowny przyrzad rozrzadczy
|
||||
void TNESt3::CheckState(double const BCP, double & /*dV1*/) // glowny przyrzad rozrzadczy
|
||||
{
|
||||
double const BVP{ BrakeRes->P() }; //-> tu ma byc komora rozprezna
|
||||
double const VVP{ ValveRes->P() };
|
||||
double const CVP{ CntrlRes->P() };
|
||||
double const MPP{ Miedzypoj->P() };
|
||||
@@ -355,14 +357,14 @@ void TNESt3::CheckState(double const BCP, double &dV1) // glowny przyrzad rozrza
|
||||
if( ( BrakeStatus & b_hld ) == 0 )
|
||||
SoundFlag |= sf_CylU;
|
||||
|
||||
if (VVP + 0.10 < CVP && BCP < 0.25) // poczatek hamowania
|
||||
if (false == Przys_blok)
|
||||
{
|
||||
ValveRes->CreatePress(0.1 * VVP);
|
||||
SoundFlag |= sf_Acc;
|
||||
ValveRes->Act();
|
||||
Przys_blok = true;
|
||||
}
|
||||
// poczatek hamowania
|
||||
if (VVP + 0.10 < CVP && BCP < 0.25 && false == Przys_blok)
|
||||
{
|
||||
ValveRes->CreatePress(0.1 * VVP);
|
||||
SoundFlag |= sf_Acc;
|
||||
ValveRes->Act();
|
||||
Przys_blok = true;
|
||||
}
|
||||
|
||||
if (BCP > 0.5)
|
||||
Zamykajacy = true;
|
||||
@@ -384,7 +386,7 @@ void TNESt3::CheckReleaser(double const dt) // odluzniacz
|
||||
}
|
||||
}
|
||||
|
||||
double TNESt3::CVs(double const BP) // napelniacz sterujacego
|
||||
double TNESt3::CVs(double const /*BP*/) const // napelniacz sterujacego
|
||||
{
|
||||
double const CVP{ CntrlRes->P() };
|
||||
double const MPP{ Miedzypoj->P() };
|
||||
@@ -398,7 +400,7 @@ double TNESt3::CVs(double const BP) // napelniacz sterujacego
|
||||
return Nozzles[dSm];
|
||||
}
|
||||
|
||||
double TNESt3::BVs(double const BCP) // napelniacz pomocniczego
|
||||
double TNESt3::BVs(double const BCP) const // napelniacz pomocniczego
|
||||
{
|
||||
double const CVP{ CntrlRes->P() };
|
||||
double const MPP{ Miedzypoj->P() };
|
||||
@@ -637,9 +639,9 @@ void TNESt3::SetSize( int const size, std::string const ¶ms ) // ustawianie
|
||||
Nozzles[dSm] = 0.9;
|
||||
|
||||
// przeliczanie z mm^2 na l/m
|
||||
for (int i = 0; i < dMAX; ++i)
|
||||
for (auto &nozzle : Nozzles)
|
||||
{
|
||||
Nozzles[i] = d2A(Nozzles[i]); //(/1000^2*pi/4*1000)
|
||||
nozzle = d2A(nozzle); //(/1000^2*pi/4*1000)
|
||||
}
|
||||
for (int i = 1; i < 4; ++i)
|
||||
{
|
||||
|
||||
@@ -70,38 +70,32 @@ static int const P_ed = 5;
|
||||
class TPrzekladnik : public TReservoir // przekladnik (powtarzacz)
|
||||
|
||||
{
|
||||
private:
|
||||
public:
|
||||
std::shared_ptr<TReservoir> BrakeRes;
|
||||
std::shared_ptr<TReservoir> Next;
|
||||
|
||||
TPrzekladnik() : TReservoir() {};
|
||||
using TReservoir::TReservoir;
|
||||
virtual void Update(double dt);
|
||||
};
|
||||
|
||||
class TRura : public TPrzekladnik // nieprzekladnik, rura laczaca
|
||||
|
||||
{
|
||||
private:
|
||||
public:
|
||||
TRura() : TPrzekladnik() {};
|
||||
virtual double P(void) /*override*/;
|
||||
virtual void Update(double dt) /*override*/;
|
||||
using TPrzekladnik::TPrzekladnik;
|
||||
double P(void) override;
|
||||
void Update(double dt) override;
|
||||
};
|
||||
|
||||
class TPrzeciwposlizg : public TRura // przy napelnianiu - rura, przy poslizgu - upust
|
||||
|
||||
{
|
||||
private:
|
||||
bool Poslizg;
|
||||
bool Poslizg{false};
|
||||
|
||||
public:
|
||||
void SetPoslizg(bool flag);
|
||||
void Update(double dt) /*override*/;
|
||||
inline TPrzeciwposlizg() : TRura()
|
||||
{
|
||||
Poslizg = false;
|
||||
}
|
||||
void Update(double dt) override;
|
||||
};
|
||||
|
||||
// przekladnik dwustopniowy
|
||||
@@ -117,10 +111,8 @@ class TRapid : public TPrzekladnik {
|
||||
public:
|
||||
void SetRapidParams(double mult, double size);
|
||||
void SetRapidStatus(bool rs);
|
||||
void Update(double dt) /*override*/;
|
||||
inline TRapid() :
|
||||
TPrzekladnik()
|
||||
{}
|
||||
void Update(double dt) override;
|
||||
using TPrzekladnik::TPrzekladnik;
|
||||
};
|
||||
|
||||
// AL2
|
||||
@@ -131,10 +123,8 @@ class TPrzekCiagly : public TPrzekladnik {
|
||||
|
||||
public:
|
||||
void SetMult(double m);
|
||||
void Update(double dt) /*override*/;
|
||||
inline TPrzekCiagly() :
|
||||
TPrzekladnik()
|
||||
{}
|
||||
void Update(double dt) override;
|
||||
using TPrzekladnik::TPrzekladnik;
|
||||
};
|
||||
|
||||
// podwojny zawor zwrotny
|
||||
@@ -145,20 +135,15 @@ class TPrzek_PZZ : public TPrzekladnik {
|
||||
|
||||
public:
|
||||
void SetLBP(double P);
|
||||
void Update(double dt) /*override*/;
|
||||
inline TPrzek_PZZ() :
|
||||
TPrzekladnik()
|
||||
{}
|
||||
void Update(double dt) override;
|
||||
using TPrzekladnik::TPrzekladnik;
|
||||
};
|
||||
|
||||
class TPrzekZalamany : public TPrzekladnik // Knicksventil
|
||||
|
||||
{
|
||||
private:
|
||||
public:
|
||||
TPrzekZalamany() :
|
||||
TPrzekladnik()
|
||||
{}
|
||||
using TPrzekladnik::TPrzekladnik;
|
||||
};
|
||||
|
||||
// przy napelnianiu - rura, przy hamowaniu - upust
|
||||
@@ -169,10 +154,8 @@ class TPrzekED : public TRura {
|
||||
|
||||
public:
|
||||
void SetP(double P);
|
||||
void Update(double dt) /*override*/;
|
||||
inline TPrzekED() :
|
||||
TRura()
|
||||
{}
|
||||
void Update(double dt) override;
|
||||
using TRura::TRura;
|
||||
};
|
||||
|
||||
class TNESt3 : public TBrake {
|
||||
@@ -206,22 +189,20 @@ class TNESt3 : public TBrake {
|
||||
double LBP = 0.0; // cisnienie hamulca pomocniczego
|
||||
|
||||
public:
|
||||
inline TNESt3(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) :
|
||||
TBrake( i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
|
||||
{}
|
||||
void Init( double const PP, double const HPP, double const LPP, double const BP, int const BDF ) /*override*/;
|
||||
virtual double GetPF( double const PP, double const dt, double const Vel ) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
void EStParams(double i_crc); // parametry charakterystyczne dla ESt
|
||||
virtual double GetCRP() /*override*/;
|
||||
using TBrake::TBrake;
|
||||
void Init( double const PP, double const HPP, double const LPP, double const BP, int const BDF ) override;
|
||||
double GetPF( double const PP, double const dt, double const Vel ) override; // przeplyw miedzy komora wstepna i PG
|
||||
void EStParams(double i_crc) const; // parametry charakterystyczne dla ESt
|
||||
double GetCRP() override;
|
||||
void CheckState(double const BCP, double &dV1); // glowny przyrzad rozrzadczy
|
||||
void CheckReleaser(double const dt); // odluzniacz
|
||||
double CVs(double const BP); // napelniacz sterujacego
|
||||
double BVs(double const BCP); // napelniacz pomocniczego
|
||||
double CVs(double const BP) const; // napelniacz sterujacego
|
||||
double BVs(double const BCP) const; // napelniacz pomocniczego
|
||||
void SetSize( int const size, std::string const ¶ms ); // ustawianie dysz (rozmiaru ZR), przekladniki
|
||||
void PLC(double const mass); // wspolczynnik cisnienia przystawki wazacej
|
||||
void SetLP(double const TM, double const LM, double const TBP); // parametry przystawki wazacej
|
||||
virtual void ForceEmptiness() /*override*/; // wymuszenie bycia pustym
|
||||
void SetLBP(double const P); // cisnienie z hamulca pomocniczego
|
||||
void PLC(double const mass) override; // wspolczynnik cisnienia przystawki wazacej
|
||||
void SetLP(double const TM, double const LM, double const TBP) override; // parametry przystawki wazacej
|
||||
void ForceEmptiness() override; // wymuszenie bycia pustym
|
||||
void SetLBP(double const P) override; // cisnienie z hamulca pomocniczego
|
||||
};
|
||||
|
||||
extern double d2A( double const d );
|
||||
|
||||
@@ -41,6 +41,7 @@ class TFricMat
|
||||
public:
|
||||
virtual double GetFC(double N, double Vel);
|
||||
|
||||
virtual ~TFricMat() = default;
|
||||
};
|
||||
|
||||
|
||||
@@ -49,7 +50,7 @@ class TP10Bg: public TFricMat
|
||||
|
||||
{
|
||||
public:
|
||||
double GetFC(double N, double Vel)/*override*/;
|
||||
double GetFC(double N, double Vel) override;
|
||||
|
||||
};
|
||||
|
||||
@@ -59,7 +60,7 @@ class TP10Bgu: public TFricMat
|
||||
|
||||
{
|
||||
public:
|
||||
double GetFC(double N, double Vel)/*override*/;
|
||||
double GetFC(double N, double Vel) override;
|
||||
|
||||
};
|
||||
|
||||
@@ -69,7 +70,7 @@ class TP10yBg: public TFricMat
|
||||
|
||||
{
|
||||
public:
|
||||
double GetFC(double N, double Vel)/*override*/;
|
||||
double GetFC(double N, double Vel) override;
|
||||
|
||||
};
|
||||
|
||||
@@ -79,7 +80,7 @@ class TP10yBgu: public TFricMat
|
||||
|
||||
{
|
||||
public:
|
||||
double GetFC(double N, double Vel)/*override*/;
|
||||
double GetFC(double N, double Vel) override;
|
||||
|
||||
};
|
||||
|
||||
@@ -89,7 +90,7 @@ class TP10: public TFricMat
|
||||
|
||||
{
|
||||
public:
|
||||
double GetFC(double N, double Vel)/*override*/;
|
||||
double GetFC(double N, double Vel) override;
|
||||
|
||||
};
|
||||
|
||||
@@ -99,7 +100,7 @@ class TFR513: public TFricMat
|
||||
|
||||
{
|
||||
public:
|
||||
double GetFC(double N, double Vel)/*override*/;
|
||||
double GetFC(double N, double Vel) override;
|
||||
|
||||
};
|
||||
|
||||
@@ -109,7 +110,7 @@ class TFR510: public TFricMat
|
||||
|
||||
{
|
||||
public:
|
||||
double GetFC(double N, double Vel)/*override*/;
|
||||
double GetFC(double N, double Vel) override;
|
||||
|
||||
};
|
||||
|
||||
@@ -119,7 +120,7 @@ class TCosid: public TFricMat
|
||||
|
||||
{
|
||||
public:
|
||||
double GetFC(double N, double Vel)/*override*/;
|
||||
double GetFC(double N, double Vel) override;
|
||||
|
||||
};
|
||||
|
||||
@@ -129,7 +130,7 @@ class TDisk1: public TFricMat
|
||||
|
||||
{
|
||||
public:
|
||||
double GetFC(double N, double Vel)/*override*/;
|
||||
double GetFC(double N, double Vel) override;
|
||||
|
||||
};
|
||||
|
||||
@@ -139,7 +140,7 @@ class TDisk2: public TFricMat
|
||||
|
||||
{
|
||||
public:
|
||||
double GetFC(double N, double Vel)/*override*/;
|
||||
double GetFC(double N, double Vel) override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -357,21 +357,14 @@ end ; */
|
||||
/// <param name="i_mat">Friction material id (bp_* constant, optionally OR'ed with bp_MHS).</param>
|
||||
/// <param name="i_ba">Number of braked axles.</param>
|
||||
/// <param name="i_nbpa">Number of blocks per axle.</param>
|
||||
TBrake::TBrake(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)
|
||||
TBrake::TBrake(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) :
|
||||
BCN(i_bcn), BCM(1), BCA(i_bcn * i_bcr * i_bcr * M_PI), BrakeDelays(i_BD), MaxBP(i_mbp), BA(i_ba), NBpA(i_nbpa), SizeBR(i_brc * 0.0128)
|
||||
{
|
||||
// inherited:: Create;
|
||||
MaxBP = i_mbp;
|
||||
BCN = i_bcn;
|
||||
BCM = 1;
|
||||
BCA = i_bcn * i_bcr * i_bcr * M_PI;
|
||||
BA = i_ba;
|
||||
NBpA = i_nbpa;
|
||||
BrakeDelays = i_BD;
|
||||
BrakeDelayFlag = bdelay_P;
|
||||
// 210.88
|
||||
// SizeBR:=i_bcn*i_bcr*i_bcr*i_bcd*40.17*MaxBP/(5-MaxBP); //objetosc ZP w stosunku do cylindra
|
||||
// 14" i cisnienia 4.2 atm
|
||||
SizeBR = i_brc * 0.0128;
|
||||
SizeBC = i_bcn * i_bcr * i_bcr * i_bcd * 210.88 * MaxBP / 4.2; // objetosc CH w stosunku do cylindra 14" i cisnienia 4.2 atm
|
||||
|
||||
BrakeCyl = std::make_shared<TBrakeCyl>();
|
||||
@@ -450,7 +443,7 @@ double TBrake::GetFC(double const Vel, double const N)
|
||||
|
||||
/// <summary>Returns the gauge pressure inside the brake cylinder.</summary>
|
||||
// cisnienie cylindra hamulcowego
|
||||
double TBrake::GetBCP()
|
||||
double TBrake::GetBCP() const
|
||||
{
|
||||
return BrakeCyl->P();
|
||||
}
|
||||
@@ -464,14 +457,14 @@ double TBrake::GetEDBCP()
|
||||
|
||||
/// <summary>Returns the auxiliary reservoir (ZP) pressure.</summary>
|
||||
// cisnienie zbiornika pomocniczego
|
||||
double TBrake::GetBRP()
|
||||
double TBrake::GetBRP() const
|
||||
{
|
||||
return BrakeRes->P();
|
||||
}
|
||||
|
||||
/// <summary>Returns the valve pre-chamber pressure.</summary>
|
||||
// cisnienie komory wstepnej
|
||||
double TBrake::GetVRP()
|
||||
double TBrake::GetVRP() const
|
||||
{
|
||||
return ValveRes->P();
|
||||
}
|
||||
@@ -516,7 +509,7 @@ double TBrake::GetHPFlow(double const HP, double const dt)
|
||||
/// <summary>
|
||||
/// Returns the piston force from the cylinder pressure (BCA * 100 * P).
|
||||
/// </summary>
|
||||
double TBrake::GetBCF()
|
||||
double TBrake::GetBCF() const
|
||||
{
|
||||
return BCA * 100 * BrakeCyl->P();
|
||||
}
|
||||
@@ -558,7 +551,7 @@ bool TBrake::Releaser() const
|
||||
/// support the EP brake (TWest, TEStEP1/2, ...).
|
||||
/// </summary>
|
||||
/// <param name="nEPS">EP intensity.</param>
|
||||
void TBrake::SetEPS(double const nEPS) {}
|
||||
void TBrake::SetEPS(double const nEPS) { /* no effect for this device type */ }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the anti-slip brake state flags. Bit 1 of <paramref name="state"/>
|
||||
@@ -572,7 +565,7 @@ void TBrake::ASB(int const state)
|
||||
}
|
||||
|
||||
/// <summary>Returns the raw BrakeStatus bitfield.</summary>
|
||||
int TBrake::GetStatus()
|
||||
int TBrake::GetStatus() const
|
||||
{
|
||||
return BrakeStatus;
|
||||
}
|
||||
@@ -674,14 +667,14 @@ double TWest::GetPF(double const PP, double const dt, double const Vel)
|
||||
BCP = BrakeCyl->P();
|
||||
|
||||
if ((BrakeStatus & b_hld) == b_hld)
|
||||
{
|
||||
if (VVP + 0.03 < BVP)
|
||||
BrakeStatus |= b_on;
|
||||
else if (VVP > BVP + 0.1)
|
||||
BrakeStatus &= ~(b_on | b_hld);
|
||||
else if (VVP > BVP)
|
||||
BrakeStatus &= ~b_on;
|
||||
else
|
||||
;
|
||||
}
|
||||
else if (VVP + 0.25 < BVP)
|
||||
BrakeStatus |= b_on | b_hld;
|
||||
|
||||
@@ -707,7 +700,6 @@ double TWest::GetPF(double const PP, double const dt, double const Vel)
|
||||
temp = BVP * int(EPS > 0);
|
||||
dv = PF(temp, LBP, 0.0015) * dt * EPS * EPS * int(LBP * EPS < MaxBP * LoadC);
|
||||
LBP = LBP - dv;
|
||||
dv = 0;
|
||||
|
||||
// przeplyw ZP <-> silowniki
|
||||
if ((BrakeStatus & b_on) == b_on && (TareBP < 0.1 || BCP < MaxBP * LoadC))
|
||||
@@ -781,20 +773,15 @@ void TWest::SetLBP(double const P)
|
||||
/// <param name="nEPS">New EP intensity.</param>
|
||||
void TWest::SetEPS(double const nEPS)
|
||||
{
|
||||
double BCP;
|
||||
|
||||
BCP = BrakeCyl->P();
|
||||
if (nEPS > 0)
|
||||
DCV = true;
|
||||
else if (nEPS == 0)
|
||||
else if (nEPS == 0 && EPS != 0)
|
||||
{
|
||||
if (EPS != 0)
|
||||
{
|
||||
if (LBP > 0.4)
|
||||
LBP = BrakeCyl->P();
|
||||
if (LBP < 0.15)
|
||||
LBP = 0;
|
||||
}
|
||||
if (LBP > 0.4)
|
||||
LBP = BrakeCyl->P();
|
||||
if (LBP < 0.15)
|
||||
LBP = 0;
|
||||
}
|
||||
EPS = nEPS;
|
||||
}
|
||||
@@ -838,12 +825,14 @@ void TESt::CheckReleaser(double const dt)
|
||||
|
||||
// odluzniacz
|
||||
if ((BrakeStatus & b_rls) == b_rls)
|
||||
{
|
||||
if (CVP - VVP < 0)
|
||||
BrakeStatus &= ~b_rls;
|
||||
else
|
||||
{
|
||||
CntrlRes->Flow(+PF(CVP, 0, 0.1) * dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -854,11 +843,10 @@ void TESt::CheckReleaser(double const dt)
|
||||
/// </summary>
|
||||
/// <param name="BCP">Brake cylinder (or impulse-chamber) pressure.</param>
|
||||
/// <param name="dV1">In/out brake-pipe flow correction (unused in this base impl).</param>
|
||||
void TESt::CheckState(double const BCP, double &dV1)
|
||||
void TESt::CheckState(double const BCP, double & /*dV1*/)
|
||||
{
|
||||
|
||||
double const VVP{ValveRes->P()};
|
||||
double const BVP{BrakeRes->P()};
|
||||
double const CVP{CntrlRes->P()};
|
||||
|
||||
// sprawdzanie stanu
|
||||
@@ -927,7 +915,7 @@ void TESt::CheckState(double const BCP, double &dV1)
|
||||
/// </summary>
|
||||
/// <param name="BP">Brake cylinder (or impulse) pressure.</param>
|
||||
/// <returns>Opening coefficient (0 closed, 1 fully open).</returns>
|
||||
double TESt::CVs(double const BP)
|
||||
double TESt::CVs(double const BP) const
|
||||
{
|
||||
double VVP;
|
||||
double BVP;
|
||||
@@ -958,7 +946,7 @@ double TESt::CVs(double const BP)
|
||||
/// </summary>
|
||||
/// <param name="BCP">Brake cylinder pressure.</param>
|
||||
/// <returns>Opening coefficient.</returns>
|
||||
double TESt::BVs(double const BCP)
|
||||
double TESt::BVs(double const BCP) const
|
||||
{
|
||||
double VVP;
|
||||
double BVP;
|
||||
@@ -1000,11 +988,8 @@ double TESt::GetPF(double const PP, double const dt, double const Vel)
|
||||
double CVP;
|
||||
|
||||
BVP = BrakeRes->P();
|
||||
VVP = ValveRes->P();
|
||||
BCP = BrakeCyl->P();
|
||||
CVP = CntrlRes->P() - 0.0;
|
||||
|
||||
dv = 0;
|
||||
dV1 = 0;
|
||||
|
||||
// sprawdzanie stanu
|
||||
@@ -1086,7 +1071,7 @@ void TESt::Init(double const PP, double const HPP, double const LPP, double cons
|
||||
/// derived variants and currently a no-op.
|
||||
/// </summary>
|
||||
/// <param name="i_crc">Characteristic value.</param>
|
||||
void TESt::EStParams(double const i_crc) {}
|
||||
void TESt::EStParams(double const /*i_crc*/) const { /* no effect for this device type */ }
|
||||
|
||||
/// <summary>Returns the control reservoir (ZS) pressure.</summary>
|
||||
double TESt::GetCRP()
|
||||
@@ -1160,7 +1145,6 @@ double TEStEP2::GetPF(double const PP, double const dt, double const Vel)
|
||||
BCP = ImplsRes->P();
|
||||
CVP = CntrlRes->P(); // 110115 - konsultacje warszawa1
|
||||
|
||||
dv = 0;
|
||||
dV1 = 0;
|
||||
|
||||
// odluzniacz
|
||||
@@ -1168,14 +1152,14 @@ double TEStEP2::GetPF(double const PP, double const dt, double const Vel)
|
||||
|
||||
// sprawdzanie stanu
|
||||
if ((BrakeStatus & b_hld) == b_hld && BCP > 0.25)
|
||||
{
|
||||
if (VVP + 0.003 + BCP / BVM < CVP - 0.12)
|
||||
BrakeStatus |= b_on; // hamowanie stopniowe;
|
||||
else if (VVP - 0.003 + BCP / BVM > CVP - 0.12)
|
||||
BrakeStatus &= ~(b_on | b_hld); // luzowanie;
|
||||
else if (VVP + BCP / BVM > CVP - 0.12)
|
||||
BrakeStatus &= ~b_on; // zatrzymanie napelaniania;
|
||||
else
|
||||
;
|
||||
}
|
||||
else if (VVP + 0.10 < CVP - 0.12 && BCP < 0.25) // poczatek hamowania
|
||||
{
|
||||
// if ((BrakeStatus & 1) == 0)
|
||||
@@ -1343,9 +1327,9 @@ void TEStEP1::SetEPS(double const nEPS)
|
||||
double TESt3::GetPF(double const PP, double const dt, double const Vel)
|
||||
{
|
||||
double BVP{BrakeRes->P()};
|
||||
double VVP{ValveRes->P()};
|
||||
double VVP;
|
||||
double BCP{BrakeCyl->P()};
|
||||
double CVP{CntrlRes->P() - 0.0};
|
||||
double CVP;
|
||||
|
||||
double dv{0.0};
|
||||
double dV1{0.0};
|
||||
@@ -1420,11 +1404,8 @@ double TESt4R::GetPF(double const PP, double const dt, double const Vel)
|
||||
double CVP;
|
||||
|
||||
BVP = BrakeRes->P();
|
||||
VVP = ValveRes->P();
|
||||
BCP = ImplsRes->P();
|
||||
CVP = CntrlRes->P();
|
||||
|
||||
dv = 0;
|
||||
dV1 = 0;
|
||||
|
||||
// sprawdzanie stanu
|
||||
@@ -1543,11 +1524,9 @@ double TESt3AL2::GetPF(double const PP, double const dt, double const Vel)
|
||||
double CVP;
|
||||
|
||||
BVP = BrakeRes->P();
|
||||
VVP = ValveRes->P();
|
||||
BCP = ImplsRes->P();
|
||||
CVP = CntrlRes->P() - 0.0;
|
||||
|
||||
dv = 0;
|
||||
dV1 = 0;
|
||||
|
||||
// sprawdzanie stanu
|
||||
@@ -1715,8 +1694,7 @@ double TLSt::GetPF(double const PP, double const dt, double const Vel)
|
||||
SoundFlag |= sf_CylU;
|
||||
}
|
||||
// equivalent of checkreleaser() in the base class?
|
||||
bool is_releasing = BrakeStatus & b_rls || UniversalFlag & TUniversalBrake::ub_Release;
|
||||
if (is_releasing)
|
||||
if (bool is_releasing = BrakeStatus & b_rls || UniversalFlag & TUniversalBrake::ub_Release; is_releasing)
|
||||
{
|
||||
if (CVP < 0.0)
|
||||
{
|
||||
@@ -1934,14 +1912,14 @@ double TEStED::GetPF(double const PP, double const dt, double const Vel)
|
||||
else if (VVP + (BCP - 0.1) / BVM < CVP - 0.05 && BCP > 0.25) // zatrzymanie luzowania
|
||||
BrakeStatus |= b_hld;
|
||||
|
||||
if (VVP + 0.10 < CVP && BCP < 0.25) // poczatek hamowania
|
||||
if (!Przys_blok)
|
||||
{
|
||||
ValveRes->CreatePress(0.75 * VVP);
|
||||
SoundFlag |= sf_Acc;
|
||||
ValveRes->Act();
|
||||
Przys_blok = true;
|
||||
}
|
||||
// poczatek hamowania
|
||||
if (VVP + 0.10 < CVP && BCP < 0.25 && !Przys_blok)
|
||||
{
|
||||
ValveRes->CreatePress(0.75 * VVP);
|
||||
SoundFlag |= sf_Acc;
|
||||
ValveRes->Act();
|
||||
Przys_blok = true;
|
||||
}
|
||||
|
||||
if (BCP > 0.5)
|
||||
Zamykajacy = true;
|
||||
@@ -2069,7 +2047,6 @@ double TEStED::GetPF(double const PP, double const dt, double const Vel)
|
||||
void TEStED::Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF)
|
||||
{
|
||||
TLSt::Init(PP, HPP, LPP, BP, BDF);
|
||||
int i;
|
||||
|
||||
ValveRes->CreatePress(PP);
|
||||
BrakeCyl->CreatePress(BP);
|
||||
@@ -2104,7 +2081,7 @@ void TEStED::Init(double const PP, double const HPP, double const LPP, double co
|
||||
Nozzles[6] = 0.9;
|
||||
|
||||
{
|
||||
for (i = 0; i < 11; ++i)
|
||||
for (int i = 0; i < 11; ++i)
|
||||
{
|
||||
Nozzles[i] = Nozzles[i] * Nozzles[i] * 3.14159 / 4000;
|
||||
}
|
||||
@@ -2165,14 +2142,14 @@ void TCV1::CheckState(double const BCP, double &dV1)
|
||||
|
||||
// sprawdzanie stanu
|
||||
if ((BrakeStatus & b_hld) == b_hld)
|
||||
{
|
||||
if (VVP + 0.003 + BCP / BVM < CVP)
|
||||
BrakeStatus |= b_on; // hamowanie stopniowe;
|
||||
else if (VVP - 0.003 + BCP * 1.0 / BVM > CVP)
|
||||
BrakeStatus &= ~(b_on | b_hld); // luzowanie;
|
||||
else if (VVP + BCP * 1.0 / BVM > CVP)
|
||||
BrakeStatus &= ~b_on; // zatrzymanie napelaniania;
|
||||
else
|
||||
;
|
||||
}
|
||||
else if (VVP + 0.10 < CVP && BCP < 0.1) // poczatek hamowania
|
||||
{
|
||||
BrakeStatus |= b_on | b_hld;
|
||||
@@ -2188,7 +2165,7 @@ void TCV1::CheckState(double const BCP, double &dV1)
|
||||
/// </summary>
|
||||
/// <param name="BP">Cylinder pressure.</param>
|
||||
/// <returns>Opening coefficient.</returns>
|
||||
double TCV1::CVs(double const BP)
|
||||
double TCV1::CVs(double const BP) const
|
||||
{
|
||||
// przeplyw ZS <-> PG
|
||||
if (BP > 0.05)
|
||||
@@ -2204,7 +2181,7 @@ double TCV1::CVs(double const BP)
|
||||
/// </summary>
|
||||
/// <param name="BCP">Cylinder pressure.</param>
|
||||
/// <returns>Opening coefficient.</returns>
|
||||
double TCV1::BVs(double const BCP)
|
||||
double TCV1::BVs(double const BCP) const
|
||||
{
|
||||
double VVP;
|
||||
double BVP;
|
||||
@@ -2243,11 +2220,9 @@ double TCV1::GetPF(double const PP, double const dt, double const Vel)
|
||||
double CVP;
|
||||
|
||||
BVP = BrakeRes->P();
|
||||
VVP = std::min(ValveRes->P(), BVP + 0.05);
|
||||
BCP = BrakeCyl->P();
|
||||
CVP = CntrlRes->P();
|
||||
|
||||
dv = 0;
|
||||
dV1 = 0;
|
||||
|
||||
// sprawdzanie stanu
|
||||
@@ -2402,11 +2377,9 @@ double TCV1L_TR::GetPF(double const PP, double const dt, double const Vel)
|
||||
double CVP;
|
||||
|
||||
BVP = BrakeRes->P();
|
||||
VVP = std::min(ValveRes->P(), BVP + 0.05);
|
||||
BCP = ImplsRes->P();
|
||||
CVP = CntrlRes->P();
|
||||
|
||||
dv = 0;
|
||||
dV1 = 0;
|
||||
|
||||
// sprawdzanie stanu
|
||||
@@ -2488,10 +2461,12 @@ void TKE::CheckReleaser(double const dt)
|
||||
|
||||
// odluzniacz
|
||||
if (true == ((BrakeStatus & b_rls) == b_rls))
|
||||
{
|
||||
if (CVP - VVP < 0)
|
||||
BrakeStatus &= ~b_rls;
|
||||
else
|
||||
CntrlRes->Flow(+PF(CVP, 0, 0.1) * dt);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -2502,13 +2477,11 @@ void TKE::CheckReleaser(double const dt)
|
||||
/// </summary>
|
||||
/// <param name="BCP">Cylinder (or impulse-chamber) pressure.</param>
|
||||
/// <param name="dV1">In/out brake-pipe flow correction (unused here).</param>
|
||||
void TKE::CheckState(double const BCP, double &dV1)
|
||||
void TKE::CheckState(double const BCP, double & /*dV1*/)
|
||||
{
|
||||
double VVP;
|
||||
double BVP;
|
||||
double CVP;
|
||||
|
||||
BVP = BrakeRes->P();
|
||||
VVP = ValveRes->P();
|
||||
CVP = CntrlRes->P();
|
||||
|
||||
@@ -2578,13 +2551,11 @@ void TKE::CheckState(double const BCP, double &dV1)
|
||||
/// </summary>
|
||||
/// <param name="BP">Cylinder (or impulse) pressure.</param>
|
||||
/// <returns>Opening coefficient.</returns>
|
||||
double TKE::CVs(double const BP)
|
||||
double TKE::CVs(double const BP) const
|
||||
{
|
||||
double VVP;
|
||||
double BVP;
|
||||
double CVP;
|
||||
|
||||
BVP = BrakeRes->P();
|
||||
CVP = CntrlRes->P();
|
||||
VVP = ValveRes->P();
|
||||
|
||||
@@ -2604,7 +2575,7 @@ double TKE::CVs(double const BP)
|
||||
/// </summary>
|
||||
/// <param name="BCP">Impulse-chamber pressure.</param>
|
||||
/// <returns>Opening coefficient.</returns>
|
||||
double TKE::BVs(double const BCP)
|
||||
double TKE::BVs(double const /*BCP*/) const
|
||||
{
|
||||
double VVP;
|
||||
double BVP;
|
||||
@@ -2651,7 +2622,6 @@ double TKE::GetPF(double const PP, double const dt, double const Vel)
|
||||
IMP = ImplsRes->P();
|
||||
CVP = CntrlRes->P();
|
||||
|
||||
dv = 0;
|
||||
dV1 = 0;
|
||||
|
||||
// sprawdzanie stanu
|
||||
@@ -2694,7 +2664,8 @@ double TKE::GetPF(double const PP, double const dt, double const Vel)
|
||||
ImplsRes->Flow(-dv);
|
||||
|
||||
// rapid
|
||||
if (!(typeid(*FM) == typeid(TDisk1) || typeid(*FM) == typeid(TDisk2))) // jesli zeliwo to schodz
|
||||
auto const &frictionmaterial{*FM};
|
||||
if (auto const &frictionmaterialtype{typeid(frictionmaterial)}; !(frictionmaterialtype == typeid(TDisk1) || frictionmaterialtype == typeid(TDisk2))) // jesli zeliwo to schodz
|
||||
RapidStatus = (BrakeDelayFlag & bdelay_R) == bdelay_R && (RV < 0 || (Vel > RV && RapidStatus) || Vel > RV + 20);
|
||||
else // jesli tarczowki, to zostan
|
||||
RapidStatus = (BrakeDelayFlag & bdelay_R) == bdelay_R;
|
||||
@@ -2872,7 +2843,7 @@ void TDriverHandle::Init(double Press)
|
||||
|
||||
/// <summary>Default reductor adjustment — no-op.</summary>
|
||||
/// <param name="nAdj">Pressure correction.</param>
|
||||
void TDriverHandle::SetReductor(double nAdj) {}
|
||||
void TDriverHandle::SetReductor(double nAdj) { /* no effect for this device type */ }
|
||||
|
||||
/// <summary>Default cab-gauge pressure — 0.</summary>
|
||||
double TDriverHandle::GetCP()
|
||||
@@ -2969,9 +2940,8 @@ double TFV4a::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
if (lround(i_bcp) == -1)
|
||||
{
|
||||
CP = CP + 5 * std::min(std::abs(LimPP - CP), 0.2) * PR(CP, LimPP) * dt / 2;
|
||||
if (CP < RP + 0.03)
|
||||
if (TP < 5)
|
||||
TP = TP + dt;
|
||||
if (CP < RP + 0.03 && TP < 5)
|
||||
TP = TP + dt;
|
||||
// if(cp+0.03<5.4)then
|
||||
if (RP + 0.03 < 5.4 || CP + 0.03 < 5.4) // fala
|
||||
dpMainValve = PF(std::min(HP, 17.1), PP, ActFlowSpeed / LBDelay) * dt;
|
||||
@@ -3037,11 +3007,10 @@ double TFV4aM::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
int const LBDelay{100};
|
||||
double const xpM{0.3}; // mnoznik membrany komory pod
|
||||
|
||||
ep = PP / 2.0 * 1.5 + ep / 2.0 * 0.5; // SPKS!!
|
||||
|
||||
for (int idx = 0; idx < 5; ++idx)
|
||||
for (auto &soundvalue : Sounds)
|
||||
{
|
||||
Sounds[idx] = 0;
|
||||
soundvalue = 0;
|
||||
}
|
||||
|
||||
// na wszelki wypadek, zeby nie wyszlo poza zakres
|
||||
@@ -3134,13 +3103,9 @@ double TFV4aM::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
}
|
||||
}
|
||||
|
||||
if (EQ(i_bcp, 0))
|
||||
if (EQ(i_bcp, 0) && TP > 2)
|
||||
{
|
||||
|
||||
if (TP > 2)
|
||||
{
|
||||
dpMainValve *= 1.5;
|
||||
}
|
||||
dpMainValve *= 1.5;
|
||||
}
|
||||
|
||||
ep = dpPipe;
|
||||
@@ -3239,16 +3204,16 @@ double TFV4aM::GetRP()
|
||||
/// </summary>
|
||||
/// <param name="pos">Continuous handle position.</param>
|
||||
/// <returns>Interpolated target pressure [bar].</returns>
|
||||
double TFV4aM::LPP_RP(double pos) // cisnienie z zaokraglonej pozycji;
|
||||
double TFV4aM::LPP_RP(double pos) const // cisnienie z zaokraglonej pozycji;
|
||||
{
|
||||
int const i_pos = 2 + std::floor(pos); // zaokraglone w dol
|
||||
auto const i_pos = static_cast<int>(2 + std::floor(pos)); // zaokraglone w dol
|
||||
|
||||
return BPT[i_pos][1] + (BPT[i_pos + 1][1] - BPT[i_pos][1]) * (pos + 2 - i_pos); // interpolacja liniowa
|
||||
}
|
||||
/// <summary>Returns true if pos is within ±0.5 of i_pos (detent test).</summary>
|
||||
/// <param name="pos">Continuous handle position.</param>
|
||||
/// <param name="i_pos">Detent centre.</param>
|
||||
bool TFV4aM::EQ(double pos, double i_pos)
|
||||
bool TFV4aM::EQ(double pos, double i_pos) const
|
||||
{
|
||||
return pos <= i_pos + 0.5 && pos > i_pos - 0.5;
|
||||
}
|
||||
@@ -3279,12 +3244,11 @@ double TMHZ_EN57::GetPF(double i_bcp, double PP, double HP, double dt, double ep
|
||||
double DP;
|
||||
double pom;
|
||||
|
||||
for (int idx = 0; idx < 5; ++idx)
|
||||
for (auto &soundvalue : Sounds)
|
||||
{
|
||||
Sounds[idx] = 0;
|
||||
soundvalue = 0;
|
||||
}
|
||||
|
||||
DP = 0;
|
||||
|
||||
i_bcp = std::clamp(i_bcp, -0.999, 9.999); // na wszelki wypadek, zeby nie wyszlo poza zakres
|
||||
|
||||
@@ -3425,7 +3389,7 @@ double TMHZ_EN57::GetEP(double pos)
|
||||
/// </summary>
|
||||
/// <param name="pos">Continuous handle position.</param>
|
||||
/// <returns>Target brake-pipe pressure [bar].</returns>
|
||||
double TMHZ_EN57::LPP_RP(double pos) // cisnienie z zaokraglonej pozycji;
|
||||
double TMHZ_EN57::LPP_RP(double pos) const // cisnienie z zaokraglonej pozycji;
|
||||
{
|
||||
if (pos > 8.5)
|
||||
return 5.0 - 0.15 * pos - 0.35;
|
||||
@@ -3456,7 +3420,7 @@ void TMHZ_EN57::SetParams(bool AO, bool MO, double OverP, double, double OMP, do
|
||||
}
|
||||
|
||||
/// <summary>Returns true if pos is within ±0.5 of i_pos (detent test).</summary>
|
||||
bool TMHZ_EN57::EQ(double pos, double i_pos)
|
||||
bool TMHZ_EN57::EQ(double pos, double i_pos) const
|
||||
{
|
||||
return pos <= i_pos + 0.5 && pos > i_pos - 0.5;
|
||||
}
|
||||
@@ -3484,14 +3448,12 @@ double TMHZ_K5P::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
double dpMainValve;
|
||||
double ActFlowSpeed;
|
||||
double DP;
|
||||
double pom;
|
||||
|
||||
for (int idx = 0; idx < 5; ++idx)
|
||||
for (auto &soundvalue : Sounds)
|
||||
{
|
||||
Sounds[idx] = 0;
|
||||
soundvalue = 0;
|
||||
}
|
||||
|
||||
DP = 0;
|
||||
|
||||
i_bcp = std::clamp(i_bcp, -0.999, 2.999); // na wszelki wypadek, zeby nie wyszlo poza zakres
|
||||
|
||||
@@ -3512,7 +3474,6 @@ double TMHZ_K5P::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
LimCP = 3.4;
|
||||
else // luzowanie
|
||||
LimCP = 5.0;
|
||||
pom = CP;
|
||||
LimCP = std::min(LimCP, HP); // pozycja + czasowy lub zasilanie
|
||||
ActFlowSpeed = 4;
|
||||
|
||||
@@ -3636,7 +3597,7 @@ void TMHZ_K5P::SetParams(bool AO, bool MO, double OverP, double FSF, double OMP,
|
||||
}
|
||||
|
||||
/// <summary>Returns true if pos is within ±0.5 of i_pos (detent test).</summary>
|
||||
bool TMHZ_K5P::EQ(double pos, double i_pos)
|
||||
bool TMHZ_K5P::EQ(double pos, double i_pos) const
|
||||
{
|
||||
return pos <= i_pos + 0.5 && pos > i_pos - 0.5;
|
||||
}
|
||||
@@ -3663,14 +3624,12 @@ double TMHZ_6P::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
double dpMainValve;
|
||||
double ActFlowSpeed;
|
||||
double DP;
|
||||
double pom;
|
||||
|
||||
for (int idx = 0; idx < 5; ++idx)
|
||||
for (auto &soundvalue : Sounds)
|
||||
{
|
||||
Sounds[idx] = 0;
|
||||
soundvalue = 0;
|
||||
}
|
||||
|
||||
DP = 0;
|
||||
|
||||
i_bcp = std::clamp(i_bcp, -0.999, 3.999); // na wszelki wypadek, zeby nie wyszlo poza zakres
|
||||
|
||||
@@ -3691,7 +3650,6 @@ double TMHZ_6P::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
LimCP = 3.4;
|
||||
else // luzowanie
|
||||
LimCP = 5.0;
|
||||
pom = CP;
|
||||
LimCP = std::min(LimCP, HP); // pozycja + czasowy lub zasilanie
|
||||
ActFlowSpeed = 4;
|
||||
|
||||
@@ -3815,7 +3773,7 @@ void TMHZ_6P::SetParams(bool AO, bool MO, double OverP, double FSF, double OMP,
|
||||
}
|
||||
|
||||
/// <summary>Returns true if pos is within ±0.5 of i_pos (detent test).</summary>
|
||||
bool TMHZ_6P::EQ(double pos, double i_pos)
|
||||
bool TMHZ_6P::EQ(double pos, double i_pos) const
|
||||
{
|
||||
return pos <= i_pos + 0.5 && pos > i_pos - 0.5;
|
||||
}
|
||||
@@ -3844,7 +3802,7 @@ double TM394::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
double ActFlowSpeed;
|
||||
int BCP;
|
||||
|
||||
BCP = lround(i_bcp);
|
||||
BCP = static_cast<int>(lround(i_bcp));
|
||||
if (BCP < -1)
|
||||
BCP = 1;
|
||||
|
||||
@@ -3855,6 +3813,7 @@ double TM394::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
if (BCP == 0)
|
||||
LimPP = LimPP + RedAdj;
|
||||
if (BCP != 2)
|
||||
{
|
||||
if (CP < LimPP)
|
||||
CP = CP + 4 * std::min(abs(LimPP - CP), 0.05) * PR(CP, LimPP) * dt; // zbiornik sterujacy
|
||||
// cp:=cp+6*(2+int(bcp<0))*std::min(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt //zbiornik
|
||||
@@ -3863,6 +3822,7 @@ double TM394::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
CP = CP - 0.2 * dt / 100;
|
||||
else
|
||||
CP = CP + 4 * (1 + int(BCP != 3) + int(BCP > 4)) * std::min(abs(LimPP - CP), 0.05) * PR(CP, LimPP) * dt; // zbiornik sterujacy
|
||||
}
|
||||
|
||||
LimPP = CP;
|
||||
dpPipe = std::min(HP, LimPP);
|
||||
@@ -3937,7 +3897,7 @@ double TH14K1::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
//{ (10, 0), (4, 1), (0, 1), (4, 0), (4, -1), (15, -1) };
|
||||
double const NomPress = 5.0;
|
||||
|
||||
int BCP = std::lround(i_bcp);
|
||||
auto BCP = static_cast<int>(std::lround(i_bcp));
|
||||
if (i_bcp < -1)
|
||||
{
|
||||
BCP = 1;
|
||||
@@ -4034,7 +3994,7 @@ double TSt113::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
|
||||
CP = PP;
|
||||
|
||||
BCP = lround(i_bcp);
|
||||
BCP = static_cast<int>(lround(i_bcp));
|
||||
|
||||
EPS = BEP_K[BCP + 1];
|
||||
|
||||
|
||||
@@ -272,10 +272,11 @@ class TReservoir
|
||||
|
||||
/// <summary>Default constructor — creates a 1 L reservoir at zero pressure.</summary>
|
||||
TReservoir() = default;
|
||||
virtual ~TReservoir() = default;
|
||||
};
|
||||
|
||||
/// <summary>Pointer typedef for a reservoir instance.</summary>
|
||||
typedef TReservoir *PReservoir;
|
||||
using PReservoir = TReservoir *;
|
||||
|
||||
/// <summary>
|
||||
/// Brake cylinder reservoir — overrides pressure functions to model the
|
||||
@@ -290,15 +291,15 @@ class TBrakeCyl : public TReservoir
|
||||
/// Returns absolute pressure inside the brake cylinder (P() * 0.1).
|
||||
/// </summary>
|
||||
/// <returns>Absolute cylinder pressure.</returns>
|
||||
virtual double pa() /*override*/;
|
||||
double pa() override;
|
||||
/// <summary>
|
||||
/// Returns gauge pressure inside the brake cylinder, modelling the
|
||||
/// piston-stroke pressure curve (dead volume, linear stroke, fully extended).
|
||||
/// </summary>
|
||||
/// <returns>Cylinder pressure in bar.</returns>
|
||||
virtual double P() /*override*/;
|
||||
double P() override;
|
||||
/// <summary>Default constructor.</summary>
|
||||
TBrakeCyl() : TReservoir() {};
|
||||
using TReservoir::TReservoir;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -399,7 +400,7 @@ class TBrake
|
||||
/// Returns the piston force produced by the brake cylinder pressure.
|
||||
/// </summary>
|
||||
/// <returns>Force in arbitrary engine units (BCA * 100 * P).</returns>
|
||||
double GetBCF(); // sila tlokowa z tloka
|
||||
double GetBCF() const; // sila tlokowa z tloka
|
||||
/// <summary>
|
||||
/// Computes the airflow drawn from the high-pressure (8 bar / main) line for one step.
|
||||
/// </summary>
|
||||
@@ -408,16 +409,16 @@ class TBrake
|
||||
/// <returns>Net flow from the high-pressure line.</returns>
|
||||
virtual double GetHPFlow(double const HP, double const dt); // przeplyw - 8 bar
|
||||
/// <summary>Returns brake cylinder gauge pressure [bar].</summary>
|
||||
double GetBCP(); // cisnienie cylindrow hamulcowych
|
||||
double GetBCP() const; // cisnienie cylindrow hamulcowych
|
||||
/// <summary>
|
||||
/// Returns brake cylinder pressure originating only from the pneumatic
|
||||
/// (main) brake — used to drive the ED (electrodynamic) brake e.g. in EP09.
|
||||
/// </summary>
|
||||
virtual double GetEDBCP(); // cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED w EP09
|
||||
/// <summary>Returns auxiliary reservoir (ZP) pressure [bar].</summary>
|
||||
double GetBRP(); // cisnienie zbiornika pomocniczego
|
||||
double GetBRP() const; // cisnienie zbiornika pomocniczego
|
||||
/// <summary>Returns valve pre-chamber pressure [bar].</summary>
|
||||
double GetVRP(); // cisnienie komory wstepnej rozdzielacza
|
||||
double GetVRP() const; // cisnienie komory wstepnej rozdzielacza
|
||||
/// <summary>Returns control reservoir (ZS) pressure [bar]; defaults to the auxiliary reservoir for valves without a dedicated ZS.</summary>
|
||||
virtual double GetCRP(); // cisnienie zbiornika sterujacego
|
||||
/// <summary>
|
||||
@@ -441,7 +442,7 @@ class TBrake
|
||||
virtual void SetEPS(double const nEPS); // hamulec EP
|
||||
/// <summary>Sets the rapid step ratio. Default no-op; overridden where supported.</summary>
|
||||
/// <param name="RMR">Rapid ratio.</param>
|
||||
virtual void SetRM(double const RMR) {}; // ustalenie przelozenia rapida
|
||||
virtual void SetRM(double const RMR) { /* no effect for this device type */ } // ustalenie przelozenia rapida
|
||||
/// <summary>Sets the velocity threshold for the rapid step.</summary>
|
||||
/// <param name="RVR">Velocity threshold (same unit as Vel passed to GetPF).</param>
|
||||
virtual void SetRV(double const RVR)
|
||||
@@ -455,20 +456,20 @@ class TBrake
|
||||
/// <param name="TM">Tare (empty) mass.</param>
|
||||
/// <param name="LM">Loaded mass.</param>
|
||||
/// <param name="TBP">Brake cylinder pressure for the tare mass.</param>
|
||||
virtual void SetLP(double const TM, double const LM, double const TBP) {}; // parametry przystawki wazacej
|
||||
virtual void SetLP(double const TM, double const LM, double const TBP) { /* no effect for this device type */ } // parametry przystawki wazacej
|
||||
/// <summary>Sets the auxiliary (local) brake target pressure.</summary>
|
||||
/// <param name="P">Local brake pressure [bar].</param>
|
||||
virtual void SetLBP(double const P) {}; // cisnienie z hamulca pomocniczego
|
||||
virtual void SetLBP(double const P) { /* no effect for this device type */ } // cisnienie z hamulca pomocniczego
|
||||
/// <summary>Updates the load-weighing pressure coefficient based on current vehicle mass.</summary>
|
||||
/// <param name="mass">Current vehicle mass.</param>
|
||||
virtual void PLC(double const mass) {}; // wspolczynnik cisnienia przystawki wazacej
|
||||
virtual void PLC(double const mass) { /* no effect for this device type */ } // wspolczynnik cisnienia przystawki wazacej
|
||||
/// <summary>
|
||||
/// Engages the anti-slip brake function (set hold and/or release flags).
|
||||
/// </summary>
|
||||
/// <param name="state">Two-bit value: bit1 = hold (b_asb), bit0 = release (b_asb_unbrake).</param>
|
||||
void ASB(int state); // hamulec przeciwposlizgowy
|
||||
/// <summary>Returns the raw BrakeStatus flags (for sound/visual cues).</summary>
|
||||
int GetStatus(); // flaga statusu, moze sie przydac do odglosow
|
||||
int GetStatus() const; // flaga statusu, moze sie przydac do odglosow
|
||||
/// <summary>Sets the anti-slip target pressure.</summary>
|
||||
/// <param name="Press">Pressure [bar].</param>
|
||||
void SetASBP(double const Press); // ustalenie cisnienia pp
|
||||
@@ -497,13 +498,14 @@ class TBrake
|
||||
/// brake when ED braking is sufficient. Default no-op; overridden where supported.
|
||||
/// </summary>
|
||||
/// <param name="EDstate">ED brake intensity (0..1).</param>
|
||||
virtual void SetED(double const EDstate) {}; // stan hamulca ED do luzowania
|
||||
virtual void SetED(double const EDstate) { /* no effect for this device type */ } // stan hamulca ED do luzowania
|
||||
/// <summary>Sets the universal-button flags (see TUniversalBrake).</summary>
|
||||
/// <param name="flag">Combined ub_* flags.</param>
|
||||
virtual void SetUniversalFlag(int flag)
|
||||
{
|
||||
UniversalFlag = flag;
|
||||
} // przycisk uniwersalny
|
||||
virtual ~TBrake() = default;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -537,26 +539,26 @@ class TWest : public TBrake
|
||||
/// <param name="LPP">Low pressure.</param>
|
||||
/// <param name="BP">Initial cylinder pressure.</param>
|
||||
/// <param name="BDF">Initial brake delay flag.</param>
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) override;
|
||||
/// <summary>Sets the auxiliary brake target pressure and engages the DCV when above cylinder.</summary>
|
||||
/// <param name="P">Pressure [bar].</param>
|
||||
void SetLBP(double const P); // cisnienie z hamulca pomocniczego
|
||||
void SetLBP(double const P) override; // cisnienie z hamulca pomocniczego
|
||||
/// <summary>One-step distributor advance (Westinghouse logic).</summary>
|
||||
/// <returns>Net flow exchanged with the brake pipe.</returns>
|
||||
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
double GetPF(double const PP, double const dt, double const Vel) override; // przeplyw miedzy komora wstepna i PG
|
||||
/// <summary>Returns the high-pressure flow drawn during the last GetPF step.</summary>
|
||||
double GetHPFlow(double const HP, double const dt) /*override*/;
|
||||
double GetHPFlow(double const HP, double const dt) override;
|
||||
/// <summary>Recomputes the load-weighing pressure coefficient for the current mass.</summary>
|
||||
/// <param name="mass">Vehicle mass.</param>
|
||||
void PLC(double const mass); // wspolczynnik cisnienia przystawki wazacej
|
||||
void PLC(double const mass) override; // wspolczynnik cisnienia przystawki wazacej
|
||||
/// <summary>Sets the EP brake state and toggles the DCV / latches LBP from cylinder pressure on release.</summary>
|
||||
/// <param name="nEPS">New EP intensity.</param>
|
||||
void SetEPS(double const nEPS) /*override*/; // stan hamulca EP
|
||||
void SetEPS(double const nEPS) override; // stan hamulca EP
|
||||
/// <summary>Stores the load-weighing parameters (TareM, LoadM, TareBP).</summary>
|
||||
void SetLP(double const TM, double const LM, double const TBP); // parametry przystawki wazacej
|
||||
void SetLP(double const TM, double const LM, double const TBP) override; // parametry przystawki wazacej
|
||||
|
||||
/// <summary>Constructs the distributor by forwarding all parameters to TBrake.</summary>
|
||||
inline TWest(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) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa) {}
|
||||
using TBrake::TBrake;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -567,7 +569,6 @@ class TWest : public TBrake
|
||||
class TESt : public TBrake
|
||||
{
|
||||
|
||||
private:
|
||||
protected:
|
||||
/// <summary>Control reservoir (ZS) — long-term reference pressure.</summary>
|
||||
std::shared_ptr<TReservoir> CntrlRes; // zbiornik sterujący
|
||||
@@ -576,15 +577,15 @@ class TESt : public TBrake
|
||||
|
||||
public:
|
||||
/// <summary>Initialises the ESt distributor; sizes the control reservoir (15 l) and computes BVM.</summary>
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) override;
|
||||
/// <summary>One-step distributor advance for the ESt baseline.</summary>
|
||||
/// <returns>Net flow exchanged with the brake pipe.</returns>
|
||||
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
double GetPF(double const PP, double const dt, double const Vel) override; // przeplyw miedzy komora wstepna i PG
|
||||
/// <summary>Sets ESt-specific characteristic parameters (placeholder; used by some variants).</summary>
|
||||
/// <param name="i_crc">Characteristic value.</param>
|
||||
void EStParams(double i_crc); // parametry charakterystyczne dla ESt
|
||||
void EStParams(double i_crc) const; // parametry charakterystyczne dla ESt
|
||||
/// <summary>Returns the control reservoir (ZS) pressure.</summary>
|
||||
double GetCRP() /*override*/;
|
||||
double GetCRP() override;
|
||||
/// <summary>
|
||||
/// Updates BrakeStatus (b_on/b_hld) according to the relations between
|
||||
/// pre-chamber, cylinder and control reservoir pressures (the main slide valve).
|
||||
@@ -602,16 +603,16 @@ class TESt : public TBrake
|
||||
/// </summary>
|
||||
/// <param name="BP">Cylinder pressure (or impulse-chamber pressure).</param>
|
||||
/// <returns>Dimensionless opening coefficient.</returns>
|
||||
double CVs(double BP); // napelniacz sterujacego
|
||||
double CVs(double BP) const; // napelniacz sterujacego
|
||||
/// <summary>
|
||||
/// Returns the effective opening factor of the auxiliary-reservoir filling
|
||||
/// slide valve (ZP <-> pre-chamber path).
|
||||
/// </summary>
|
||||
/// <param name="BCP">Brake cylinder pressure.</param>
|
||||
/// <returns>Dimensionless opening coefficient.</returns>
|
||||
double BVs(double BCP); // napelniacz pomocniczego
|
||||
double BVs(double BCP) const; // napelniacz pomocniczego
|
||||
/// <summary>Vents the valve, brake and control reservoirs to zero.</summary>
|
||||
void ForceEmptiness() /*override*/; // wymuszenie bycia pustym
|
||||
void ForceEmptiness() override; // wymuszenie bycia pustym
|
||||
|
||||
/// <summary>Constructs the ESt distributor and creates the control reservoir.</summary>
|
||||
inline TESt(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) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
|
||||
@@ -627,16 +628,15 @@ class TESt : public TBrake
|
||||
class TESt3 : public TESt
|
||||
{
|
||||
|
||||
private:
|
||||
// double CylFlowSpeed[2][2]; //zmienna nie uzywana
|
||||
|
||||
public:
|
||||
/// <summary>One-step distributor advance for ESt3 (G/P-dependent fill/release curves).</summary>
|
||||
/// <returns>Net flow exchanged with the brake pipe.</returns>
|
||||
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
double GetPF(double const PP, double const dt, double const Vel) override; // przeplyw miedzy komora wstepna i PG
|
||||
|
||||
/// <summary>Constructs the ESt3 distributor.</summary>
|
||||
inline TESt3(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) : TESt(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa) {}
|
||||
using TESt::TESt;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -660,13 +660,13 @@ class TESt3AL2 : public TESt3
|
||||
|
||||
public:
|
||||
/// <summary>Initialises the impulse chamber on top of the ESt initialisation.</summary>
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) override;
|
||||
/// <summary>One-step distributor advance for ESt3/AL2 with load-weighing relay.</summary>
|
||||
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
double GetPF(double const PP, double const dt, double const Vel) override; // przeplyw miedzy komora wstepna i PG
|
||||
/// <summary>Recomputes LoadC for the current vehicle mass.</summary>
|
||||
void PLC(double const mass); // wspolczynnik cisnienia przystawki wazacej
|
||||
void PLC(double const mass) override; // wspolczynnik cisnienia przystawki wazacej
|
||||
/// <summary>Stores the load-weighing parameters.</summary>
|
||||
void SetLP(double const TM, double const LM, double const TBP); // parametry przystawki wazacej
|
||||
void SetLP(double const TM, double const LM, double const TBP) override; // parametry przystawki wazacej
|
||||
|
||||
/// <summary>Constructs the distributor and creates the impulse chamber.</summary>
|
||||
inline TESt3AL2(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) : TESt3(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
|
||||
@@ -695,9 +695,9 @@ class TESt4R : public TESt
|
||||
|
||||
public:
|
||||
/// <summary>Initialises the ESt4R; sizes the impulse chamber and selects the R delay.</summary>
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) override;
|
||||
/// <summary>One-step distributor advance for ESt4R (rapid step active above velocity threshold).</summary>
|
||||
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
double GetPF(double const PP, double const dt, double const Vel) override; // przeplyw miedzy komora wstepna i PG
|
||||
|
||||
/// <summary>Constructs the distributor and creates the impulse chamber.</summary>
|
||||
inline TESt4R(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) : TESt(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
|
||||
@@ -713,7 +713,6 @@ class TESt4R : public TESt
|
||||
class TLSt : public TESt4R
|
||||
{
|
||||
|
||||
private:
|
||||
// double CylFlowSpeed[2][2]; // zmienna nie używana
|
||||
|
||||
protected:
|
||||
@@ -726,24 +725,24 @@ class TLSt : public TESt4R
|
||||
|
||||
public:
|
||||
/// <summary>Initialises the LSt; resizes the valve and impulse reservoirs and presets pressures.</summary>
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) override;
|
||||
/// <summary>Sets the auxiliary brake target pressure for the DCV.</summary>
|
||||
void SetLBP(double const P); // cisnienie z hamulca pomocniczego
|
||||
void SetLBP(double const P) override; // cisnienie z hamulca pomocniczego
|
||||
/// <summary>Sets the rapid step ratio (RM = 1 - RMR).</summary>
|
||||
/// <param name="RMR">Reduction ratio (0 disables rapid, > 0 enables).</param>
|
||||
void SetRM(double const RMR); // ustalenie przelozenia rapida
|
||||
void SetRM(double const RMR) override; // ustalenie przelozenia rapida
|
||||
/// <summary>One-step distributor advance for LSt (DCV + rapid + ED release).</summary>
|
||||
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
double GetPF(double const PP, double const dt, double const Vel) override; // przeplyw miedzy komora wstepna i PG
|
||||
/// <summary>Computes the high-pressure inflow (replenishes the auxiliary reservoir from the main line).</summary>
|
||||
double GetHPFlow(double const HP, double const dt) /*override*/; // przeplyw - 8 bar
|
||||
double GetHPFlow(double const HP, double const dt) override; // przeplyw - 8 bar
|
||||
/// <summary>Returns the brake-cylinder reference pressure used by the ED brake controller (CVP-BCP * BVM).</summary>
|
||||
virtual double GetEDBCP(); // cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED w EP09
|
||||
double GetEDBCP() override; // cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED w EP09
|
||||
/// <summary>Sets the ED brake state used to relax the pneumatic brake.</summary>
|
||||
/// <param name="EDstate">ED intensity (0..1).</param>
|
||||
virtual void SetED(double const EDstate); // stan hamulca ED do luzowania
|
||||
void SetED(double const EDstate) override; // stan hamulca ED do luzowania
|
||||
|
||||
/// <summary>Constructs the LSt distributor.</summary>
|
||||
inline TLSt(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) : TESt4R(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa) {}
|
||||
using TESt4R::TESt4R;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -774,15 +773,15 @@ class TEStED : public TLSt
|
||||
|
||||
public:
|
||||
/// <summary>Initialises the EStED — sets up Miedzypoj, ImplsRes and the nozzle characteristics.</summary>
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) override;
|
||||
/// <summary>One-step distributor advance for EStED (full EP09 logic with intermediate reservoir).</summary>
|
||||
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
double GetPF(double const PP, double const dt, double const Vel) override; // przeplyw miedzy komora wstepna i PG
|
||||
/// <summary>Returns ED-brake reference pressure (ImplsRes pressure scaled by load coefficient).</summary>
|
||||
double GetEDBCP() /*override*/; // cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED
|
||||
double GetEDBCP() override; // cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED
|
||||
/// <summary>Recomputes LoadC for the current vehicle mass.</summary>
|
||||
void PLC(double const mass); // wspolczynnik cisnienia przystawki wazacej
|
||||
void PLC(double const mass) override; // wspolczynnik cisnienia przystawki wazacej
|
||||
/// <summary>Stores the load-weighing parameters.</summary>
|
||||
void SetLP(double const TM, double const LM, double const TBP); // parametry przystawki wazacej
|
||||
void SetLP(double const TM, double const LM, double const TBP) override; // parametry przystawki wazacej
|
||||
|
||||
/// <summary>Constructs the distributor and creates the intermediate reservoir.</summary>
|
||||
inline TEStED(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)
|
||||
@@ -812,21 +811,21 @@ class TEStEP2 : public TLSt
|
||||
|
||||
public:
|
||||
/// <summary>Initialises the EP2-equipped distributor (impulse chamber, P delay).</summary>
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/; // inicjalizacja
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) override; // inicjalizacja
|
||||
/// <summary>One-step distributor advance with EP2 EP brake logic.</summary>
|
||||
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
double GetPF(double const PP, double const dt, double const Vel) override; // przeplyw miedzy komora wstepna i PG
|
||||
/// <summary>Recomputes LoadC for the current vehicle mass.</summary>
|
||||
void PLC(double const mass); // wspolczynnik cisnienia przystawki wazacej
|
||||
void PLC(double const mass) override; // wspolczynnik cisnienia przystawki wazacej
|
||||
/// <summary>Sets EP intensity; if EP is active and LBP < cylinder pressure, latches LBP from cylinder.</summary>
|
||||
void SetEPS(double const nEPS) /*override*/; // stan hamulca EP
|
||||
void SetEPS(double const nEPS) override; // stan hamulca EP
|
||||
/// <summary>Stores the load-weighing parameters.</summary>
|
||||
void SetLP(double const TM, double const LM, double const TBP); // parametry przystawki wazacej
|
||||
void SetLP(double const TM, double const LM, double const TBP) override; // parametry przystawki wazacej
|
||||
/// <summary>EP brake flow integration step. Override in EP1 for proportional control.</summary>
|
||||
/// <param name="dt">Time step [s].</param>
|
||||
void virtual EPCalc(double dt);
|
||||
|
||||
/// <summary>Constructs the EP2 distributor.</summary>
|
||||
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) {}
|
||||
using TLSt::TLSt;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -839,15 +838,13 @@ class TEStEP1 : public TEStEP2
|
||||
|
||||
public:
|
||||
/// <summary>Proportional EP flow integration step (uses fractional part of EPS as the EP target).</summary>
|
||||
void EPCalc(double dt);
|
||||
void EPCalc(double dt) override;
|
||||
/// <summary>Stores the EP intensity.</summary>
|
||||
/// <param name="nEPS">Target EP value (integer part = direction, fractional part = magnitude).</param>
|
||||
void SetEPS(double const nEPS) override; // stan hamulca EP
|
||||
|
||||
/// <summary>Constructs the EP1 distributor.</summary>
|
||||
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)
|
||||
{
|
||||
}
|
||||
using TEStEP2::TEStEP2;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -867,21 +864,21 @@ class TCV1 : public TBrake
|
||||
|
||||
public:
|
||||
/// <summary>Initialises the CV1 distributor (sizes ZS, sets pressures, computes BVM).</summary>
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) override;
|
||||
/// <summary>One-step distributor advance for the CV1 baseline.</summary>
|
||||
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
double GetPF(double const PP, double const dt, double const Vel) override; // przeplyw miedzy komora wstepna i PG
|
||||
/// <summary>Returns the control reservoir (ZS) pressure.</summary>
|
||||
double GetCRP() /*override*/;
|
||||
double GetCRP() override;
|
||||
/// <summary>Updates BrakeStatus based on pre-chamber/cylinder/control reservoir relations and the releaser.</summary>
|
||||
/// <param name="BCP">Cylinder (or impulse) pressure.</param>
|
||||
/// <param name="dV1">In/out brake pipe flow correction.</param>
|
||||
void CheckState(double const BCP, double &dV1);
|
||||
/// <summary>Returns the ZS-filling slide valve opening factor for the given cylinder pressure.</summary>
|
||||
double CVs(double const BP);
|
||||
double CVs(double const BP) const;
|
||||
/// <summary>Returns the ZP-filling slide valve opening factor for the given cylinder pressure.</summary>
|
||||
double BVs(double const BCP);
|
||||
double BVs(double const BCP) const;
|
||||
/// <summary>Vents valve, brake and control reservoirs to zero.</summary>
|
||||
void ForceEmptiness() /*override*/; // wymuszenie bycia pustym
|
||||
void ForceEmptiness() override; // wymuszenie bycia pustym
|
||||
|
||||
/// <summary>Constructs the CV1 distributor and creates the control reservoir.</summary>
|
||||
inline TCV1(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) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
|
||||
@@ -922,13 +919,13 @@ class TCV1L_TR : public TCV1
|
||||
|
||||
public:
|
||||
/// <summary>Initialises the CV1-L-TR (sizes the impulse chamber on top of CV1::Init).</summary>
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) override;
|
||||
/// <summary>One-step distributor advance for CV1-L-TR (impulse chamber + DCV).</summary>
|
||||
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
double GetPF(double const PP, double const dt, double const Vel) override; // przeplyw miedzy komora wstepna i PG
|
||||
/// <summary>Sets the auxiliary brake target pressure for the DCV.</summary>
|
||||
void SetLBP(double const P); // cisnienie z hamulca pomocniczego
|
||||
void SetLBP(double const P) override; // cisnienie z hamulca pomocniczego
|
||||
/// <summary>Computes the high-pressure (8 bar) inflow used to replenish the auxiliary reservoir.</summary>
|
||||
double GetHPFlow(double const HP, double const dt) /*override*/; // przeplyw - 8 bar
|
||||
double GetHPFlow(double const HP, double const dt) override; // przeplyw - 8 bar
|
||||
|
||||
/// <summary>Constructs the CV1-L-TR and creates the impulse chamber.</summary>
|
||||
inline TCV1L_TR(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) : TCV1(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
|
||||
@@ -971,31 +968,31 @@ class TKE : public TBrake
|
||||
|
||||
public:
|
||||
/// <summary>Initialises the KE distributor (control / impulse / auxiliary reservoirs and BVM).</summary>
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) /*override*/;
|
||||
void Init(double const PP, double const HPP, double const LPP, double const BP, int const BDF) override;
|
||||
/// <summary>Sets the rapid step ratio (RM = 1 - RMR).</summary>
|
||||
void SetRM(double const RMR); // ustalenie przelozenia rapida
|
||||
void SetRM(double const RMR) override; // ustalenie przelozenia rapida
|
||||
/// <summary>One-step distributor advance for the KE distributor.</summary>
|
||||
double GetPF(double const PP, double const dt, double const Vel) /*override*/; // przeplyw miedzy komora wstepna i PG
|
||||
double GetPF(double const PP, double const dt, double const Vel) override; // przeplyw miedzy komora wstepna i PG
|
||||
/// <summary>Computes the high-pressure (8 bar) inflow used to replenish the auxiliary reservoir.</summary>
|
||||
double GetHPFlow(double const HP, double const dt) /*override*/; // przeplyw - 8 bar
|
||||
double GetHPFlow(double const HP, double const dt) override; // przeplyw - 8 bar
|
||||
/// <summary>Returns the control reservoir (ZS) pressure.</summary>
|
||||
double GetCRP() /*override*/;
|
||||
double GetCRP() override;
|
||||
/// <summary>Updates BrakeStatus from cylinder/pre-chamber/control reservoir pressures (KE-specific thresholds).</summary>
|
||||
void CheckState(double const BCP, double &dV1);
|
||||
/// <summary>Drives the releaser logic for KE — bleeds the control reservoir while engaged.</summary>
|
||||
void CheckReleaser(double const dt); // odluzniacz
|
||||
/// <summary>ZS-filling slide valve opening factor for the given cylinder pressure.</summary>
|
||||
double CVs(double const BP); // napelniacz sterujacego
|
||||
double CVs(double const BP) const; // napelniacz sterujacego
|
||||
/// <summary>ZP-filling slide valve opening factor for the given cylinder pressure.</summary>
|
||||
double BVs(double const BCP); // napelniacz pomocniczego
|
||||
double BVs(double const BCP) const; // napelniacz pomocniczego
|
||||
/// <summary>Recomputes LoadC for the current vehicle mass.</summary>
|
||||
void PLC(double const mass); // wspolczynnik cisnienia przystawki wazacej
|
||||
void PLC(double const mass) override; // wspolczynnik cisnienia przystawki wazacej
|
||||
/// <summary>Stores the load-weighing parameters.</summary>
|
||||
void SetLP(double const TM, double const LM, double const TBP); // parametry przystawki wazacej
|
||||
void SetLP(double const TM, double const LM, double const TBP) override; // parametry przystawki wazacej
|
||||
/// <summary>Sets the auxiliary brake target pressure for the DCV.</summary>
|
||||
void SetLBP(double const P); // cisnienie z hamulca pomocniczego
|
||||
void SetLBP(double const P) override; // cisnienie z hamulca pomocniczego
|
||||
/// <summary>Vents valve, brake, control, impulse and secondary auxiliary reservoirs to zero.</summary>
|
||||
void ForceEmptiness() /*override*/; // wymuszenie bycia pustym
|
||||
void ForceEmptiness() override; // wymuszenie bycia pustym
|
||||
|
||||
/// <summary>Constructs the KE distributor and creates the control / impulse / secondary reservoirs.</summary>
|
||||
inline TKE(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) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
|
||||
@@ -1077,7 +1074,7 @@ class TDriverHandle
|
||||
/// <param name="OverP">Unbrake over-pressure [bar].</param>
|
||||
/// <param name="OMP">Overload (assimilation) max pressure [bar].</param>
|
||||
/// <param name="OPD">Overload pressure decay rate [bar/s].</param>
|
||||
virtual void SetParams(bool AO, bool MO, double, double, double OMP, double OPD) {}; // ustawianie jakichs parametrow dla zaworu
|
||||
virtual void SetParams(bool AO, bool MO, double, double, double OMP, double OPD) { /* no effect for this device type */ } // ustawianie jakichs parametrow dla zaworu
|
||||
/// <summary>Sets the manual overcharge button state.</summary>
|
||||
/// <param name="Active">True while the button is pressed.</param>
|
||||
virtual void OvrldButton(bool Active); // przycisk recznego przeladowania/asymilacji
|
||||
@@ -1089,6 +1086,7 @@ class TDriverHandle
|
||||
{
|
||||
memset(Sounds, 0, sizeof(Sounds));
|
||||
}
|
||||
virtual ~TDriverHandle() = default;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -1107,12 +1105,12 @@ class TFV4a : public TDriverHandle
|
||||
|
||||
public:
|
||||
/// <summary>Computes brake pipe flow for the FV4a handle (uses BPT[] table).</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Initialises CP and RP to the supplied pressure.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
|
||||
/// <summary>Default constructor.</summary>
|
||||
inline TFV4a() : TDriverHandle() {}
|
||||
using TDriverHandle::TDriverHandle;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -1143,27 +1141,27 @@ class TFV4aM : public TDriverHandle
|
||||
/// Returns the brake pipe pressure target interpolated from BPT[] for the given handle position.
|
||||
/// </summary>
|
||||
/// <param name="pos">Handle position.</param>
|
||||
double LPP_RP(double pos);
|
||||
double LPP_RP(double pos) const;
|
||||
/// <summary>Returns true if pos is within ±0.5 of i_pos (detent comparison).</summary>
|
||||
bool EQ(double pos, double i_pos);
|
||||
bool EQ(double pos, double i_pos) const;
|
||||
|
||||
public:
|
||||
/// <summary>Computes brake pipe flow for the FV4a/M handle (interpolated BPT, wave modelling, accelerator).</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Initialises CP and RP.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
/// <summary>Sets the reductor adjustment offset.</summary>
|
||||
void SetReductor(double nAdj) /*override*/;
|
||||
void SetReductor(double nAdj) override;
|
||||
/// <summary>Returns Sounds[i] (or 0 if i > 4).</summary>
|
||||
double GetSound(int i) /*override*/;
|
||||
double GetSound(int i) override;
|
||||
/// <summary>Returns pos_table[i].</summary>
|
||||
double GetPos(int i) /*override*/;
|
||||
double GetPos(int i) override;
|
||||
/// <summary>Returns the time chamber pressure (TP).</summary>
|
||||
double GetCP();
|
||||
double GetCP() override;
|
||||
/// <summary>Returns the regulator pressure (5 + TP*0.08 + RedAdj).</summary>
|
||||
double GetRP();
|
||||
double GetRP() override;
|
||||
/// <summary>Default constructor.</summary>
|
||||
inline TFV4aM() : TDriverHandle() {}
|
||||
using TDriverHandle::TDriverHandle;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@@ -1193,32 +1191,31 @@ class TMHZ_EN57 : public TDriverHandle
|
||||
static double const pos_table[11]; //= { -2, 10, -1, 0, 0, 2, 9, 10, 0, 0, 0 };
|
||||
|
||||
/// <summary>Returns the brake pipe pressure target for the given handle position (piecewise).</summary>
|
||||
double LPP_RP(double pos);
|
||||
double LPP_RP(double pos) const;
|
||||
/// <summary>Returns true if pos is within ±0.5 of i_pos.</summary>
|
||||
bool EQ(double pos, double i_pos);
|
||||
bool EQ(double pos, double i_pos) const;
|
||||
|
||||
public:
|
||||
/// <summary>Computes brake pipe flow for MHZ_EN57 (covers handle positions -1..10 with EP/pneumatic mix).</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Initialises CP.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
/// <summary>Sets the reductor adjustment offset.</summary>
|
||||
void SetReductor(double nAdj) /*override*/;
|
||||
void SetReductor(double nAdj) override;
|
||||
/// <summary>Returns Sounds[i] (or 0 if i > 4).</summary>
|
||||
double GetSound(int i) /*override*/;
|
||||
double GetSound(int i) override;
|
||||
/// <summary>Returns pos_table[i].</summary>
|
||||
double GetPos(int i) /*override*/;
|
||||
double GetPos(int i) override;
|
||||
/// <summary>Returns the regulator pressure (RP).</summary>
|
||||
double GetCP() /*override*/;
|
||||
double GetCP() override;
|
||||
/// <summary>Returns the regulator target (5 + RedAdj).</summary>
|
||||
double GetRP() /*override*/;
|
||||
double GetRP() override;
|
||||
/// <summary>Returns EP brake intensity for the given handle position.</summary>
|
||||
double GetEP(double pos);
|
||||
double GetEP(double pos) override;
|
||||
/// <summary>Configures handle parameters (auto/manual overcharge, over-pressure, overcharge dynamics).</summary>
|
||||
void SetParams(bool AO, bool MO, double OverP, double, double OMP, double OPD);
|
||||
void SetParams(bool AO, bool MO, double OverP, double, double OMP, double OPD) override;
|
||||
/// <summary>Default constructor.</summary>
|
||||
inline TMHZ_EN57(void) : TDriverHandle() {}
|
||||
};
|
||||
using TDriverHandle::TDriverHandle;};
|
||||
|
||||
/// <summary>
|
||||
/// MHZ_K5P — Knorr 5-position combined brake handle.
|
||||
@@ -1232,7 +1229,6 @@ class TMHZ_K5P : public TDriverHandle
|
||||
/// <summary>Time chamber pressure [bar].</summary>
|
||||
double TP = 0.0; // zbiornik czasowy
|
||||
/// <summary>Reductor reservoir pressure [bar].</summary>
|
||||
double RP = 0.0; // zbiornik redukcyjny
|
||||
/// <summary>Reductor adjustment offset.</summary>
|
||||
double RedAdj = 0.0; // dostosowanie reduktora cisnienia (krecenie kapturkiem)
|
||||
/// <summary>True while filling-stroke / release wave is active.</summary>
|
||||
@@ -1249,29 +1245,28 @@ class TMHZ_K5P : public TDriverHandle
|
||||
static double const pos_table[11]; //= { -2, 10, -1, 0, 0, 2, 9, 10, 0, 0, 0 };
|
||||
|
||||
/// <summary>Returns true if pos is within ±0.5 of i_pos.</summary>
|
||||
bool EQ(double pos, double i_pos);
|
||||
bool EQ(double pos, double i_pos) const;
|
||||
|
||||
public:
|
||||
/// <summary>Computes brake pipe flow for the K5P 5-position handle (release / cut-off / brake / emergency).</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Initialises CP and enables the time chambers.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
/// <summary>Sets the reductor adjustment offset.</summary>
|
||||
void SetReductor(double nAdj) /*override*/;
|
||||
void SetReductor(double nAdj) override;
|
||||
/// <summary>Returns Sounds[i] (or 0 if i > 4).</summary>
|
||||
double GetSound(int i) /*override*/;
|
||||
double GetSound(int i) override;
|
||||
/// <summary>Returns pos_table[i].</summary>
|
||||
double GetPos(int i) /*override*/;
|
||||
double GetPos(int i) override;
|
||||
/// <summary>Returns CP.</summary>
|
||||
double GetCP() /*override*/;
|
||||
double GetCP() override;
|
||||
/// <summary>Returns the regulator target (5 + TP + RedAdj).</summary>
|
||||
double GetRP() /*override*/;
|
||||
double GetRP() override;
|
||||
/// <summary>Configures handle parameters (auto/manual overcharge, over-pressure, filling-stroke factor, overcharge dynamics).</summary>
|
||||
void SetParams(bool AO, bool MO, double, double, double OMP, double OPD); /*ovveride*/
|
||||
void SetParams(bool AO, bool MO, double, double, double OMP, double OPD) override;
|
||||
|
||||
/// <summary>Default constructor.</summary>
|
||||
inline TMHZ_K5P(void) : TDriverHandle() {}
|
||||
};
|
||||
using TDriverHandle::TDriverHandle;};
|
||||
|
||||
/// <summary>
|
||||
/// MHZ_6P — 6-position combined brake handle (similar logic to K5P with one more detent).
|
||||
@@ -1285,7 +1280,6 @@ class TMHZ_6P : public TDriverHandle
|
||||
/// <summary>Time chamber pressure [bar].</summary>
|
||||
double TP = 0.0; // zbiornik czasowy
|
||||
/// <summary>Reductor reservoir pressure [bar].</summary>
|
||||
double RP = 0.0; // zbiornik redukcyjny
|
||||
/// <summary>Reductor adjustment offset.</summary>
|
||||
double RedAdj = 0.0; // dostosowanie reduktora cisnienia (krecenie kapturkiem)
|
||||
/// <summary>True while filling-stroke / release wave is active.</summary>
|
||||
@@ -1302,29 +1296,28 @@ class TMHZ_6P : public TDriverHandle
|
||||
static double const pos_table[11]; //= { -2, 10, -1, 0, 0, 2, 9, 10, 0, 0, 0 };
|
||||
|
||||
/// <summary>Returns true if pos is within ±0.5 of i_pos.</summary>
|
||||
bool EQ(double pos, double i_pos);
|
||||
bool EQ(double pos, double i_pos) const;
|
||||
|
||||
public:
|
||||
/// <summary>Computes brake pipe flow for the 6P handle.</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Initialises CP and enables the time chambers.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
/// <summary>Sets the reductor adjustment offset.</summary>
|
||||
void SetReductor(double nAdj) /*override*/;
|
||||
void SetReductor(double nAdj) override;
|
||||
/// <summary>Returns Sounds[i] (or 0 if i > 4).</summary>
|
||||
double GetSound(int i) /*override*/;
|
||||
double GetSound(int i) override;
|
||||
/// <summary>Returns pos_table[i].</summary>
|
||||
double GetPos(int i) /*override*/;
|
||||
double GetPos(int i) override;
|
||||
/// <summary>Returns CP.</summary>
|
||||
double GetCP() /*override*/;
|
||||
double GetCP() override;
|
||||
/// <summary>Returns the regulator target (5 + TP + RedAdj).</summary>
|
||||
double GetRP() /*override*/;
|
||||
double GetRP() override;
|
||||
/// <summary>Configures handle parameters (auto/manual overcharge, over-pressure, filling-stroke factor, overcharge dynamics).</summary>
|
||||
void SetParams(bool AO, bool MO, double, double, double OMP, double OPD); /*ovveride*/
|
||||
void SetParams(bool AO, bool MO, double, double, double OMP, double OPD) override;
|
||||
|
||||
/// <summary>Default constructor.</summary>
|
||||
inline TMHZ_6P(void) : TDriverHandle() {}
|
||||
};
|
||||
using TDriverHandle::TDriverHandle;};
|
||||
|
||||
/* FBS2= class(TTDriverHandle)
|
||||
private
|
||||
@@ -1372,17 +1365,17 @@ class TM394 : public TDriverHandle
|
||||
|
||||
public:
|
||||
/// <summary>Computes brake pipe flow for the M394 handle (uses BPT_394).</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Initialises CP and enables the time chamber.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
/// <summary>Sets the reductor adjustment offset.</summary>
|
||||
void SetReductor(double nAdj) /*override*/;
|
||||
void SetReductor(double nAdj) override;
|
||||
/// <summary>Returns CP.</summary>
|
||||
double GetCP() /*override*/;
|
||||
double GetCP() override;
|
||||
/// <summary>Returns max(5, CP) + RedAdj.</summary>
|
||||
double GetRP() /*override*/;
|
||||
double GetRP() override;
|
||||
/// <summary>Returns pos_table[i].</summary>
|
||||
double GetPos(int i) /*override*/;
|
||||
double GetPos(int i) override;
|
||||
|
||||
/// <summary>Default constructor — sets the maximum handle position to 5.</summary>
|
||||
inline TM394(void) : TDriverHandle()
|
||||
@@ -1411,17 +1404,17 @@ class TH14K1 : public TDriverHandle
|
||||
|
||||
public:
|
||||
/// <summary>Computes brake pipe flow for the H14K1 handle.</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Initialises CP and enables the time chambers.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
/// <summary>Sets the reductor adjustment offset.</summary>
|
||||
void SetReductor(double nAdj) /*override*/;
|
||||
void SetReductor(double nAdj) override;
|
||||
/// <summary>Returns CP.</summary>
|
||||
double GetCP() /*override*/;
|
||||
double GetCP() override;
|
||||
/// <summary>Returns the regulator target (5 + RedAdj).</summary>
|
||||
double GetRP() /*override*/;
|
||||
double GetRP() override;
|
||||
/// <summary>Returns pos_table[i].</summary>
|
||||
double GetPos(int i) /*override*/;
|
||||
double GetPos(int i) override;
|
||||
|
||||
/// <summary>Default constructor — sets the maximum handle position to 4.</summary>
|
||||
inline TH14K1(void) : TDriverHandle()
|
||||
@@ -1450,21 +1443,20 @@ class TSt113 : public TH14K1
|
||||
|
||||
public:
|
||||
/// <summary>Computes brake pipe flow for the St113 handle (with EP).</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Returns CP.</summary>
|
||||
double GetCP() /*override*/;
|
||||
double GetCP() override;
|
||||
/// <summary>Returns the regulator target (5 + RedAdj).</summary>
|
||||
double GetRP() /*override*/;
|
||||
double GetRP() override;
|
||||
/// <summary>Returns the current EP intensity.</summary>
|
||||
double GetEP() /*override*/;
|
||||
double GetEP() override;
|
||||
/// <summary>Returns pos_table[i].</summary>
|
||||
double GetPos(int i) /*override*/;
|
||||
double GetPos(int i) override;
|
||||
/// <summary>Enables the time chambers (no pressure init).</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
|
||||
/// <summary>Default constructor.</summary>
|
||||
inline TSt113(void) : TH14K1() {}
|
||||
};
|
||||
using TH14K1::TH14K1;};
|
||||
|
||||
/// <summary>
|
||||
/// Test handle — minimal implementation used during development for verifying
|
||||
@@ -1479,13 +1471,12 @@ class Ttest : public TDriverHandle
|
||||
|
||||
public:
|
||||
/// <summary>Computes brake pipe flow using the FV4a-style BPT table for testing.</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Initialises CP.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
|
||||
/// <summary>Default constructor.</summary>
|
||||
inline Ttest(void) : TDriverHandle() {}
|
||||
};
|
||||
using TDriverHandle::TDriverHandle;};
|
||||
|
||||
/// <summary>
|
||||
/// FD1 auxiliary brake handle — directly drives the cylinder pressure between
|
||||
@@ -1505,18 +1496,17 @@ class TFD1 : public TDriverHandle
|
||||
double Speed = 0.0; // szybkosc dzialania
|
||||
|
||||
/// <summary>Computes the auxiliary brake outflow for this step.</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Initialises MaxBP and the action speed.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
/// <summary>Returns the currently commanded cylinder pressure (BP).</summary>
|
||||
double GetCP() /*override*/;
|
||||
double GetCP() override;
|
||||
/// <summary>Sets the action speed multiplier.</summary>
|
||||
void SetSpeed(double nSpeed);
|
||||
// procedure Init(press: real; MaxBP: real); overload;
|
||||
|
||||
/// <summary>Default constructor.</summary>
|
||||
inline TFD1(void) : TDriverHandle() {}
|
||||
};
|
||||
using TDriverHandle::TDriverHandle;};
|
||||
|
||||
/// <summary>
|
||||
/// H1405 — Knorr auxiliary brake handle (continuous, independent brake).
|
||||
@@ -1532,16 +1522,15 @@ class TH1405 : public TDriverHandle
|
||||
|
||||
public:
|
||||
/// <summary>Computes the auxiliary brake outflow for this step (proportional to handle deflection).</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Initialises MaxBP and enables the time chamber.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
/// <summary>Returns the currently commanded cylinder pressure (BP).</summary>
|
||||
double GetCP() /*override*/;
|
||||
double GetCP() override;
|
||||
// procedure Init(press: real; MaxBP: real); overload;
|
||||
|
||||
/// <summary>Default constructor.</summary>
|
||||
inline TH1405(void) : TDriverHandle() {}
|
||||
};
|
||||
using TDriverHandle::TDriverHandle;};
|
||||
|
||||
/// <summary>
|
||||
/// FVel6 — combined EP + pneumatic brake handle (Czech, 6+1 positions).
|
||||
@@ -1559,23 +1548,22 @@ class TFVel6 : public TDriverHandle
|
||||
|
||||
public:
|
||||
/// <summary>Computes brake pipe flow for FVel6 (continuous EP brake plus pneumatic emergency).</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Returns CP.</summary>
|
||||
double GetCP() /*override*/;
|
||||
double GetCP() override;
|
||||
/// <summary>Returns the regulator target (constant 5 bar).</summary>
|
||||
double GetRP() /*override*/;
|
||||
double GetRP() override;
|
||||
/// <summary>Returns the current EP intensity.</summary>
|
||||
double GetEP() /*override*/;
|
||||
double GetEP() override;
|
||||
/// <summary>Returns pos_table[i].</summary>
|
||||
double GetPos(int i) /*override*/;
|
||||
double GetPos(int i) override;
|
||||
/// <summary>Returns Sounds[i] (or 0 if i > 2).</summary>
|
||||
double GetSound(int i) /*override*/;
|
||||
double GetSound(int i) override;
|
||||
/// <summary>Enables the time chambers.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
|
||||
/// <summary>Default constructor.</summary>
|
||||
inline TFVel6(void) : TDriverHandle() {}
|
||||
};
|
||||
using TDriverHandle::TDriverHandle;};
|
||||
|
||||
/// <summary>
|
||||
/// FVE408 — newer combined EP + pneumatic brake handle (10 positions).
|
||||
@@ -1594,23 +1582,22 @@ class TFVE408 : public TDriverHandle
|
||||
|
||||
public:
|
||||
/// <summary>Computes brake pipe flow for the FVE408 handle.</summary>
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) /*override*/;
|
||||
double GetPF(double i_bcp, double PP, double HP, double dt, double ep) override;
|
||||
/// <summary>Returns CP.</summary>
|
||||
double GetCP() /*override*/;
|
||||
double GetCP() override;
|
||||
/// <summary>Returns the current EP intensity.</summary>
|
||||
double GetEP() /*override*/;
|
||||
double GetEP() override;
|
||||
/// <summary>Returns the regulator target (constant 5 bar).</summary>
|
||||
double GetRP() /*override*/;
|
||||
double GetRP() override;
|
||||
/// <summary>Returns pos_table[i].</summary>
|
||||
double GetPos(int i) /*override*/;
|
||||
double GetPos(int i) override;
|
||||
/// <summary>Returns Sounds[i] (or 0 if i > 2).</summary>
|
||||
double GetSound(int i) /*override*/;
|
||||
double GetSound(int i) override;
|
||||
/// <summary>Enables the time chamber, disables the EP-time chamber.</summary>
|
||||
void Init(double Press) /*override*/;
|
||||
void Init(double Press) override;
|
||||
|
||||
/// <summary>Default constructor.</summary>
|
||||
inline TFVE408(void) : TDriverHandle() {}
|
||||
};
|
||||
using TDriverHandle::TDriverHandle;};
|
||||
|
||||
/// <summary>
|
||||
/// Pneumatic flow rate from one pressure to another through an orifice of area S.
|
||||
|
||||
@@ -25,19 +25,19 @@ public:
|
||||
virtual bool update() = 0;
|
||||
// draws mode-specific user interface
|
||||
inline
|
||||
void render_ui() {
|
||||
void render_ui() const {
|
||||
if( m_userinterface != nullptr ) {
|
||||
m_userinterface->render(); } }
|
||||
inline
|
||||
void begin_ui_frame() {
|
||||
void begin_ui_frame() const {
|
||||
if( m_userinterface != nullptr ) {
|
||||
m_userinterface->begin_ui_frame(); } }
|
||||
inline
|
||||
void set_progress( float const Progress = 0.f, float const Subtaskprogress = 0.f ) {
|
||||
void set_progress( float const Progress = 0.f, float const Subtaskprogress = 0.f ) const {
|
||||
if( m_userinterface != nullptr ) {
|
||||
m_userinterface->set_progress( Progress, Subtaskprogress ); } }
|
||||
inline
|
||||
void set_tooltip( std::string const &Tooltip ) {
|
||||
void set_tooltip( std::string const &Tooltip ) const {
|
||||
if( m_userinterface != nullptr ) {
|
||||
m_userinterface->set_tooltip( Tooltip ); } }
|
||||
// maintenance method, called when the mode is activated
|
||||
|
||||
@@ -38,7 +38,7 @@ void
|
||||
TController::remove_hint( driver_hint const Value ) {
|
||||
|
||||
m_hints.remove_if(
|
||||
[=]( auto const &Hint ) {
|
||||
[Value]( auto const &Hint ) {
|
||||
return std::get<driver_hint>(Hint) == Value; } );
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::batteryoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->BatteryStart != start_t::manual || mvOccupied->Power24vIsAvailable == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -98,7 +98,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::batteryon );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->BatteryStart != start_t::manual || mvOccupied->Power24vIsAvailable == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -111,7 +111,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::cabdeactivation );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->AutomaticCabActivation || mvOccupied->IsCabMaster(); } );
|
||||
break;
|
||||
}
|
||||
@@ -122,7 +122,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::cabactivation );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->AutomaticCabActivation || (mvOccupied->CabMaster == false && mvOccupied->CabActive == 0); } );
|
||||
break;
|
||||
}
|
||||
@@ -134,7 +134,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::radiooff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->Radio == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
}
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const Parameter) {
|
||||
return iRadioChannel == static_cast<int>(Parameter); },
|
||||
Actionparameter );
|
||||
break;
|
||||
@@ -156,7 +156,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::radioon );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->Radio == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -168,7 +168,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::oilpumpoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvOccupied->OilPump };
|
||||
return device.start_type != start_t::manual || device.is_enabled == true || device.is_active == true || mvOccupied->Mains; } );
|
||||
break;
|
||||
@@ -180,7 +180,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::oilpumpon );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvOccupied->OilPump };
|
||||
return device.start_type != start_t::manual || (device.is_enabled == false && device.is_active == false); } );
|
||||
break;
|
||||
@@ -193,7 +193,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::fuelpumpoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvOccupied->FuelPump };
|
||||
return device.start_type != start_t::manual || device.is_enabled == true || device.is_active == true; } );
|
||||
break;
|
||||
@@ -205,7 +205,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::fuelpumpon );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvOccupied->FuelPump };
|
||||
return device.start_type != start_t::manual || (device.is_enabled == false && device.is_active == false); } );
|
||||
break;
|
||||
@@ -218,7 +218,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::pantographairsourcesetauxiliary );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvPantographUnit->bPantKurek3 == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::pantographcompressoron );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvPantographUnit->bPantKurek3 == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -240,7 +240,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::pantographcompressoroff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvPantographUnit->PantCompFlag == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -251,7 +251,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::pantographcompressoron );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvPantographUnit->PantCompFlag == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -262,7 +262,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::pantographsvalveoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvPantographUnit->PantsValve.is_active == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -273,7 +273,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::frontpantographvalveoff );
|
||||
hint(
|
||||
Action,
|
||||
[ this ]( float const Parameter ) -> bool {
|
||||
[ this ]( float const Parameter ) {
|
||||
return mvPantographUnit->Pantographs[end::front].valve.is_active == true || (Parameter > 0 && mvOccupied->Vel > Parameter); },
|
||||
Actionparameter );
|
||||
break;
|
||||
@@ -285,7 +285,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::frontpantographvalveon );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvPantographUnit->Pantographs[end::front].valve.is_active == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -296,7 +296,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::rearpantographvalveoff );
|
||||
hint(
|
||||
Action,
|
||||
[ this ]( float const Parameter ) -> bool {
|
||||
[ this ]( float const Parameter ) {
|
||||
return mvPantographUnit->Pantographs[end::rear].valve.is_active == true || (Parameter > 0 && mvOccupied->Vel > Parameter); },
|
||||
Actionparameter );
|
||||
break;
|
||||
@@ -308,7 +308,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::rearpantographvalveon );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvPantographUnit->Pantographs[end::rear].valve.is_active == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -320,7 +320,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::converteroff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyConverterEnabled == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -331,7 +331,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::converteron );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyConverterExplicitlyEnabled == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -342,7 +342,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
}
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->ConverterOverloadRelayStart != start_t::manual || mvOccupied->ConvOvldFlag == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -352,7 +352,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
}
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->GroundRelayStart != start_t::manual || mvOccupied->GroundRelay == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -362,7 +362,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
}
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->FuseFlag == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -374,7 +374,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::linebreakeropen );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyLineBreakerOpen == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -385,7 +385,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::linebreakerclose );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
// TBD, TODO: replace with consist-wide flag set true if any line breaker is closed?
|
||||
return mvControlling->Mains == false; } );
|
||||
break;
|
||||
@@ -398,7 +398,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::compressoroff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyCompressorEnabled == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -409,7 +409,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::compressoron );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyCompressorExplicitlyEnabled == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -421,7 +421,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::frontmotorblowersoff );
|
||||
hint(
|
||||
Action,
|
||||
[this]( float const Parameter ) -> bool {
|
||||
[this]( float const /*Parameter*/ ) {
|
||||
auto const &device { mvOccupied->MotorBlowers[ end::front ] };
|
||||
return device.start_type != start_t::manual || (device.is_enabled == true && device.is_disabled == false); } );
|
||||
break;
|
||||
@@ -434,7 +434,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::rearmotorblowersoff );
|
||||
hint(
|
||||
Action,
|
||||
[this]( float const Parameter ) -> bool {
|
||||
[this]( float const /*Parameter*/ ) {
|
||||
auto const &device { mvOccupied->MotorBlowers[ end::rear ] };
|
||||
return device.start_type != start_t::manual || (device.is_enabled == true && device.is_disabled == false); } );
|
||||
break;
|
||||
@@ -447,7 +447,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::springbrakeoff );
|
||||
hint(
|
||||
Action,
|
||||
[this]( float const Parameter ) -> bool {
|
||||
[this]( float const /*Parameter*/ ) {
|
||||
return mvOccupied->SpringBrake.Activate == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -458,7 +458,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::springbrakeon );
|
||||
hint(
|
||||
Action,
|
||||
[this]( float const Parameter ) -> bool {
|
||||
[this]( float const /*Parameter*/ ) {
|
||||
return mvOccupied->SpringBrake.Activate == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -470,7 +470,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::manualbrakoff );
|
||||
hint(
|
||||
Action,
|
||||
[this]( float const Parameter ) -> bool {
|
||||
[this]( float const /*Parameter*/ ) {
|
||||
return mvOccupied->LocalBrake != TLocalBrake::ManualBrake || mvOccupied->MBrake == false || mvOccupied->ManualBrakePos == ManualBrakePosNo; } );
|
||||
break;
|
||||
}
|
||||
@@ -481,7 +481,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::manualbrakon );
|
||||
hint(
|
||||
Action,
|
||||
[this]( float const Parameter ) -> bool {
|
||||
[this]( float const /*Parameter*/ ) {
|
||||
return mvOccupied->LocalBrake != TLocalBrake::ManualBrake || mvOccupied->MBrake == false || mvOccupied->ManualBrakePos == 0; } );
|
||||
break;
|
||||
}
|
||||
@@ -490,33 +490,31 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
if( AIControllFlag ) {
|
||||
while( mvControlling->RList[mvControlling->MainCtrlPos].Mn == 0
|
||||
&& mvControlling->IncMainCtrl(1) ) {
|
||||
;
|
||||
// all work is done in the loop header
|
||||
}
|
||||
}
|
||||
remove_master_controller_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this]( float const Parameter ) -> bool {
|
||||
[this]( float const /*Parameter*/ ) {
|
||||
return mvControlling->RList[mvControlling->MainCtrlPos].Mn > 0; } );
|
||||
break;
|
||||
}
|
||||
case driver_hint::mastercontrollersetseriesmode: {
|
||||
if( AIControllFlag ) {
|
||||
if( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) {
|
||||
// limit yourself to series mode
|
||||
if( mvControlling->ScndCtrlPos ) {
|
||||
mvControlling->DecScndCtrl( 2 );
|
||||
}
|
||||
while( mvControlling->RList[mvControlling->MainCtrlPos].Bn > 1
|
||||
&& mvControlling->DecMainCtrl(1) ) {
|
||||
; // all work is performed in the header
|
||||
}
|
||||
if (AIControllFlag && mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1) {
|
||||
// limit yourself to series mode
|
||||
if( mvControlling->ScndCtrlPos ) {
|
||||
mvControlling->DecScndCtrl( 2 );
|
||||
}
|
||||
while( mvControlling->RList[mvControlling->MainCtrlPos].Bn > 1
|
||||
&& mvControlling->DecMainCtrl(1) ) {
|
||||
// all work is performed in the header
|
||||
}
|
||||
}
|
||||
remove_master_controller_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this]( float const Parameter ) -> bool {
|
||||
[this]( float const /*Parameter*/ ) {
|
||||
return mvControlling->RList[mvControlling->MainCtrlPos].Bn < 2; } );
|
||||
break;
|
||||
}
|
||||
@@ -527,7 +525,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_master_controller_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvControlling->IsMainCtrlNoPowerPos() && mvControlling->IsScndCtrlNoPowerPos(); } );
|
||||
break;
|
||||
}
|
||||
@@ -535,15 +533,15 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
if( AIControllFlag ) {
|
||||
while( false == mvControlling->EIMDirectionChangeAllow()
|
||||
&& mvControlling->DecMainCtrl(1) ) {
|
||||
;
|
||||
// all work is done in the loop header
|
||||
}
|
||||
}
|
||||
remove_master_controller_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvControlling->EIMDirectionChangeAllow(); },
|
||||
mvControlling->MainCtrlMaxDirChangePos );
|
||||
static_cast<float>(mvControlling->MainCtrlMaxDirChangePos) );
|
||||
break;
|
||||
}
|
||||
case driver_hint::tractiveforcedecrease: {
|
||||
@@ -553,13 +551,13 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_master_controller_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const Parameter) {
|
||||
return std::abs(mvControlling->Ft) <= Parameter; },
|
||||
std::min(
|
||||
static_cast<float>(std::min(
|
||||
0.0,
|
||||
std::max(
|
||||
std::abs( mvControlling->Ft ) * 0.95,
|
||||
std::abs( mvControlling->Ft ) - 5.0 ) ) );
|
||||
std::abs( mvControlling->Ft ) - 5.0 ) )) );
|
||||
break;
|
||||
}
|
||||
case driver_hint::tractiveforceincrease: {
|
||||
@@ -575,21 +573,19 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
}
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return AccDesired <= EU07_AI_NOACCELERATION || (false == Ready && false == mvOccupied->ShuntMode) || AccDesired - AbsAccS <= 0.05 ||
|
||||
(mvOccupied->EIMCtrlType > 0 ? mvControlling->eimic_real >= 1.0 : mvControlling->IsScndCtrlMaxPowerPos() && mvControlling->IsMainCtrlMaxPowerPos()); } );
|
||||
break;
|
||||
}
|
||||
case driver_hint::bufferscompress: {
|
||||
if( AIControllFlag ) {
|
||||
if( std::abs( mvControlling->Ft ) < 50000.0 ) {
|
||||
IncSpeed();
|
||||
}
|
||||
if (AIControllFlag && std::abs( mvControlling->Ft ) < 50000.0) {
|
||||
IncSpeed();
|
||||
}
|
||||
remove_master_controller_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return std::abs(mvControlling->Ft) > 30.0 || (OrderCurrentGet() & Disconnect) == 0; } );
|
||||
break;
|
||||
}
|
||||
@@ -601,7 +597,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_master_controller_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvControlling->IsScndCtrlNoPowerPos(); } );
|
||||
break;
|
||||
}
|
||||
@@ -613,7 +609,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::waterpumpoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvControlling->WaterPump };
|
||||
return device.start_type != start_t::manual || (device.is_enabled == true && device.is_disabled == false) || device.is_active == true; } );
|
||||
break;
|
||||
@@ -625,7 +621,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::waterpumpon );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvControlling->WaterPump };
|
||||
return device.start_type != start_t::manual || (device.is_enabled == false && device.is_active == false); } );
|
||||
break;
|
||||
@@ -637,7 +633,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::waterpumpbreakeroff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvControlling->WaterPump };
|
||||
return device.breaker == true; } );
|
||||
break;
|
||||
@@ -649,7 +645,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::waterpumpbreakeron );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvControlling->WaterPump };
|
||||
return device.breaker == false; } );
|
||||
break;
|
||||
@@ -661,7 +657,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::waterheateroff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvControlling->WaterHeater };
|
||||
return device.is_enabled == true; } );
|
||||
break;
|
||||
@@ -673,7 +669,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::waterheateron );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvControlling->WaterHeater };
|
||||
return device.is_enabled == false; } );
|
||||
break;
|
||||
@@ -685,7 +681,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::waterheaterbreakeroff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvControlling->WaterHeater };
|
||||
return device.breaker == true; } );
|
||||
break;
|
||||
@@ -697,7 +693,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::waterheaterbreakeron );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvControlling->WaterHeater };
|
||||
return device.breaker == false; } );
|
||||
break;
|
||||
@@ -709,7 +705,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::watercircuitslinkoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvControlling->dizel_heat.auxiliary_water_circuit == false || mvControlling->WaterCircuitsLink == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -720,7 +716,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::watercircuitslinkon );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvControlling->dizel_heat.auxiliary_water_circuit == false || mvControlling->WaterCircuitsLink == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -728,7 +724,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
// NOTE: this action doesn't have AI component
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return false == IsHeatingTemperatureTooLow; } );
|
||||
break;
|
||||
}
|
||||
@@ -736,7 +732,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
// NOTE: this action doesn't have AI component
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvControlling->ScndPipePress > 4.5 || mvControlling->VeselVolume == 0.0; } );
|
||||
break;
|
||||
}
|
||||
@@ -744,7 +740,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
// NOTE: this action doesn't have AI component
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvPantographUnit->PantPress >= (is_emu() ? (mvPantographUnit->PantPressLockActive ? 4.6 : 2.6) : 4.2); } );
|
||||
break;
|
||||
}
|
||||
@@ -752,7 +748,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
// NOTE: this action doesn't have AI component
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return ExchangeTime <= 0; } );
|
||||
break;
|
||||
}
|
||||
@@ -760,7 +756,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
// NOTE: this action doesn't have AI component
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAtPassengerStop == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -773,19 +769,16 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
// driver_hint_brakingforcesetzero
|
||||
// driver_hint_brakingforcelap
|
||||
case driver_hint::trainbrakesetpipeunlock: {
|
||||
if( AIControllFlag ) {
|
||||
if( mvOccupied->HandleUnlock != -3 ) {
|
||||
while( BrakeCtrlPosition >= mvOccupied->HandleUnlock
|
||||
&& BrakeLevelAdd(-1) ) {
|
||||
// all work is done in the header
|
||||
;
|
||||
}
|
||||
if (AIControllFlag && mvOccupied->HandleUnlock != -3) {
|
||||
while( BrakeCtrlPosition >= mvOccupied->HandleUnlock
|
||||
&& BrakeLevelAdd(-1) ) {
|
||||
// all work is done in the header
|
||||
}
|
||||
}
|
||||
remove_train_brake_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->HandleUnlock == -3 || BrakeCtrlPosition == mvOccupied->HandleUnlock; } );
|
||||
break;
|
||||
}
|
||||
@@ -797,7 +790,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_train_brake_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return is_equal(mvOccupied->fBrakeCtrlPos, mvOccupied->Handle->GetPos(bh_RP), 0.2) || (mvOccupied->Handle->Time && mvOccupied->Handle->GetCP() > mvOccupied->HighPipePress - 0.05); } );
|
||||
// return ( BrakeCtrlPosition == gbh_RP ); } );
|
||||
break;
|
||||
@@ -815,7 +808,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_train_brake_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsConsistBraked /*|| ( ( OrderCurrentGet() & Disconnect ) == 0 ) */; } );
|
||||
break;
|
||||
}
|
||||
@@ -830,9 +823,9 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_train_brake_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const Parameter) {
|
||||
return std::abs(mvControlling->Fb) <= Parameter; },
|
||||
std::min( 0.0, 0.95 * std::abs( mvControlling->Fb ) ) ); // keep hint until 5% decrease
|
||||
static_cast<float>(std::min( 0.0, 0.95 * std::abs( mvControlling->Fb ) )) ); // keep hint until 5% decrease
|
||||
break;
|
||||
}
|
||||
case driver_hint::brakingforceincrease: {
|
||||
@@ -846,23 +839,25 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_train_brake_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const Parameter) {
|
||||
return std::abs(mvControlling->Fb) > Parameter || is_equal(mvOccupied->fBrakeCtrlPos, mvOccupied->Handle->GetPos(bh_EB), 0.2); },
|
||||
std::max(
|
||||
static_cast<float>(std::max(
|
||||
0.0,
|
||||
std::max(
|
||||
std::abs( mvControlling->Fb ) * 1.05,
|
||||
std::abs( mvControlling->Fb ) + 5.0 ) ) );
|
||||
std::abs( mvControlling->Fb ) + 5.0 ) )) );
|
||||
break;
|
||||
}
|
||||
case driver_hint::brakingforcesetzero: { // releases both train and independent brake
|
||||
if( AIControllFlag ) {
|
||||
while( true == DecBrake() ) { ; }
|
||||
while( true == DecBrake() ) {
|
||||
// all work is done in the loop condition
|
||||
}
|
||||
}
|
||||
remove_train_brake_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return Ready && fReady < 0.4 && is_equal(mvOccupied->fBrakeCtrlPos, mvOccupied->Handle->GetPos(bh_RP), 0.2); } );
|
||||
break;
|
||||
}
|
||||
@@ -877,18 +872,16 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
}
|
||||
// independent brake
|
||||
case driver_hint::independentbrakeapply: {
|
||||
if( AIControllFlag ) {
|
||||
if( mvOccupied->LocalBrakePosA < 1.0 ) {
|
||||
mvOccupied->IncLocalBrakeLevel( LocalBrakePosNo );
|
||||
if (mvOccupied->EIMCtrlEmergency) {
|
||||
mvOccupied->DecLocalBrakeLevel(1);
|
||||
if (AIControllFlag && mvOccupied->LocalBrakePosA < 1.0) {
|
||||
mvOccupied->IncLocalBrakeLevel( LocalBrakePosNo );
|
||||
if (mvOccupied->EIMCtrlEmergency) {
|
||||
mvOccupied->DecLocalBrakeLevel(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
remove_hint( driver_hint::independentbrakerelease );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const Parameter) {
|
||||
return mvOccupied->LocalBrakePosA >= Parameter; },
|
||||
( LocalBrakePosNo - ( mvOccupied->EIMCtrlEmergency ? 1 : 0 ) ) / LocalBrakePosNo );
|
||||
break;
|
||||
@@ -900,7 +893,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::independentbrakeapply );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->LocalBrakePosA < 0.05; } );
|
||||
break;
|
||||
}
|
||||
@@ -912,7 +905,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_reverser_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->DirActive * mvOccupied->CabActive > 0; } );
|
||||
break;
|
||||
}
|
||||
@@ -923,7 +916,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_reverser_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->DirActive * mvOccupied->CabActive < 0; } );
|
||||
break;
|
||||
}
|
||||
@@ -936,7 +929,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_reverser_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return iDirection == iDirectionOrder; } );
|
||||
break;
|
||||
}
|
||||
@@ -947,7 +940,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_reverser_hints();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->DirActive == 0; } );
|
||||
break;
|
||||
}
|
||||
@@ -959,7 +952,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::sandingoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvControlling->Sand == 0 || mvControlling->SandDose == true || mvControlling->SlippingWheels == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -970,7 +963,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::sandingon );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvControlling->Sand == 0 || mvControlling->SandDose == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -980,7 +973,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
}
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvControlling->ASBType != 1 || (mvControlling->Hamulec->GetBrakeStatus() & b_asb) != 0 || mvControlling->SlippingWheels == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -992,7 +985,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::hornoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
// NOTE: we provide slightly larger horn activation window for human driver
|
||||
return fWarningDuration + 5.0 < 0.05 || mvOccupied->WarningSignal != 0; } );
|
||||
break;
|
||||
@@ -1019,7 +1012,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
// TODO: remove other door lock hints
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->Doors.has_lock == false || mvOccupied->Doors.lock_enabled == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -1031,7 +1024,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::departuresignaloff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->Doors.has_warning == false || mvOccupied->Doors.has_autowarning == true || mvOccupied->DepartureSignal == true || mvOccupied->Vel > 5.0; } );
|
||||
break;
|
||||
}
|
||||
@@ -1042,7 +1035,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::departuresignalon );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->Doors.has_warning == false || mvOccupied->Doors.has_autowarning == true || mvOccupied->DepartureSignal == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -1055,7 +1048,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::doorrightclose );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyDoorOpen[side::right] == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -1067,7 +1060,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::doorrightopen );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyDoorOpen[side::right] == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -1079,7 +1072,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::doorleftclose );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyDoorOpen[side::left] == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -1091,7 +1084,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::doorleftopen );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyDoorOpen[side::left] == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -1102,7 +1095,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::doorrightpermitoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyDoorPermitActive[side::right] == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -1113,7 +1106,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::doorrightpermiton );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyDoorPermitActive[side::right] == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -1124,7 +1117,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::doorleftpermitoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyDoorPermitActive[side::left] == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -1135,7 +1128,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::doorleftpermiton );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return IsAnyDoorPermitActive[side::left] == false; } );
|
||||
break;
|
||||
}
|
||||
@@ -1148,7 +1141,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::consistlightsoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvOccupied->CompartmentLights };
|
||||
return Global.fLuminance * ConsistShade > 0.40 || device.start_type != start_t::manual || (device.is_enabled == true && device.is_disabled == false) || device.is_active == true; } );
|
||||
break;
|
||||
@@ -1161,7 +1154,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::consistlightson );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const &device { mvOccupied->CompartmentLights };
|
||||
return Global.fLuminance * ConsistShade < 0.35 || device.start_type != start_t::manual || (device.is_enabled == false && device.is_active == false); } );
|
||||
break;
|
||||
@@ -1174,7 +1167,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::consistheatingoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->HeatingAllow == true; } );
|
||||
break;
|
||||
}
|
||||
@@ -1185,52 +1178,48 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::consistheatingon );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return mvOccupied->HeatingAllow == false; } );
|
||||
break;
|
||||
}
|
||||
|
||||
case driver_hint::securitysystemreset: {
|
||||
if( AIControllFlag ) {
|
||||
if (mvOccupied->SecuritySystem.is_blinking())
|
||||
mvOccupied->SecuritySystemReset();
|
||||
}
|
||||
if (AIControllFlag && mvOccupied->SecuritySystem.is_blinking())
|
||||
mvOccupied->SecuritySystemReset();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return !mvOccupied->SecuritySystem.is_vigilance_blinking(); } );
|
||||
break;
|
||||
}
|
||||
case driver_hint::shpsystemreset: {
|
||||
if( AIControllFlag ) {
|
||||
if (mvOccupied->SecuritySystem.is_cabsignal_blinking())
|
||||
mvOccupied->SecuritySystem.cabsignal_reset();
|
||||
}
|
||||
if (AIControllFlag && mvOccupied->SecuritySystem.is_cabsignal_blinking())
|
||||
mvOccupied->SecuritySystem.cabsignal_reset();
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return !mvOccupied->SecuritySystem.is_cabsignal_blinking(); } );
|
||||
break;
|
||||
}
|
||||
case driver_hint::couplingadapterattach: {
|
||||
// TODO: run also for potential settings-based virtual assistant
|
||||
if( AIControllFlag ) {
|
||||
pVehicles[ end::front ]->attach_coupler_adapter( Actionparameter );
|
||||
pVehicles[ end::front ]->attach_coupler_adapter( static_cast<int>(Actionparameter) );
|
||||
}
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const Parameter) {
|
||||
auto const &device { pVehicles[ end::front ]->MoverParameters->Couplers[ static_cast<int>( Parameter ) ] };
|
||||
return device.type() == TCouplerType::Automatic; } );
|
||||
break;
|
||||
}
|
||||
case driver_hint::couplingadapterremove: {
|
||||
if( AIControllFlag || Global.AITrainman ) {
|
||||
pVehicles[ end::front ]->remove_coupler_adapter( Actionparameter );
|
||||
pVehicles[ end::front ]->remove_coupler_adapter( static_cast<int>(Actionparameter) );
|
||||
}
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const Parameter) {
|
||||
auto const &device { pVehicles[ end::front ]->MoverParameters->Couplers[ static_cast<int>( Parameter ) ] };
|
||||
return false == device.has_adapter(); } );
|
||||
break;
|
||||
@@ -1245,7 +1234,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::lightsoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return pVehicles[end::front]->has_signal_pc1_on(); } );
|
||||
break;
|
||||
}
|
||||
@@ -1258,7 +1247,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::lightsoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return pVehicles[end::front]->has_signal_pc2_on(); } );
|
||||
break;
|
||||
}
|
||||
@@ -1275,7 +1264,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::lightsoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const activeend { mvOccupied->CabActive >= 0 ? end::front : end::rear };
|
||||
auto const consistfront { mvOccupied->DirActive >= 0 ? end::front : end::rear };
|
||||
return pVehicles[consistfront]->has_signal_on(activeend, light::headlight_right) && pVehicles[1 - consistfront]->has_signal_on(1 - activeend, light::headlight_left); } );
|
||||
@@ -1290,7 +1279,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::lightsoff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return pVehicles[end::rear]->has_signal_pc5_on(); } );
|
||||
break;
|
||||
}
|
||||
@@ -1304,7 +1293,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::headcodetb1 );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
auto const activeend { mvOccupied->CabActive >= 0 ? end::front : end::rear };
|
||||
auto const consistfront { mvOccupied->DirActive >= 0 ? end::front : end::rear };
|
||||
return pVehicles[consistfront]->has_signal_on(activeend, 0) && pVehicles[1 - consistfront]->has_signal_on(1 - activeend, 0); } );
|
||||
@@ -1318,7 +1307,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::releaseroff );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return true == mvOccupied->Hamulec->Releaser(); } );
|
||||
break;
|
||||
}
|
||||
@@ -1329,7 +1318,7 @@ TController::cue_action( driver_hint const Action, float const Actionparameter )
|
||||
remove_hint( driver_hint::releaseron );
|
||||
hint(
|
||||
Action,
|
||||
[this](float const Parameter) -> bool {
|
||||
[this](float const /*Parameter*/) {
|
||||
return false == mvOccupied->Hamulec->Releaser(); } );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ enum class driver_hint {
|
||||
#ifdef DRIVER_HINT_CONTENT
|
||||
#define DRIVER_HINT_DEF(a, b) b,
|
||||
|
||||
const char *driver_hints_texts[] =
|
||||
const char *const driver_hints_texts[] =
|
||||
{
|
||||
#include "application/driverhints_def.h"
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ drivingaid_panel::update() {
|
||||
|| controlled->Mechanik == nullptr ) { return; }
|
||||
|
||||
auto const *mover = controlled->MoverParameters;
|
||||
auto const *driver = controlled->Mechanik;
|
||||
auto const *vehicledriver = controlled->Mechanik;
|
||||
auto const *owner = controlled->ctOwner != nullptr ? controlled->ctOwner : controlled->Mechanik;
|
||||
|
||||
{ // throttle, velocity, speed limits and grade
|
||||
@@ -61,8 +61,7 @@ drivingaid_panel::update() {
|
||||
// grade
|
||||
std::string gradetext;
|
||||
auto const reverser { ( mover->DirActive > 0 ? 1 : -1 ) };
|
||||
auto const grade { controlled->VectorFront().y * 100 * ( controlled->DirectionGet() == reverser ? 1 : -1 ) * reverser };
|
||||
if( std::abs( grade ) >= 0.25 ) {
|
||||
if( auto const grade { controlled->VectorFront().y * 100 * ( controlled->DirectionGet() == reverser ? 1 : -1 ) * reverser }; std::abs( grade ) >= 0.25 ) {
|
||||
std::snprintf(
|
||||
m_buffer.data(), m_buffer.size(),
|
||||
STR_C(" Grade: %.1f%%%%"),
|
||||
@@ -87,8 +86,7 @@ drivingaid_panel::update() {
|
||||
// then take into account speed change ahead, compare it with speed after potentially clearing last limit
|
||||
// lower of these two takes priority; otherwise limit lasts at least until potential last limit is cleared
|
||||
auto const noactivespeedlimit { owner->VelLimitLastDist.second < 0 };
|
||||
auto const speedatproximitydistance { min_speed( schedulespeedlimit, static_cast<int>( owner->VelNext ) ) };
|
||||
if( speedatproximitydistance == nextspeedlimit ) {
|
||||
if( auto const speedatproximitydistance { min_speed( schedulespeedlimit, static_cast<int>( owner->VelNext ) ) }; speedatproximitydistance == nextspeedlimit ) {
|
||||
if( noactivespeedlimit ) {
|
||||
nextspeedlimit = speedatproximitydistance;
|
||||
nextspeedlimitdistance = owner->ActualProximityDist;
|
||||
@@ -142,8 +140,8 @@ drivingaid_panel::update() {
|
||||
std::snprintf(
|
||||
m_buffer.data(), m_buffer.size(),
|
||||
STR_C("Throttle: %3d+%d %c%s"),
|
||||
mover->EIMCtrlType > 0 ? std::max(0, static_cast<int>(100.4 * mover->eimic_real)) : driver->Controlling()->MainCtrlPos,
|
||||
mover->EIMCtrlType > 0 ? driver->Controlling()->MainCtrlPos : driver->Controlling()->ScndCtrlPos,
|
||||
mover->EIMCtrlType > 0 ? std::max(0, static_cast<int>(100.4 * mover->eimic_real)) : vehicledriver->Controlling()->MainCtrlPos,
|
||||
mover->EIMCtrlType > 0 ? vehicledriver->Controlling()->MainCtrlPos : vehicledriver->Controlling()->ScndCtrlPos,
|
||||
mover->SpeedCtrlUnit.IsActive ? 'T' :
|
||||
mover->DirActive > 0 ? 'D' :
|
||||
mover->DirActive < 0 ? 'R' :
|
||||
@@ -253,12 +251,7 @@ scenario_panel::render() {
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2S( size_min.x, size_min.y ), ImVec2S( size_max.x, size_max.y ) );
|
||||
}
|
||||
auto const panelname { (
|
||||
title.empty() ?
|
||||
m_name :
|
||||
title )
|
||||
+ "###" + m_name };
|
||||
if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
|
||||
if( auto const panelname { ( title.empty() ? m_name : title ) + "###" + m_name }; true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
|
||||
// potential assignment section
|
||||
auto const *owner { (
|
||||
m_nearest->Mechanik != nullptr && m_nearest->Mechanik->primary() ?
|
||||
@@ -274,21 +267,19 @@ scenario_panel::render() {
|
||||
}
|
||||
// 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::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), "%s", line.data.c_str() );
|
||||
}
|
||||
// hints
|
||||
if( owner != nullptr ) {
|
||||
if( true == ImGui::CollapsingHeader( STR_C("Hints"), ImGuiTreeNodeFlags_DefaultOpen ) ) {
|
||||
for( auto const &hint : owner->m_hints ) {
|
||||
auto const isdone { std::get<TController::hintpredicate>( hint )( std::get<float>( hint ) ) };
|
||||
auto const hintcolor{ (
|
||||
isdone ?
|
||||
colors::uitextgreen :
|
||||
Global.UITextColor ) };
|
||||
ImGui::PushStyleColor( ImGuiCol_Text, { hintcolor.r, hintcolor.g, hintcolor.b, hintcolor.a } );
|
||||
ImGui::TextWrapped( Translations.lookup_c(driver_hints_texts[(size_t)std::get<driver_hint>( hint )], true), std::get<float>( hint ) );
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
if (owner != nullptr && true == ImGui::CollapsingHeader( STR_C("Hints"), ImGuiTreeNodeFlags_DefaultOpen )) {
|
||||
for( auto const &hint : owner->m_hints ) {
|
||||
auto const isdone { std::get<TController::hintpredicate>( hint )( std::get<float>( hint ) ) };
|
||||
auto const hintcolor{ (
|
||||
isdone ?
|
||||
colors::uitextgreen :
|
||||
Global.UITextColor ) };
|
||||
ImGui::PushStyleColor( ImGuiCol_Text, { hintcolor.r, hintcolor.g, hintcolor.b, hintcolor.a } );
|
||||
ImGui::TextWrapped( Translations.lookup_c(driver_hints_texts[(size_t)std::get<driver_hint>( hint )], true), std::get<float>( hint ) );
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -364,8 +355,7 @@ timetable_panel::update() {
|
||||
//odejmij lokomotywy czynne, a przynajmniej aktualną
|
||||
consistmass -= owner->pVehicle->MoverParameters->TotalMass;
|
||||
// subtract potential other half of a two-part vehicle
|
||||
auto const *previous { owner->pVehicle->Prev( coupling::permanent ) };
|
||||
if( previous != nullptr ) { consistmass -= previous->MoverParameters->TotalMass; }
|
||||
if( auto const *previous { owner->pVehicle->Prev( coupling::permanent ) }; previous != nullptr ) { consistmass -= previous->MoverParameters->TotalMass; }
|
||||
auto const *next { owner->pVehicle->Next( coupling::permanent ) };
|
||||
if( next != nullptr ) { consistmass -= next->MoverParameters->TotalMass; }
|
||||
}
|
||||
@@ -428,13 +418,13 @@ timetable_panel::update() {
|
||||
&& i < table.StationIndex
|
||||
&& ( tableline->Ah < 0 // pass-through, always valid
|
||||
|| tableline->is_maintenance // maintenance stop, always valid
|
||||
|| time.wHour * 60 + time.wMinute + time.wSecond * 0.0167 >= tableline->Dh * 60 + tableline->Dm ) ) };
|
||||
|| time.wHour * 60 + time.wMinute + time.wSecond * 0.0167 >= static_cast<float>(tableline->Dh * 60) + tableline->Dm ) ) };
|
||||
auto const loadchangeinprogress { ( static_cast<int>(std::ceil(-1.0 * owner->fStopTime)) > 0 ) };
|
||||
auto const isatpassengerstop { true == owner->IsAtPassengerStop && vehicle->MoverParameters->Vel < 1.0 };
|
||||
auto const traveltime { (
|
||||
i < 2 ? " " :
|
||||
tableline->Ah >= 0 ? to_minutes_str( CompareTime( table.TimeTable[ i - 1 ].Dh, table.TimeTable[ i - 1 ].Dm, tableline->Ah, tableline->Am ), false, 3 ) :
|
||||
to_minutes_str( std::max( 0.0, CompareTime( table.TimeTable[ i - 1 ].Dh, table.TimeTable[ i - 1 ].Dm, tableline->Dh, tableline->Dm ) - 0.5 ), false, 3 ) ) };
|
||||
tableline->Ah >= 0 ? to_minutes_str( static_cast<float>(CompareTime( table.TimeTable[ i - 1 ].Dh, table.TimeTable[ i - 1 ].Dm, tableline->Ah, tableline->Am )), false, 3 ) :
|
||||
to_minutes_str( static_cast<float>(std::max( 0.0, CompareTime( table.TimeTable[ i - 1 ].Dh, table.TimeTable[ i - 1 ].Dm, tableline->Dh, tableline->Dm ) - 0.5 )), false, 3 ) ) };
|
||||
auto const linecolor { (
|
||||
i != table.StationStart ? Global.UITextColor :
|
||||
loadchangeinprogress ? colors::uitextred :
|
||||
@@ -486,19 +476,14 @@ timetable_panel::render() {
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2S( size_min.x * horizontalScale, size_min.y ), ImVec2S( size_max.x * horizontalScale, size_max.y ) );
|
||||
}
|
||||
auto const panelname { (
|
||||
title.empty() ?
|
||||
m_name :
|
||||
title )
|
||||
+ "###" + m_name };
|
||||
if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
|
||||
if( auto const panelname { ( title.empty() ? m_name : title ) + "###" + m_name }; true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
|
||||
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::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), "%s", line.data.c_str() );
|
||||
}
|
||||
if( is_expanded ) {
|
||||
ImGui::PushStyleVar( ImGuiStyleVar_ItemSpacing, ImVec2( 1, 0 ) );
|
||||
for( auto const &line : m_tablelines ) {
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), "%s", line.data.c_str() );
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
@@ -576,25 +561,16 @@ debug_panel::render() {
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2S( size_min.x, size_min.y ), ImVec2S( size_max.x, size_max.y ) );
|
||||
}
|
||||
auto const panelname { (
|
||||
title.empty() ?
|
||||
m_name :
|
||||
title )
|
||||
+ "###" + m_name };
|
||||
if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
|
||||
if( auto const panelname { ( title.empty() ? m_name : title ) + "###" + m_name }; 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() );
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), "%s", line.data.c_str() );
|
||||
}
|
||||
// sections
|
||||
ImGui::Separator();
|
||||
if( true == render_section( "Vehicle", m_vehiclelines ) ) {
|
||||
if( DebugModeFlag && m_input.mover && m_input.mover->DamageFlag != 0 ) {
|
||||
if( true == ImGui::Button( "Stop and repair consist" ) ) {
|
||||
command_relay relay;
|
||||
relay.post(user_command::resetconsist, 0.0, 0.0, GLFW_PRESS, 0, glm::vec3(0.0f), &m_input.vehicle->name());
|
||||
}
|
||||
}
|
||||
if (true == render_section( "Vehicle", m_vehiclelines ) && DebugModeFlag && m_input.mover && m_input.mover->DamageFlag != 0 && true == ImGui::Button( "Stop and repair consist" )) {
|
||||
command_relay commandrelay;
|
||||
commandrelay.post(user_command::resetconsist, 0.0, 0.0, GLFW_PRESS, 0, glm::vec3(0.0f), &m_input.vehicle->name());
|
||||
}
|
||||
render_section( "Vehicle Engine", m_enginelines );
|
||||
render_section( "Vehicle AI", m_ailines );
|
||||
@@ -611,13 +587,13 @@ debug_panel::render() {
|
||||
render_section_developer(); // Developer tools
|
||||
#ifdef WITH_UART
|
||||
if(true == render_section( "UART", m_uartlines)) {
|
||||
int ports_num = UartStatus.available_ports.size();
|
||||
char **avlports = new char*[ports_num];
|
||||
auto ports_num = static_cast<int>(UartStatus.available_ports.size());
|
||||
auto avlports = new char*[ports_num];
|
||||
for (int i=0; i < ports_num; i++) {
|
||||
avlports[i] = (char *) UartStatus.available_ports[i].c_str();
|
||||
}
|
||||
ImGui::Combo("Port", &UartStatus.selected_port_index, avlports, ports_num);
|
||||
ImGui::Combo("Baud", &UartStatus.selected_baud_index, uart_baudrates_list, uart_baudrates_list_num);
|
||||
ImGui::Combo("Baud", &UartStatus.selected_baud_index, uart_baudrates_list, static_cast<int>(uart_baudrates_list_num));
|
||||
ImGui::Checkbox("Enabled", &UartStatus.enabled);
|
||||
}
|
||||
#endif
|
||||
@@ -625,8 +601,8 @@ debug_panel::render() {
|
||||
ImGui::Separator();
|
||||
bool flag = DebugModeFlag;
|
||||
if (ImGui::Checkbox("Debug Mode", &flag)) {
|
||||
command_relay relay;
|
||||
relay.post(user_command::debugtoggle, 0.0, 0.0, GLFW_RELEASE, 0);
|
||||
command_relay commandrelay;
|
||||
commandrelay.post(user_command::debugtoggle, 0.0, 0.0, GLFW_RELEASE, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,8 +623,8 @@ debug_panel::render_section_scenario() {
|
||||
auto fogrange = std::log( Global.fFogEnd );
|
||||
if( ImGui::SliderFloat(
|
||||
( to_string( std::exp( fogrange ), 0, 5 ) + " m###fogend" ).c_str(), &fogrange, std::log( 10.0f ), std::log( 50000.0f ), "Fog distance" ) ) {
|
||||
command_relay relay;
|
||||
relay.post(
|
||||
command_relay commandrelay;
|
||||
commandrelay.post(
|
||||
user_command::setweather,
|
||||
std::clamp( std::exp( fogrange ), 10.0f, 50000.0f ),
|
||||
Global.Overcast,
|
||||
@@ -661,8 +637,8 @@ debug_panel::render_section_scenario() {
|
||||
(to_string(Airtemperature, 1) + " deg C###Airtemperature").c_str(),
|
||||
&Airtemperature, -35.0f, 40.0f, "Air Temperature"))
|
||||
{
|
||||
command_relay relay;
|
||||
relay.post(
|
||||
command_relay commandrelay;
|
||||
commandrelay.post(
|
||||
user_command::settemperature,
|
||||
std::clamp(Airtemperature, -35.0f, 40.0f),
|
||||
Global.Overcast,
|
||||
@@ -673,8 +649,8 @@ debug_panel::render_section_scenario() {
|
||||
{
|
||||
if( ImGui::SliderFloat(
|
||||
( to_string( Global.Overcast, 2, 5 ) + " (" + Global.Weather + ")###overcast" ).c_str(), &Global.Overcast, 0.0f, 2.0f, "Cloud cover" ) ) {
|
||||
command_relay relay;
|
||||
relay.post(
|
||||
command_relay commandrelay;
|
||||
commandrelay.post(
|
||||
user_command::setweather,
|
||||
Global.fFogEnd,
|
||||
std::clamp( Global.Overcast, 0.0f, 2.0f ),
|
||||
@@ -685,8 +661,8 @@ debug_panel::render_section_scenario() {
|
||||
{
|
||||
if( ImGui::SliderFloat(
|
||||
( to_string( Global.fMoveLight, 0, 5 ) + " (" + Global.Season + ")###movelight" ).c_str(), &Global.fMoveLight, 0.0f, 364.0f, "Day of year" ) ) {
|
||||
command_relay relay;
|
||||
relay.post(
|
||||
command_relay commandrelay;
|
||||
commandrelay.post(
|
||||
user_command::setdatetime,
|
||||
std::clamp( Global.fMoveLight, 0.0f, 365.0f ),
|
||||
simulation::Time.data().wHour * 60 + simulation::Time.data().wMinute,
|
||||
@@ -695,10 +671,8 @@ debug_panel::render_section_scenario() {
|
||||
}
|
||||
// dynamic material update checkbox
|
||||
ImGui::Checkbox( "Update Item Materials", &Global.UpdateMaterials );
|
||||
if( DebugModeFlag ) {
|
||||
if( ImGui::Checkbox( "Force Daylight", &Global.FakeLight ) ) {
|
||||
simulation::Environment.on_daylight_change();
|
||||
}
|
||||
if (DebugModeFlag && ImGui::Checkbox( "Force Daylight", &Global.FakeLight )) {
|
||||
simulation::Environment.on_daylight_change();
|
||||
}
|
||||
// advanced options, only visible in debug mode
|
||||
if( DebugModeFlag ) {
|
||||
@@ -713,8 +687,8 @@ debug_panel::render_section_scenario() {
|
||||
+ ":"
|
||||
+ std::string( std::to_string( int( 100 + simulation::Time.data().wMinute ) ).substr( 1, 2 ) ) ) };
|
||||
if( ImGui::SliderInt( ( timestring + " (" + Global.Period + ")###simulationtime" ).c_str(), &time, 0, 1439, "Time of day" ) ) {
|
||||
command_relay relay;
|
||||
relay.post(
|
||||
command_relay commandrelay;
|
||||
commandrelay.post(
|
||||
user_command::setdatetime,
|
||||
Global.fMoveLight,
|
||||
std::clamp( time, 0, 1439 ),
|
||||
@@ -903,7 +877,7 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
||||
mover.LoadFlag,
|
||||
mover.LocalBrakePosA,
|
||||
mover.LocalBrakePosAEIM,
|
||||
mover.ManualBrakePos / static_cast<float>(ManualBrakePosNo),
|
||||
static_cast<float>(mover.ManualBrakePos) / static_cast<float>(ManualBrakePosNo),
|
||||
mover.SpringBrake.Activate ? 1.f : 0.f,
|
||||
// cylinders
|
||||
mover.BrakePress,
|
||||
@@ -981,11 +955,11 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
||||
|
||||
if (!std::isnan(last_time)) {
|
||||
double dt = Timer::GetTime() - last_time;
|
||||
AccN_jerk_graph.update((mover.AccN - last_AccN) / dt);
|
||||
AccN_acc_graph.update(mover.AccN);
|
||||
AccN_jerk_graph.update(static_cast<float>((mover.AccN - last_AccN) / dt));
|
||||
AccN_acc_graph.update(static_cast<float>(mover.AccN));
|
||||
}
|
||||
|
||||
last_AccN = mover.AccN;
|
||||
last_AccN = static_cast<float>(mover.AccN);
|
||||
last_time = Timer::GetTime();
|
||||
}
|
||||
|
||||
@@ -1002,7 +976,7 @@ void debug_panel::graph_data::update(float val) {
|
||||
void debug_panel::graph_data::render() {
|
||||
ImGui::PushID(this);
|
||||
ImGui::SliderFloat(STR_C("##Range"), &range, 0.5f, 60.0f, "%.1f");
|
||||
ImGui::PlotLines("##plot", data.data(), data.size(), pos, nullptr, 0.0f, range, ImVec2(0, 100));
|
||||
ImGui::PlotLines("##plot", data.data(), static_cast<int>(data.size()), static_cast<int>(pos), nullptr, 0.0f, range, ImVec2(0, 100));
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
@@ -1047,9 +1021,9 @@ debug_panel::update_vehicle_brake() const {
|
||||
{ bdelay_R, "R" },
|
||||
{ bdelay_M, "+Mg" } };
|
||||
|
||||
for( auto const &delay : delays ) {
|
||||
if( ( mover.BrakeDelayFlag & delay.first ) == delay.first ) {
|
||||
brakedelay += delay.second;
|
||||
for( auto const &[delayflag, delayname] : delays ) {
|
||||
if( ( mover.BrakeDelayFlag & delayflag ) == delayflag ) {
|
||||
brakedelay += delayname;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1057,7 +1031,7 @@ debug_panel::update_vehicle_brake() const {
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_engine( std::vector<text_line> &Output ) {
|
||||
debug_panel::update_section_engine( std::vector<text_line> &Output ) const {
|
||||
|
||||
if( m_input.vehicle == nullptr ) { return; }
|
||||
if( m_input.mover == nullptr ) { return; }
|
||||
@@ -1072,9 +1046,9 @@ debug_panel::update_section_engine( std::vector<text_line> &Output ) {
|
||||
for( int i = 0; i <= 20; ++i ) {
|
||||
|
||||
std::string parameters =
|
||||
mover.eimc_labels[ i ] + to_string( mover.eimc[ i ], 2, 9 )
|
||||
TMoverParameters::eimc_labels[ i ] + to_string( mover.eimc[ i ], 2, 9 )
|
||||
+ " | "
|
||||
+ mover.eimv_labels[ i ] + to_string( mover.eimv[ i ], 2, 9 );
|
||||
+ TMoverParameters::eimv_labels[ i ] + to_string( mover.eimv[ i ], 2, 9 );
|
||||
|
||||
if( i < 10 ) {
|
||||
parameters +=
|
||||
@@ -1084,7 +1058,7 @@ debug_panel::update_section_engine( std::vector<text_line> &Output ) {
|
||||
parameters += " med:";
|
||||
}
|
||||
else if( i >= 13 ) {
|
||||
parameters += " | " + vehicle.MED_labels[ i - 13 ] + to_string( vehicle.MED[ 0 ][ i - 13 ], 2, 9 );
|
||||
parameters += " | " + TDynamicObject::MED_labels[ i - 13 ] + to_string( vehicle.MED[ 0 ][ i - 13 ], 2, 9 );
|
||||
}
|
||||
|
||||
Output.emplace_back( parameters, Global.UITextColor );
|
||||
@@ -1112,8 +1086,8 @@ debug_panel::update_section_engine( std::vector<text_line> &Output ) {
|
||||
{ "cdesi: ", mover.dizel_engagestate },
|
||||
{ "cdelt: ", mover.dizel_engagedeltaomega },
|
||||
{ "gears: ", mover.dizel_automaticgearstatus} };
|
||||
for( auto const ¶meter : paramvalues ) {
|
||||
parameterstext += "\n" + parameter.first + to_string( parameter.second, 2, 9 );
|
||||
for( auto const &[parametername, parametervalue] : paramvalues ) {
|
||||
parameterstext += "\n" + parametername + to_string( parametervalue, 2, 9 );
|
||||
}
|
||||
Output.emplace_back( parameterstext, Global.UITextColor );
|
||||
|
||||
@@ -1130,15 +1104,15 @@ debug_panel::update_section_engine( std::vector<text_line> &Output ) {
|
||||
{ "hRtTq: ", mover.hydro_R_Torque }
|
||||
|
||||
};
|
||||
for( auto const ¶meter : hydrovalues ) {
|
||||
parameterstext += "\n" + parameter.first + to_string( parameter.second, 2, 9 );
|
||||
for( auto const &[parametername, parametervalue] : hydrovalues ) {
|
||||
parameterstext += "\n" + parametername + to_string( parametervalue, 2, 9 );
|
||||
}
|
||||
Output.emplace_back( parameterstext, Global.UITextColor );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_ai( std::vector<text_line> &Output ) {
|
||||
debug_panel::update_section_ai( std::vector<text_line> &Output ) const {
|
||||
|
||||
if( m_input.mover == nullptr ) { return; }
|
||||
if( m_input.mechanik == nullptr ) { return; }
|
||||
@@ -1202,14 +1176,14 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
|
||||
{ mover.RunningTrack.Velmax, "track" } };
|
||||
|
||||
std::string restrictionstext;
|
||||
for( auto const &restriction : restrictions ) {
|
||||
if( restriction.first < 0.0 ) { continue; }
|
||||
for( auto const &[restrictionspeed, restrictionsource] : restrictions ) {
|
||||
if( restrictionspeed < 0.0 ) { continue; }
|
||||
if( false == restrictionstext.empty() ) {
|
||||
restrictionstext += ", ";
|
||||
}
|
||||
restrictionstext +=
|
||||
to_string( restriction.first, 0 )
|
||||
+ " (" + restriction.second + ")";
|
||||
to_string( restrictionspeed, 0 )
|
||||
+ " (" + restrictionsource + ")";
|
||||
}
|
||||
|
||||
if( false == restrictionstext.empty() ) {
|
||||
@@ -1262,7 +1236,7 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_scantable( std::vector<text_line> &Output ) {
|
||||
debug_panel::update_section_scantable( std::vector<text_line> &Output ) const {
|
||||
|
||||
if( m_input.mechanik == nullptr ) { return; }
|
||||
|
||||
@@ -1284,8 +1258,8 @@ debug_panel::update_section_scantable( std::vector<text_line> &Output ) {
|
||||
|
||||
#ifdef WITH_UART
|
||||
void
|
||||
debug_panel::update_section_uart( std::vector<text_line> &Output ) {
|
||||
uart_status *status = &UartStatus;
|
||||
debug_panel::update_section_uart( std::vector<text_line> &Output ) const {
|
||||
uart_status const *status = &UartStatus;
|
||||
|
||||
Output.emplace_back(
|
||||
("Port: " + status->port_name).c_str(),
|
||||
@@ -1312,7 +1286,7 @@ debug_panel::update_section_uart( std::vector<text_line> &Output ) {
|
||||
#endif
|
||||
|
||||
void
|
||||
debug_panel::update_section_scenario( std::vector<text_line> &Output ) {
|
||||
debug_panel::update_section_scenario( std::vector<text_line> &Output ) const {
|
||||
|
||||
auto textline =
|
||||
"vehicles: " + to_string( Timer::subsystem.sim_dynamics.average(), 2 ) + " msec"
|
||||
@@ -1326,7 +1300,7 @@ debug_panel::update_section_scenario( std::vector<text_line> &Output ) {
|
||||
+ to_string( simulation::Environment.wind_azimuth(), 0 ) // ma być azymut, czyli 0 na północy i rośnie na wschód
|
||||
+ " "
|
||||
+ std::string( "N NEE SES SWW NW" )
|
||||
.substr( 0 + 2 * std::floor( std::fmod( 8 + ( glm::radians( simulation::Environment.wind_azimuth() ) + 0.5 * M_PI_4 ) / M_PI_4, 8 ) ), 2 )
|
||||
.substr( static_cast<std::size_t>( 2 * std::floor( std::fmod( 8 + ( glm::radians( simulation::Environment.wind_azimuth() ) + 0.5 * M_PI_4 ) / M_PI_4, 8 ) ) ), 2 )
|
||||
+ ", " + to_string( glm::length( simulation::Environment.wind() ), 1 ) + " m/s";
|
||||
textline += "\nAir temperature: " + to_string( Global.AirTemperature, 1 ) + " deg C";
|
||||
|
||||
@@ -1340,36 +1314,36 @@ debug_panel::update_section_eventqueue( std::vector<text_line> &Output ) {
|
||||
|
||||
// current event queue
|
||||
auto const time { Timer::GetTime() };
|
||||
auto const *event { simulation::Events.begin() };
|
||||
auto const *queuedevent { simulation::Events.begin() };
|
||||
auto const searchfilter { std::string( m_eventsearch.data() ) };
|
||||
|
||||
Output.emplace_back( "Delay: Event:", Global.UITextColor );
|
||||
|
||||
while( event != nullptr
|
||||
while( queuedevent != nullptr
|
||||
&& Output.size() < 30 ) {
|
||||
|
||||
if( false == event->m_ignored
|
||||
&& false == event->m_passive
|
||||
if( false == queuedevent->m_ignored
|
||||
&& false == queuedevent->m_passive
|
||||
&& ( false == m_eventqueueactivevehicleonly
|
||||
|| event->m_activator == m_input.vehicle ) ) {
|
||||
|| queuedevent->m_activator == m_input.vehicle ) ) {
|
||||
|
||||
auto const label { event->m_name + ( event->m_activator ? " (by: " + event->m_activator->asName + ")" : "" ) };
|
||||
auto const label { queuedevent->m_name + ( queuedevent->m_activator ? " (by: " + queuedevent->m_activator->asName + ")" : "" ) };
|
||||
|
||||
if( false == searchfilter.empty()
|
||||
&& false == contains(label, searchfilter) ) {
|
||||
event = event->m_next;
|
||||
queuedevent = queuedevent->m_next;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto const delay { " " + to_string( std::max( 0.0, event->m_launchtime - time ), 1 ) };
|
||||
auto const delay { " " + to_string( std::max( 0.0, queuedevent->m_launchtime - time ), 1 ) };
|
||||
textline =
|
||||
delay.substr( delay.length() - 6 )
|
||||
+ " "
|
||||
+ label + ( event->m_sibling ? " (joint event)" : "" );
|
||||
+ label + ( queuedevent->m_sibling ? " (joint event)" : "" );
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
event = event->m_next;
|
||||
queuedevent = queuedevent->m_next;
|
||||
}
|
||||
if( Output.size() == 1 ) {
|
||||
// event queue can be empty either because no event got through active filters, or because it is genuinely empty
|
||||
@@ -1378,7 +1352,7 @@ debug_panel::update_section_eventqueue( std::vector<text_line> &Output ) {
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_powergrid( std::vector<text_line> &Output ) {
|
||||
debug_panel::update_section_powergrid( std::vector<text_line> &Output ) const {
|
||||
|
||||
auto const lowpowercolor { glm::vec4( 164.0f / 255.0f, 132.0f / 255.0f, 84.0f / 255.0f, 1.f ) };
|
||||
auto const nopowercolor { glm::vec4( 164.0f / 255.0f, 84.0f / 255.0f, 84.0f / 255.0f, 1.f ) };
|
||||
@@ -1420,7 +1394,7 @@ debug_panel::update_section_powergrid( std::vector<text_line> &Output ) {
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_camera( std::vector<text_line> &Output ) {
|
||||
debug_panel::update_section_camera( std::vector<text_line> &Output ) const {
|
||||
|
||||
if( m_input.camera == nullptr ) { return; }
|
||||
|
||||
@@ -1440,13 +1414,13 @@ debug_panel::update_section_camera( std::vector<text_line> &Output ) {
|
||||
+ to_string( 180.0 - glm::degrees( camera.Angle.y ), 0 ) // ma być azymut, czyli 0 na północy i rośnie na wschód
|
||||
+ " "
|
||||
+ std::string( "S SEE NEN NWW SW" )
|
||||
.substr( 0 + 2 * floor( fmod( 8 + ( camera.Angle.y + 0.5 * M_PI_4 ) / M_PI_4, 8 ) ), 2 );
|
||||
.substr( static_cast<std::size_t>( 2 * floor( fmod( 8 + ( camera.Angle.y + 0.5 * M_PI_4 ) / M_PI_4, 8 ) ) ), 2 );
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
}
|
||||
|
||||
void
|
||||
debug_panel::update_section_renderer( std::vector<text_line> &Output ) {
|
||||
debug_panel::update_section_renderer( std::vector<text_line> &Output ) const {
|
||||
|
||||
// gfx renderer data
|
||||
auto textline =
|
||||
@@ -1526,7 +1500,7 @@ debug_panel::render_section( std::string const &Header, std::vector<text_line> c
|
||||
}
|
||||
|
||||
bool
|
||||
debug_panel::render_section( std::vector<text_line> const &Lines ) {
|
||||
debug_panel::render_section( std::vector<text_line> const &Lines ) const {
|
||||
|
||||
for( auto const &line : Lines ) {
|
||||
ImGui::PushStyleColor( ImGuiCol_Text, { line.color.r, line.color.g, line.color.b, line.color.a } );
|
||||
@@ -1537,7 +1511,7 @@ debug_panel::render_section( std::vector<text_line> const &Lines ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool debug_panel::render_section_developer()
|
||||
bool debug_panel::render_section_developer() const
|
||||
{
|
||||
if (false == ImGui::CollapsingHeader("Developer tools"))
|
||||
return false;
|
||||
@@ -1553,7 +1527,7 @@ bool debug_panel::render_section_developer()
|
||||
}
|
||||
|
||||
bool
|
||||
debug_panel::render_section_settings() {
|
||||
debug_panel::render_section_settings() const {
|
||||
|
||||
if( false == ImGui::CollapsingHeader( "Settings" ) ) { return false; }
|
||||
|
||||
@@ -1563,9 +1537,9 @@ debug_panel::render_section_settings() {
|
||||
// reflection fidelity
|
||||
ImGui::SliderInt( ( std::to_string( Global.reflectiontune.fidelity ) + "###reflectionfidelity" ).c_str(), &Global.reflectiontune.fidelity, 0, 2, "Reflection fidelity" );
|
||||
ImGui::SliderInt( ( std::to_string( Global.gfx_shadow_rank_cutoff ) + "###shadowrankcutoff" ).c_str(), &Global.gfx_shadow_rank_cutoff, 1, 3, "Shadow ranks" );
|
||||
if( ImGui::SliderFloat( ( to_string( std::abs( Global.gfx_shadow_angle_min ), 2 ) + "###shadowanglecutoff" ).c_str(), &Global.gfx_shadow_angle_min, -1.0, -0.2, "Shadow angle cutoff" ) ) {
|
||||
if( ImGui::SliderFloat( ( to_string( std::abs( Global.gfx_shadow_angle_min ), 2 ) + "###shadowanglecutoff" ).c_str(), &Global.gfx_shadow_angle_min, -1.0, -0.2f, "Shadow angle cutoff" ) ) {
|
||||
Global.gfx_shadow_angle_min = quantize( Global.gfx_shadow_angle_min, 0.05f );
|
||||
};
|
||||
}
|
||||
if( DebugModeFlag ) {
|
||||
// sky sliders
|
||||
{
|
||||
@@ -1595,8 +1569,8 @@ debug_panel::render_section_settings() {
|
||||
if (simulation::Train) {
|
||||
float val = simulation::Train->get_radiovolume();
|
||||
if( ImGui::SliderFloat( ( std::to_string( static_cast<int>( val * 100 ) ) + "%###volumeradio" ).c_str(), &val, 0.0f, 1.0f, "Vehicle radio volume" ) ) {
|
||||
command_relay relay;
|
||||
relay.post(user_command::radiovolumeset, val, 0.0, GLFW_PRESS, 0);
|
||||
command_relay commandrelay;
|
||||
commandrelay.post(user_command::radiovolumeset, val, 0.0, GLFW_PRESS, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1635,12 +1609,7 @@ transcripts_panel::render() {
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2S( size_min.x, size_min.y ), ImVec2S( size_max.x, size_max.y ) );
|
||||
}
|
||||
auto const panelname { (
|
||||
title.empty() ?
|
||||
m_name :
|
||||
title )
|
||||
+ "###" + m_name };
|
||||
if( true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
|
||||
if( auto const panelname { ( title.empty() ? m_name : title ) + "###" + m_name }; true == ImGui::Begin( panelname.c_str(), &is_open, flags ) ) {
|
||||
// header section
|
||||
for( auto const &line : text_lines ) {
|
||||
ImGui::TextWrapped( "%s", line.data.c_str() );
|
||||
|
||||
@@ -54,7 +54,6 @@ public:
|
||||
|
||||
private:
|
||||
// members
|
||||
std::array<char, 256> m_buffer;
|
||||
TDynamicObject const *m_nearest { nullptr };
|
||||
};
|
||||
|
||||
@@ -81,42 +80,41 @@ private:
|
||||
// methods
|
||||
// generate and send section data to provided output
|
||||
void update_section_vehicle( std::vector<text_line> &Output );
|
||||
void update_section_engine( std::vector<text_line> &Output );
|
||||
void update_section_ai( std::vector<text_line> &Output );
|
||||
void update_section_scantable( std::vector<text_line> &Output );
|
||||
void update_section_scenario( std::vector<text_line> &Output );
|
||||
void update_section_engine( std::vector<text_line> &Output ) const;
|
||||
void update_section_ai( std::vector<text_line> &Output ) const;
|
||||
void update_section_scantable( std::vector<text_line> &Output ) const;
|
||||
void update_section_scenario( std::vector<text_line> &Output ) const;
|
||||
void update_section_eventqueue( std::vector<text_line> &Output );
|
||||
void update_section_powergrid( std::vector<text_line> &Output );
|
||||
void update_section_camera( std::vector<text_line> &Output );
|
||||
void update_section_renderer( std::vector<text_line> &Output );
|
||||
void update_section_powergrid( std::vector<text_line> &Output ) const;
|
||||
void update_section_camera( std::vector<text_line> &Output ) const;
|
||||
void update_section_renderer( std::vector<text_line> &Output ) const;
|
||||
#ifdef WITH_UART
|
||||
void update_section_uart( std::vector<text_line> &Output );
|
||||
void update_section_uart( std::vector<text_line> &Output ) const;
|
||||
#endif
|
||||
// section update helpers
|
||||
std::string update_vehicle_coupler( int const Side );
|
||||
std::string update_vehicle_brake() const;
|
||||
// renders provided lines, under specified collapsing header
|
||||
bool render_section( std::string const &Header, std::vector<text_line> const &Lines );
|
||||
bool render_section( std::vector<text_line> const &Lines );
|
||||
bool render_section( std::vector<text_line> const &Lines ) const;
|
||||
bool render_section_scenario();
|
||||
bool render_section_eventqueue();
|
||||
bool render_section_settings();
|
||||
bool render_section_developer();
|
||||
bool render_section_settings() const;
|
||||
bool render_section_developer() const;
|
||||
// members
|
||||
std::array<char, 1024> m_buffer;
|
||||
std::array<char, 128> m_eventsearch;
|
||||
input_data m_input;
|
||||
std::vector<text_line>
|
||||
m_vehiclelines,
|
||||
m_enginelines,
|
||||
m_ailines,
|
||||
m_scantablelines,
|
||||
m_cameralines,
|
||||
m_scenariolines,
|
||||
m_eventqueuelines,
|
||||
m_powergridlines,
|
||||
m_rendererlines,
|
||||
m_uartlines;
|
||||
std::vector<text_line> m_vehiclelines;
|
||||
std::vector<text_line> m_enginelines;
|
||||
std::vector<text_line> m_ailines;
|
||||
std::vector<text_line> m_scantablelines;
|
||||
std::vector<text_line> m_cameralines;
|
||||
std::vector<text_line> m_scenariolines;
|
||||
std::vector<text_line> m_eventqueuelines;
|
||||
std::vector<text_line> m_powergridlines;
|
||||
std::vector<text_line> m_rendererlines;
|
||||
std::vector<text_line> m_uartlines;
|
||||
|
||||
double last_time = std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
@@ -134,8 +132,6 @@ private:
|
||||
graph_data AccN_acc_graph;
|
||||
float last_AccN;
|
||||
|
||||
std::array<char, 128> queue_event_buf = { 0 };
|
||||
std::array<char, 128> queue_event_activator_buf = { 0 };
|
||||
|
||||
bool m_eventqueueactivevehicleonly { false };
|
||||
};
|
||||
|
||||
@@ -11,13 +11,13 @@ TTranscripts Transcripts;
|
||||
|
||||
// dodanie linii do tabeli, (show) i (hide) w [s] od aktualnego czasu
|
||||
void
|
||||
TTranscripts::AddLine( std::string const &txt, float show, float hide, bool it ) {
|
||||
TTranscripts::AddLine( std::string_view txt, float show, float hide, bool it ) {
|
||||
|
||||
if( show == hide ) { return; } // komentarz jest ignorowany
|
||||
|
||||
// TODO: replace the timeangledeg mess with regular time points math
|
||||
show = Global.fTimeAngleDeg + show / 240.0; // jeśli doba to 360, to 1s będzie równe 1/240
|
||||
hide = Global.fTimeAngleDeg + hide / 240.0;
|
||||
show = static_cast<float>(Global.fTimeAngleDeg + show / 240.0); // jeśli doba to 360, to 1s będzie równe 1/240
|
||||
hide = static_cast<float>(Global.fTimeAngleDeg + hide / 240.0);
|
||||
|
||||
TTranscript transcript;
|
||||
transcript.asText = txt;
|
||||
@@ -34,7 +34,7 @@ TTranscripts::AddLine( std::string const &txt, float show, float hide, bool it )
|
||||
|
||||
// dodanie tekstów, długość dźwięku, czy istotne
|
||||
void
|
||||
TTranscripts::Add( std::string const &txt, bool backgorund ) {
|
||||
TTranscripts::Add( std::string const &txt, bool /*backgorund*/ ) {
|
||||
|
||||
if( true == txt.empty() ) { return; }
|
||||
|
||||
@@ -42,20 +42,21 @@ TTranscripts::Add( std::string const &txt, bool backgorund ) {
|
||||
cParser parser( asciitext );
|
||||
while( true == parser.getTokens( 3, false, "[]\n" ) ) {
|
||||
|
||||
float begin{ 0.f }, end{ 0.f };
|
||||
float begin{ 0.f };
|
||||
float end{ 0.f };
|
||||
std::string transcript;
|
||||
parser
|
||||
>> begin
|
||||
>> end
|
||||
>> transcript;
|
||||
AddLine( transcript, 0.10 * begin, 0.12 * end, false );
|
||||
AddLine( transcript, static_cast<float>(0.10 * begin), static_cast<float>(0.12 * end), false );
|
||||
}
|
||||
// try to handle malformed(?) cases with no show/hide times
|
||||
std::string transcript; parser >> transcript;
|
||||
while( false == transcript.empty() ) {
|
||||
|
||||
// WriteLog( "Transcript text with no display/hide times: \"" + transcript + "\"" );
|
||||
AddLine( transcript, 0.0, 0.12 * transcript.size(), false );
|
||||
AddLine( transcript, 0.0, static_cast<float>(0.12 * static_cast<double>(transcript.size())), false );
|
||||
transcript = ""; parser >> transcript;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
// constructors
|
||||
TTranscripts() = default;
|
||||
// methods
|
||||
void AddLine( std::string const &txt, float show, float hide, bool it );
|
||||
void AddLine( std::string_view txt, float show, float hide, bool it );
|
||||
// dodanie tekstów, długość dźwięku, czy istotne
|
||||
void Add( std::string const &txt, bool background = false );
|
||||
// usuwanie niepotrzebnych (ok. 10 razy na sekundę)
|
||||
|
||||
116
audio/sound.cpp
116
audio/sound.cpp
@@ -47,19 +47,18 @@ sound_source::deserialize( cParser &Input, sound_type const Legacytype, int cons
|
||||
if( Input.peek() == "{" ) {
|
||||
// block type config
|
||||
while( true == deserialize_mapping( Input ) ) {
|
||||
; // all work done by while()
|
||||
// all work done by while()
|
||||
}
|
||||
|
||||
if( false == m_soundchunks.empty() ) {
|
||||
// arrange loaded sound chunks in requested order
|
||||
std::sort(
|
||||
std::begin( m_soundchunks ), std::end( m_soundchunks ),
|
||||
[]( soundchunk_pair const &Left, soundchunk_pair const &Right ) {
|
||||
std::ranges::sort(
|
||||
m_soundchunks, []( soundchunk_pair const &Left, soundchunk_pair const &Right ) {
|
||||
return Left.second.threshold < Right.second.threshold; } );
|
||||
// calculate and cache full range points for each chunk, including crossfade sections:
|
||||
// on the far end the crossfade section extends to the threshold point of the next chunk...
|
||||
for( std::size_t idx = 0; idx < m_soundchunks.size() - 1; ++idx ) {
|
||||
m_soundchunks[ idx ].second.fadeout = m_soundchunks[ idx + 1 ].second.threshold;
|
||||
m_soundchunks[ idx ].second.fadeout = static_cast<float>(m_soundchunks[ idx + 1 ].second.threshold);
|
||||
/*
|
||||
m_soundchunks[ idx ].second.fadeout =
|
||||
interpolate<float>(
|
||||
@@ -69,11 +68,11 @@ sound_source::deserialize( cParser &Input, sound_type const Legacytype, int cons
|
||||
*/
|
||||
}
|
||||
// ...and on the other end from the threshold point back into the range of previous chunk
|
||||
m_soundchunks.front().second.fadein = std::max( 0, m_soundchunks.front().second.threshold );
|
||||
m_soundchunks.front().second.fadein = static_cast<float>(std::max( 0, m_soundchunks.front().second.threshold ));
|
||||
// m_soundchunks.front().second.fadein = m_soundchunks.front().second.threshold;
|
||||
for( std::size_t idx = 1; idx < m_soundchunks.size(); ++idx ) {
|
||||
auto const previouschunkwidth { m_soundchunks[ idx ].second.threshold - m_soundchunks[ idx - 1 ].second.threshold };
|
||||
m_soundchunks[ idx ].second.fadein = m_soundchunks[ idx ].second.threshold - 0.01f * m_crossfaderange * previouschunkwidth;
|
||||
m_soundchunks[ idx ].second.fadein = static_cast<float>(m_soundchunks[ idx ].second.threshold) - 0.01f * static_cast<float>(m_crossfaderange) * static_cast<float>(previouschunkwidth);
|
||||
/*
|
||||
m_soundchunks[ idx ].second.fadein =
|
||||
interpolate<float>(
|
||||
@@ -82,11 +81,11 @@ sound_source::deserialize( cParser &Input, sound_type const Legacytype, int cons
|
||||
m_crossfaderange * 0.01f );
|
||||
*/
|
||||
}
|
||||
m_soundchunks.back().second.fadeout = std::max( Chunkrange, m_soundchunks.back().second.threshold );
|
||||
m_soundchunks.back().second.fadeout = static_cast<float>(std::max( Chunkrange, m_soundchunks.back().second.threshold ));
|
||||
// m_soundchunks.back().second.fadeout = m_soundchunks.back().second.threshold;
|
||||
// test if the chunk table contains any actual samples while at it
|
||||
for( auto &soundchunk : m_soundchunks ) {
|
||||
if( soundchunk.first.buffer != null_handle ) {
|
||||
for( auto &[chunkbuffer, chunkdata] : m_soundchunks ) {
|
||||
if( chunkbuffer.buffer != null_handle ) {
|
||||
m_soundchunksempty = false;
|
||||
break;
|
||||
}
|
||||
@@ -117,24 +116,18 @@ sound_source::deserialize( cParser &Input, sound_type const Legacytype, int cons
|
||||
}
|
||||
}
|
||||
|
||||
if( Legacyparameters & sound_parameters::range ) {
|
||||
if( Input.getTokens( 1, false ) ) {
|
||||
Input >> m_range;
|
||||
}
|
||||
if (Legacyparameters & sound_parameters::range && Input.getTokens( 1, false )) {
|
||||
Input >> m_range;
|
||||
}
|
||||
if( Legacyparameters & sound_parameters::amplitude ) {
|
||||
if( Input.getTokens( 2, false ) ) {
|
||||
Input
|
||||
>> m_amplitudefactor
|
||||
>> m_amplitudeoffset;
|
||||
}
|
||||
if (Legacyparameters & sound_parameters::amplitude && Input.getTokens( 2, false )) {
|
||||
Input
|
||||
>> m_amplitudefactor
|
||||
>> m_amplitudeoffset;
|
||||
}
|
||||
if( Legacyparameters & sound_parameters::frequency ) {
|
||||
if( Input.getTokens( 2, false ) ) {
|
||||
Input
|
||||
>> m_frequencyfactor
|
||||
>> m_frequencyoffset;
|
||||
}
|
||||
if (Legacyparameters & sound_parameters::frequency && Input.getTokens( 2, false )) {
|
||||
Input
|
||||
>> m_frequencyfactor
|
||||
>> m_frequencyoffset;
|
||||
}
|
||||
}
|
||||
// restore parser behaviour
|
||||
@@ -225,9 +218,9 @@ sound_source::deserialize_mapping( cParser &Input ) {
|
||||
if( indexstart != std::string::npos ) {
|
||||
auto const index { std::stoi( key.substr( indexstart, indexend - indexstart ) ) };
|
||||
auto const pitch { Input.getToken<float>( false, "\n\r\t ,;" ) };
|
||||
for( auto &chunk : m_soundchunks ) {
|
||||
if( chunk.second.threshold == index ) {
|
||||
chunk.second.pitch = pitch > 0.f ? pitch : 1.f;
|
||||
for( auto &[chunkbuffer, chunkdata] : m_soundchunks ) {
|
||||
if( chunkdata.threshold == index ) {
|
||||
chunkdata.pitch = pitch > 0.f ? pitch : 1.f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -240,13 +233,14 @@ sound_source::deserialize_mapping( cParser &Input ) {
|
||||
m_crossfaderange = std::clamp( m_crossfaderange, 0, 100 );
|
||||
}
|
||||
else if( key == "placement:" ) {
|
||||
using enum sound_placement;
|
||||
auto const value { Input.getToken<std::string>( true, "\n\r\t ,;" ) };
|
||||
std::map<std::string, sound_placement> const placements {
|
||||
{ "internal", sound_placement::internal },
|
||||
{ "engine", sound_placement::engine },
|
||||
{ "external", sound_placement::external },
|
||||
{ "custom", sound_placement::custom },
|
||||
{ "general", sound_placement::general } };
|
||||
std::map<std::string, sound_placement, std::less<>> const placements {
|
||||
{ "internal", internal },
|
||||
{ "engine", engine },
|
||||
{ "external", external },
|
||||
{ "custom", custom },
|
||||
{ "general", general } };
|
||||
auto lookup{ placements.find( value ) };
|
||||
if( lookup != placements.end() ) {
|
||||
m_placement = lookup->second;
|
||||
@@ -262,7 +256,7 @@ sound_source::deserialize_mapping( cParser &Input ) {
|
||||
}
|
||||
else {
|
||||
// floating point properties
|
||||
std::map<std::string, float &> const properties {
|
||||
std::map<std::string, float &, std::less<>> const properties {
|
||||
{ "frequencyfactor:", m_frequencyfactor },
|
||||
{ "frequencyoffset:", m_frequencyoffset },
|
||||
{ "amplitudefactor:", m_amplitudefactor },
|
||||
@@ -339,8 +333,8 @@ sound_source::copy_sounds( sound_source const &Source ) {
|
||||
for( auto &sound : m_sounds ) {
|
||||
sound.playing = 0;
|
||||
}
|
||||
for( auto &sound : m_soundchunks ) {
|
||||
sound.first.playing = 0;
|
||||
for( auto &[chunkbuffer, chunkdata] : m_soundchunks ) {
|
||||
chunkbuffer.playing = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@@ -400,7 +394,7 @@ sound_source::play_basic() {
|
||||
// dispatch appropriate sound
|
||||
if( true == m_playbeginning
|
||||
&& sound(sound_id::begin).buffer != null_handle) {
|
||||
std::vector<sound_id> sounds { sound_id::begin, sound_id::main };
|
||||
std::vector sounds { sound_id::begin, sound_id::main };
|
||||
insert( std::begin( sounds ), std::end( sounds ) );
|
||||
m_playbeginning = false;
|
||||
}
|
||||
@@ -424,14 +418,14 @@ sound_source::play_combined() {
|
||||
auto const soundpoint { compute_combined_point() };
|
||||
for( std::uint32_t idx = 0; idx < m_soundchunks.size(); ++idx ) {
|
||||
|
||||
auto const &soundchunk { m_soundchunks[ idx ] };
|
||||
auto const &[chunkbuffer, chunkdata]{ m_soundchunks[ idx ] };
|
||||
// a chunk covers range from fade in point, where it starts rising in volume over crossfade distance,
|
||||
// lasts until fadeout - crossfade distance point, past which it grows quiet until fade out point where it ends
|
||||
if( soundpoint < soundchunk.second.fadein ) { break; }
|
||||
if( soundpoint >= soundchunk.second.fadeout ) { continue; }
|
||||
if( soundpoint < chunkdata.fadein ) { break; }
|
||||
if( soundpoint >= chunkdata.fadeout ) { continue; }
|
||||
|
||||
if( soundchunk.first.buffer == null_handle || ( (m_flags & (sound_flags::exclusive | sound_flags::looping)) != 0
|
||||
&& soundchunk.first.playing > 0 ) ) {
|
||||
if( chunkbuffer.buffer == null_handle || ( (m_flags & (sound_flags::exclusive | sound_flags::looping)) != 0
|
||||
&& chunkbuffer.playing > 0 ) ) {
|
||||
// combined sounds only play looped, single copy of each activated chunk
|
||||
continue;
|
||||
}
|
||||
@@ -675,9 +669,9 @@ sound_source::update_combined( audio::openal_source &Source ) {
|
||||
// for sound chunks, test whether the chunk should still be active given current value of the controlling variable
|
||||
if( ( m_flags & ( sound_flags::exclusive | sound_flags::looping ) ) != 0 ) {
|
||||
auto const soundpoint { compute_combined_point() };
|
||||
auto const &soundchunk { m_soundchunks[ soundhandle ^ sound_id::chunk ] };
|
||||
if( soundpoint < soundchunk.second.fadein
|
||||
|| soundpoint >= soundchunk.second.fadeout ) {
|
||||
auto const &[chunkbuffer, chunkdata]{ m_soundchunks[ soundhandle ^ sound_id::chunk ] };
|
||||
if( soundpoint < chunkdata.fadein
|
||||
|| soundpoint >= chunkdata.fadeout ) {
|
||||
Source.stop();
|
||||
update_counter( soundhandle, -1 );
|
||||
return;
|
||||
@@ -761,7 +755,7 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
|
||||
|
||||
// relative pitch adjustment
|
||||
// pitch of each chunk is modified based on ratio of the chunk's pitch to that of its neighbour
|
||||
if( soundpoint < chunkdata.threshold ) {
|
||||
if( soundpoint < static_cast<float>(chunkdata.threshold) ) {
|
||||
|
||||
if( chunkindex > 0 ) {
|
||||
// interpolate between the pitch of previous chunk and this chunk's base pitch,
|
||||
@@ -772,7 +766,7 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
|
||||
previouschunkdata.pitch / chunkdata.pitch,
|
||||
1.f,
|
||||
std::clamp(
|
||||
( soundpoint - previouschunkdata.threshold ) / ( chunkdata.threshold - previouschunkdata.threshold ),
|
||||
( soundpoint - static_cast<float>(previouschunkdata.threshold) ) / ( static_cast<float>(chunkdata.threshold - previouschunkdata.threshold) ),
|
||||
0.f, 1.f ) );
|
||||
}
|
||||
}
|
||||
@@ -787,7 +781,7 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
|
||||
1.f,
|
||||
nextchunkdata.pitch / chunkdata.pitch,
|
||||
std::clamp(
|
||||
( soundpoint - chunkdata.threshold ) / ( nextchunkdata.threshold - chunkdata.threshold ),
|
||||
( soundpoint - static_cast<float>(chunkdata.threshold) ) / ( static_cast<float>(nextchunkdata.threshold - chunkdata.threshold) ),
|
||||
0.f, 1.f ) );
|
||||
}
|
||||
else {
|
||||
@@ -801,7 +795,7 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
|
||||
if( chunkindex > 0 ) {
|
||||
// chunks other than the first can have fadein
|
||||
auto const fadeinwidth { chunkdata.threshold - chunkdata.fadein };
|
||||
if( soundpoint < chunkdata.threshold ) {
|
||||
if( soundpoint < static_cast<float>(chunkdata.threshold) ) {
|
||||
float lineargain =
|
||||
std::lerp(
|
||||
0.f, 1.f,
|
||||
@@ -809,8 +803,8 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
|
||||
( soundpoint - chunkdata.fadein ) / fadeinwidth,
|
||||
0.f, 1.f ) );
|
||||
m_properties.gain *=
|
||||
lineargain /
|
||||
(1 + (1 - lineargain) * -0.57); // approximation of logarytmic fade in
|
||||
static_cast<float>(lineargain /
|
||||
(1 + (1 - lineargain) * -0.57)); // approximation of logarytmic fade in
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -828,8 +822,8 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
|
||||
std::clamp(
|
||||
( soundpoint - fadeoutstart ) / fadeoutwidth,
|
||||
0.f, 1.f ) );
|
||||
m_properties.gain *= (-lineargain + 1) /
|
||||
(1 + lineargain * -0.57); // approximation of logarytmic fade out
|
||||
m_properties.gain *= static_cast<float>((-lineargain + 1) /
|
||||
(1 + lineargain * -0.57)); // approximation of logarytmic fade out
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -867,14 +861,14 @@ sound_source::empty() const {
|
||||
|
||||
// returns true if the source is emitting any sound
|
||||
bool
|
||||
sound_source::is_playing( bool const Includesoundends ) const {
|
||||
sound_source::is_playing( bool const /*Includesoundends*/ ) const {
|
||||
|
||||
auto isplaying { sound(sound_id::begin).playing > 0 || sound(sound_id::main).playing > 0 };
|
||||
if( false == isplaying
|
||||
&& false == m_soundchunks.empty() ) {
|
||||
// for emitters with sample tables check also if any of the chunks is active
|
||||
for( auto const &soundchunk : m_soundchunks ) {
|
||||
if( soundchunk.first.playing > 0 ) {
|
||||
for( auto const &[chunkbuffer, chunkdata] : m_soundchunks ) {
|
||||
if( chunkbuffer.playing > 0 ) {
|
||||
isplaying = true;
|
||||
break; // one will do
|
||||
}
|
||||
@@ -905,7 +899,7 @@ sound_source::has_bookends() const {
|
||||
}
|
||||
|
||||
// returns location of the sound source in simulation region space
|
||||
glm::dvec3 const
|
||||
glm::dvec3
|
||||
sound_source::location() const {
|
||||
|
||||
if( m_owner == nullptr ) {
|
||||
@@ -927,7 +921,7 @@ sound_source::range( float const Range ) {
|
||||
}
|
||||
|
||||
// returns defined range of the sound
|
||||
float const
|
||||
float
|
||||
sound_source::range() const {
|
||||
|
||||
return m_range;
|
||||
@@ -1016,7 +1010,7 @@ sound_source::update_soundproofing() {
|
||||
void
|
||||
sound_source::insert( sound_handle const Sound ) {
|
||||
|
||||
std::vector<sound_handle> sounds { Sound };
|
||||
std::vector sounds { Sound };
|
||||
return insert( std::begin( sounds ), std::end( sounds ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
offset() const;
|
||||
// sound source name setter/getter
|
||||
void
|
||||
name( std::string Name );
|
||||
name( std::string const &Name );
|
||||
std::string const &
|
||||
name() const;
|
||||
// playback starting point shift setter/getter
|
||||
@@ -137,12 +137,12 @@ public:
|
||||
bool
|
||||
has_bookends() const;
|
||||
// returns location of the sound source in simulation region space
|
||||
glm::dvec3 const
|
||||
glm::dvec3
|
||||
location() const;
|
||||
// returns defined range of the sound
|
||||
void
|
||||
range( float const Range );
|
||||
float const
|
||||
float
|
||||
range() const;
|
||||
|
||||
// members
|
||||
@@ -252,7 +252,7 @@ inline TDynamicObject const * sound_source::owner() const { return m_owner; }
|
||||
inline void sound_source::offset( glm::vec3 const Offset ) { m_offset = Offset; }
|
||||
inline glm::vec3 const & sound_source::offset() const { return m_offset; }
|
||||
// sound source name setter/getter
|
||||
inline void sound_source::name( std::string Name ) { m_name = Name; }
|
||||
inline void sound_source::name( std::string const &Name ) { m_name = Name; }
|
||||
inline std::string const & sound_source::name() const { return m_name; }
|
||||
// playback starting point shift setter/getter
|
||||
inline void sound_source::start( float const Offset ) { m_startoffset = Offset; }
|
||||
|
||||
@@ -15,9 +15,7 @@ cMoon::cMoon() {
|
||||
m_observer.temp = 15.0; // ambient dry-bulb temperature, degrees C
|
||||
}
|
||||
|
||||
cMoon::~cMoon() {
|
||||
|
||||
}
|
||||
cMoon::~cMoon() = default;
|
||||
|
||||
void
|
||||
cMoon::init() {
|
||||
@@ -74,8 +72,8 @@ float cMoon::getIntensity() {
|
||||
void cMoon::setLocation( float const Longitude, float const Latitude ) {
|
||||
|
||||
// convert fraction from geographical base of 6o minutes
|
||||
m_observer.longitude = (int)Longitude + (Longitude - (int)Longitude) * 100.0 / 60.0;
|
||||
m_observer.latitude = (int)Latitude + (Latitude - (int)Latitude) * 100.0 / 60.0 ;
|
||||
m_observer.longitude = (int)Longitude + (Longitude - static_cast<float>((int)Longitude)) * 100.0 / 60.0;
|
||||
m_observer.latitude = (int)Latitude + (Latitude - static_cast<float>((int)Latitude)) * 100.0 / 60.0 ;
|
||||
}
|
||||
|
||||
// sets current time, overriding one acquired from the system clock
|
||||
@@ -103,9 +101,9 @@ void cMoon::move() {
|
||||
|
||||
SYSTEMTIME localtime = simulation::Time.data(); // time for the calculation
|
||||
|
||||
if( m_observer.hour >= 0 ) { localtime.wHour = m_observer.hour; }
|
||||
if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; }
|
||||
if( m_observer.second >= 0 ) { localtime.wSecond = m_observer.second; }
|
||||
if( m_observer.hour >= 0 ) { localtime.wHour = static_cast<uint16_t>(m_observer.hour); }
|
||||
if( m_observer.minute >= 0 ) { localtime.wMinute = static_cast<uint16_t>(m_observer.minute); }
|
||||
if( m_observer.second >= 0 ) { localtime.wSecond = static_cast<uint16_t>(m_observer.second); }
|
||||
|
||||
double localut =
|
||||
localtime.wHour
|
||||
@@ -158,7 +156,6 @@ void cMoon::move() {
|
||||
double const yeclip = m_body.distance * ( std::sin( degtorad * longascnode ) * std::cos( vpluswinrad ) + std::cos( degtorad * longascnode ) * std::sin( vpluswinrad ) * std::cos( degtorad * inclination ) );
|
||||
double const zeclip = m_body.distance * std::sin( vpluswinrad ) * std::sin( degtorad * inclination );
|
||||
// ecliptic coordinates
|
||||
double ecliplat = radtodeg * std::atan2( zeclip, std::sqrt( xeclip*xeclip + yeclip*yeclip ) );
|
||||
m_body.eclong = clamp_circular( radtodeg * std::atan2( yeclip, xeclip ) );
|
||||
// distance
|
||||
m_body.distance = std::sqrt( xeclip*xeclip + yeclip*yeclip + zeclip*zeclip );
|
||||
@@ -174,17 +171,13 @@ void cMoon::move() {
|
||||
m_body.mnlong = clamp_circular( longascnode + perigeearg + m_body.mnanom );
|
||||
// Moon's mean elongation: D = Lm - Ls
|
||||
double const mnelong = clamp_circular( m_body.mnlong - sunmnlong );
|
||||
// Moon's argument of latitude: F = Lm - N
|
||||
double const arglat = clamp_circular( m_body.mnlong - longascnode );
|
||||
// longitude perturbations
|
||||
double const pertevection = -1.274 * std::sin( degtorad * ( m_body.mnanom - 2.0 * mnelong ) ); // Evection
|
||||
double const pertvariation = +0.658 * std::sin( degtorad * ( 2.0 * mnelong ) ); // Variation
|
||||
double const pertyearlyeqt = -0.186 * std::sin( degtorad * sunmnanom ); // Yearly equation
|
||||
// latitude perturbations
|
||||
double const pertlat = -0.173 * std::sin( degtorad * ( arglat - 2.0 * mnelong ) );
|
||||
|
||||
m_body.eclong += pertevection + pertvariation + pertyearlyeqt;
|
||||
ecliplat += pertlat;
|
||||
// declination
|
||||
m_body.declin = radtodeg * std::asin( std::sin (m_body.oblecl * degtorad) * std::sin(m_body.eclong * degtorad) );
|
||||
|
||||
@@ -267,7 +260,6 @@ void cMoon::refract() {
|
||||
|
||||
void cMoon::irradiance() {
|
||||
|
||||
static double radtodeg = 57.295779513; // converts from radians to degrees
|
||||
static double degtorad = 0.0174532925; // converts from degrees to radians
|
||||
|
||||
m_body.dayang = ( simulation::Time.year_day() - 1 ) * 360.0 / 365.0;
|
||||
@@ -299,7 +291,7 @@ cMoon::phase() {
|
||||
m_phase = 50;
|
||||
else {
|
||||
// calculate moon's age in days from new moon
|
||||
float ip = normalize( ( simulation::Time.julian_day() - 2451550.1f ) / 29.530588853f );
|
||||
float ip = normalize( ( static_cast<float>(simulation::Time.julian_day()) - 2451550.1f ) / 29.530588853f );
|
||||
m_phase = ip * 29.53f;
|
||||
}
|
||||
}
|
||||
@@ -308,7 +300,7 @@ cMoon::phase() {
|
||||
float
|
||||
cMoon::normalize( const float Value ) const {
|
||||
|
||||
float value = Value - floor( Value );
|
||||
auto value = static_cast<float>(Value - floor( Value ));
|
||||
if( value < 0.f ) { ++value; }
|
||||
|
||||
return value;
|
||||
|
||||
@@ -53,8 +53,7 @@ CSkyDome::CSkyDome (int const Tesselation) :
|
||||
Generate();
|
||||
}
|
||||
|
||||
CSkyDome::~CSkyDome() {
|
||||
}
|
||||
CSkyDome::~CSkyDome() = default;
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
@@ -71,13 +70,13 @@ void CSkyDome::Generate() {
|
||||
|
||||
for( int i = 0; i <= latitudes; ++i ) {
|
||||
|
||||
float const latitude = M_PI * ( -0.5f + (float)i / latitudes / 2 ); // half-sphere only
|
||||
auto const latitude = static_cast<float>(M_PI * ( -0.5f + (float)i / static_cast<float>(latitudes) / 2 )); // half-sphere only
|
||||
float const z = std::sin( latitude );
|
||||
float const zr = std::cos( latitude );
|
||||
|
||||
for( int j = 0; j <= longitudes; ++j ) {
|
||||
|
||||
float const longitude = 2.0 * M_PI * (float)j / longitudes;
|
||||
auto const longitude = static_cast<float>(2.0 * M_PI * (float)j / longitudes);
|
||||
float const x = std::cos( longitude );
|
||||
float const y = std::sin( longitude );
|
||||
/*
|
||||
@@ -147,7 +146,7 @@ void CSkyDome::SetOvercastFactor( float const Overcast ) {
|
||||
m_overcast = std::clamp( Overcast, 0.0f, 1.0f ) * 0.75f; // going above 0.65 makes the model go pretty bad, appearance-wise
|
||||
}
|
||||
|
||||
void CSkyDome::GetPerez( float *Perez, float Distribution[ 5 ][ 2 ], const float Turbidity ) {
|
||||
void CSkyDome::GetPerez( float *Perez, float Distribution[ 5 ][ 2 ], const float Turbidity ) const {
|
||||
|
||||
Perez[ 0 ] = Distribution[ 0 ][ 0 ] * Turbidity + Distribution[ 0 ][ 1 ];
|
||||
Perez[ 1 ] = Distribution[ 1 ][ 0 ] * Turbidity + Distribution[ 1 ][ 1 ];
|
||||
@@ -156,7 +155,7 @@ void CSkyDome::GetPerez( float *Perez, float Distribution[ 5 ][ 2 ], const float
|
||||
Perez[ 4 ] = Distribution[ 4 ][ 0 ] * Turbidity + Distribution[ 4 ][ 1 ];
|
||||
}
|
||||
|
||||
float CSkyDome::GetZenith( float Zenithmatrix[ 3 ][ 4 ], const float Theta, const float Turbidity ) {
|
||||
float CSkyDome::GetZenith( float Zenithmatrix[ 3 ][ 4 ], const float Theta, const float Turbidity ) const {
|
||||
|
||||
const float theta2 = Theta*Theta;
|
||||
const float theta3 = Theta*theta2;
|
||||
@@ -167,15 +166,15 @@ float CSkyDome::GetZenith( float Zenithmatrix[ 3 ][ 4 ], const float Theta, cons
|
||||
|
||||
}
|
||||
|
||||
float CSkyDome::PerezFunctionO1( float Perezcoeffs[ 5 ], const float Thetasun, const float Zenithval ) {
|
||||
float CSkyDome::PerezFunctionO1( float const Perezcoeffs[ 5 ], const float Thetasun, const float Zenithval ) const {
|
||||
|
||||
const float val = ( 1.0f + Perezcoeffs[ 0 ] * std::exp( Perezcoeffs[ 1 ] ) ) *
|
||||
( 1.0f + Perezcoeffs[ 2 ] * std::exp( Perezcoeffs[ 3 ] * Thetasun ) + Perezcoeffs[ 4 ] * std::pow( std::cos( Thetasun ), 2 ) );
|
||||
const auto val = static_cast<float>(( 1.0f + Perezcoeffs[ 0 ] * std::exp( Perezcoeffs[ 1 ] ) ) *
|
||||
( 1.0f + Perezcoeffs[ 2 ] * std::exp( Perezcoeffs[ 3 ] * Thetasun ) + Perezcoeffs[ 4 ] * std::pow( std::cos( Thetasun ), 2 ) ));
|
||||
|
||||
return Zenithval / val;
|
||||
}
|
||||
|
||||
float CSkyDome::PerezFunctionO2( float Perezcoeffs[ 5 ], const float Icostheta, const float Gamma, const float Cosgamma2, const float Zenithval ) {
|
||||
float CSkyDome::PerezFunctionO2( float const Perezcoeffs[ 5 ], const float Icostheta, const float Gamma, const float Cosgamma2, const float Zenithval ) const {
|
||||
// iCosTheta = 1.0f / cosf(theta)
|
||||
// cosGamma2 = SQR( cosf( gamma ) )
|
||||
return Zenithval * ( 1.0f + Perezcoeffs[ 0 ] * std::exp( Perezcoeffs[ 1 ] * Icostheta ) ) *
|
||||
@@ -188,7 +187,7 @@ void CSkyDome::RebuildColors() {
|
||||
auto gammacorrection = glm::mix( glm::vec3( 1.0f ), glm::vec3( 0.45f ), twilightfactor );
|
||||
|
||||
// get zenith luminance
|
||||
float const chi = ( 4.0f / 9.0f - m_turbidity / 120.0f ) * ( M_PI - 2.0f * m_thetasun );
|
||||
auto const chi = static_cast<float>(( 4.0f / 9.0f - m_turbidity / 120.0f ) * ( M_PI - 2.0f * m_thetasun ));
|
||||
float zenithluminance = ( 4.0453f * m_turbidity - 4.9710f ) * std::tan( chi ) - 0.2155f * m_turbidity + 2.4192f;
|
||||
|
||||
// get x / y zenith
|
||||
@@ -196,22 +195,26 @@ void CSkyDome::RebuildColors() {
|
||||
float zenithy = GetZenith( m_zenithymatrix, m_thetasun, m_turbidity );
|
||||
|
||||
// get perez function parametrs
|
||||
float perezluminance[5], perezx[5], perezy[5];
|
||||
GetPerez( perezluminance, m_distributionluminance, m_turbidity );
|
||||
GetPerez( perezx, m_distributionxcomp, m_turbidity );
|
||||
GetPerez( perezy, m_distributionycomp, m_turbidity );
|
||||
std::array<float, 5> perezluminance{};
|
||||
std::array<float, 5> perezx{};
|
||||
std::array<float, 5> perezy{};
|
||||
GetPerez( perezluminance.data(), m_distributionluminance, m_turbidity );
|
||||
GetPerez( perezx.data(), m_distributionxcomp, m_turbidity );
|
||||
GetPerez( perezy.data(), m_distributionycomp, m_turbidity );
|
||||
|
||||
// make some precalculation
|
||||
zenithx = PerezFunctionO1( perezx, m_thetasun, zenithx );
|
||||
zenithy = PerezFunctionO1( perezy, m_thetasun, zenithy );
|
||||
zenithluminance = PerezFunctionO1( perezluminance, m_thetasun, zenithluminance );
|
||||
zenithx = PerezFunctionO1( perezx.data(), m_thetasun, zenithx );
|
||||
zenithy = PerezFunctionO1( perezy.data(), m_thetasun, zenithy );
|
||||
zenithluminance = PerezFunctionO1( perezluminance.data(), m_thetasun, zenithluminance );
|
||||
|
||||
// start with fresh average for the new pass
|
||||
glm::vec3 averagecolor, averagehorizoncolor;
|
||||
glm::vec3 averagecolor;
|
||||
glm::vec3 averagehorizoncolor;
|
||||
|
||||
// trough all vertices
|
||||
glm::vec3 vertex;
|
||||
glm::vec3 color, colorconverter;
|
||||
glm::vec3 color;
|
||||
glm::vec3 colorconverter;
|
||||
|
||||
for ( unsigned int i = 0; i < m_vertices.size(); ++i ) {
|
||||
// grab it
|
||||
@@ -235,14 +238,14 @@ void CSkyDome::RebuildColors() {
|
||||
// = 1.0f / cosf( arccos( vertex.y ) );
|
||||
// = 1.0f / vertex.y;
|
||||
float const icostheta = 1.0f / vertex.y;
|
||||
float const cosgamma2 = std::pow( std::cos( gamma ), 2 );
|
||||
auto const cosgamma2 = static_cast<float>(std::pow( std::cos( gamma ), 2 ));
|
||||
|
||||
// Compute x,y values
|
||||
float const x = PerezFunctionO2( perezx, icostheta, gamma, cosgamma2, zenithx );
|
||||
float const y = PerezFunctionO2( perezy, icostheta, gamma, cosgamma2, zenithy );
|
||||
float const x = PerezFunctionO2( perezx.data(), icostheta, gamma, cosgamma2, zenithx );
|
||||
float const y = PerezFunctionO2( perezy.data(), icostheta, gamma, cosgamma2, zenithy );
|
||||
|
||||
// luminance(Y) for clear & overcast sky
|
||||
float const yclear = std::max( 0.01f, PerezFunctionO2( perezluminance, icostheta, gamma, cosgamma2, zenithluminance ) );
|
||||
float const yclear = std::max( 0.01f, PerezFunctionO2( perezluminance.data(), icostheta, gamma, cosgamma2, zenithluminance ) );
|
||||
float const yover = std::max( 0.01f, zenithluminance * ( 1.0f + 2.0f * vertex.y ) / 3.0f );
|
||||
|
||||
float const Y = std::lerp( yclear, yover, m_overcast );
|
||||
@@ -271,7 +274,7 @@ void CSkyDome::RebuildColors() {
|
||||
|
||||
// override the hue, based on sun height above the horizon. crude way to deal with model shortcomings
|
||||
// correction begins when the sun is higher than 10 degrees above the horizon, and fully in effect at 10+15 degrees
|
||||
float const degreesabovehorizon = 90.0f - m_thetasun * ( 180.0f / M_PI );
|
||||
auto const degreesabovehorizon = static_cast<float>(90.0f - m_thetasun * ( 180.0f / M_PI ));
|
||||
auto const sunbasedphase = std::clamp( 1.0f / 15.0f * ( degreesabovehorizon - 10.0f ), 0.0f, 1.0f );
|
||||
// correction is applied in linear manner from the bottom, becomes fully in effect for vertices with y = 0.50
|
||||
auto const heightbasedphase = std::clamp( vertex.y * 2.0f, 0.0f, 1.0f );
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
class CSkyDome {
|
||||
public:
|
||||
CSkyDome( int const Tesselation = 54 );
|
||||
explicit CSkyDome( int const Tesselation = 54 );
|
||||
~CSkyDome();
|
||||
void Generate();
|
||||
void RebuildColors();
|
||||
@@ -20,8 +20,8 @@ public:
|
||||
void Update( glm::vec3 const &Sun );
|
||||
|
||||
// retrieves average colour of the sky dome
|
||||
glm::vec3 GetAverageColor() { return m_averagecolour * 8.f / 6.f; }
|
||||
glm::vec3 GetAverageHorizonColor() { return m_averagehorizoncolour; }
|
||||
glm::vec3 GetAverageColor() const { return m_averagecolour * 8.f / 6.f; }
|
||||
glm::vec3 GetAverageHorizonColor() const { return m_averagehorizoncolour; }
|
||||
|
||||
std::vector<glm::vec3> const & vertices() const {
|
||||
return m_vertices; }
|
||||
@@ -35,7 +35,8 @@ public:
|
||||
private:
|
||||
// shading parametrs
|
||||
glm::vec3 m_sundirection;
|
||||
float m_thetasun, m_phisun;
|
||||
float m_thetasun;
|
||||
float m_phisun;
|
||||
float m_turbidity;
|
||||
bool m_linearexpcontrol;
|
||||
float m_expfactor;
|
||||
@@ -59,9 +60,9 @@ private:
|
||||
static float m_zenithymatrix[ 3 ][ 4 ];
|
||||
|
||||
// coloring
|
||||
void GetPerez( float *Perez, float Distribution[ 5 ][ 2 ], const float Turbidity );
|
||||
float GetZenith( float Zenithmatrix[ 3 ][ 4 ], const float Theta, const float Turbidity );
|
||||
float PerezFunctionO1( float Perezcoeffs[ 5 ], const float Thetasun, const float Zenithval );
|
||||
float PerezFunctionO2( float Perezcoeffs[ 5 ], const float Icostheta, const float Gamma, const float Cosgamma2, const float Zenithval );
|
||||
void GetPerez( float *Perez, float Distribution[ 5 ][ 2 ], const float Turbidity ) const;
|
||||
float GetZenith( float Zenithmatrix[ 3 ][ 4 ], const float Theta, const float Turbidity ) const;
|
||||
float PerezFunctionO1( float const Perezcoeffs[ 5 ], const float Thetasun, const float Zenithval ) const;
|
||||
float PerezFunctionO2( float const Perezcoeffs[ 5 ], const float Icostheta, const float Gamma, const float Cosgamma2, const float Zenithval ) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -15,10 +15,7 @@ cSun::cSun() {
|
||||
m_observer.temp = 15.0; // ambient dry-bulb temperature, degrees C
|
||||
}
|
||||
|
||||
cSun::~cSun()
|
||||
{
|
||||
|
||||
}
|
||||
cSun::~cSun() = default;
|
||||
|
||||
void
|
||||
cSun::init() {
|
||||
@@ -79,8 +76,8 @@ float cSun::getIntensity() {
|
||||
void cSun::setLocation( float const Longitude, float const Latitude ) {
|
||||
|
||||
// convert fraction from geographical base of 6o minutes
|
||||
m_observer.longitude = (int)Longitude + (Longitude - (int)Longitude) * 100.0 / 60.0;
|
||||
m_observer.latitude = (int)Latitude + (Latitude - (int)Latitude) * 100.0 / 60.0 ;
|
||||
m_observer.longitude = (int)Longitude + (Longitude - static_cast<float>((int)Longitude)) * 100.0 / 60.0;
|
||||
m_observer.latitude = (int)Latitude + (Latitude - static_cast<float>((int)Latitude)) * 100.0 / 60.0 ;
|
||||
}
|
||||
|
||||
// sets current time, overriding one acquired from the system clock
|
||||
@@ -108,9 +105,9 @@ void cSun::move() {
|
||||
|
||||
SYSTEMTIME localtime = simulation::Time.data(); // time for the calculation
|
||||
|
||||
if( m_observer.hour >= 0 ) { localtime.wHour = m_observer.hour; }
|
||||
if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; }
|
||||
if( m_observer.second >= 0 ) { localtime.wSecond = m_observer.second; }
|
||||
if( m_observer.hour >= 0 ) { localtime.wHour = static_cast<uint16_t>(m_observer.hour); }
|
||||
if( m_observer.minute >= 0 ) { localtime.wMinute = static_cast<uint16_t>(m_observer.minute); }
|
||||
if( m_observer.second >= 0 ) { localtime.wSecond = static_cast<uint16_t>(m_observer.second); }
|
||||
|
||||
double localut =
|
||||
localtime.wHour
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "utilities/Logs.h"
|
||||
|
||||
#ifdef __unix__
|
||||
piped_proc::piped_proc(std::string cmd, bool write)
|
||||
piped_proc::piped_proc(std::string const &cmd, bool write)
|
||||
{
|
||||
file = popen(cmd.c_str(), write ? "w" : "r");
|
||||
}
|
||||
@@ -26,7 +26,7 @@ size_t piped_proc::read(unsigned char *buf, size_t len)
|
||||
return fread(buf, 1, len, file);
|
||||
}
|
||||
|
||||
size_t piped_proc::write(unsigned char *buf, size_t len)
|
||||
size_t piped_proc::write(unsigned char const *buf, size_t len)
|
||||
{
|
||||
if (!file)
|
||||
return 0;
|
||||
@@ -34,7 +34,7 @@ size_t piped_proc::write(unsigned char *buf, size_t len)
|
||||
return fwrite(buf, 1, len, file);
|
||||
}
|
||||
#elif _WIN32
|
||||
piped_proc::piped_proc(std::string cmd, bool write)
|
||||
piped_proc::piped_proc(std::string const &cmd, bool write)
|
||||
{
|
||||
PROCESS_INFORMATION process;
|
||||
STARTUPINFO siStartInfo;
|
||||
@@ -97,7 +97,7 @@ size_t piped_proc::read(unsigned char *buf, size_t len)
|
||||
return read;
|
||||
}
|
||||
|
||||
size_t piped_proc::write(unsigned char *buf, size_t len)
|
||||
size_t piped_proc::write(unsigned char const *buf, size_t len)
|
||||
{
|
||||
if (!pipe_wr)
|
||||
return 0;
|
||||
|
||||
@@ -23,8 +23,8 @@ HANDLE pipe_wr = nullptr;
|
||||
#endif
|
||||
|
||||
public:
|
||||
piped_proc(std::string cmd, bool write = false);
|
||||
explicit piped_proc(std::string const &cmd, bool write = false);
|
||||
size_t read(unsigned char *buf, size_t len);
|
||||
size_t write(unsigned char *buf, size_t len);
|
||||
size_t write(unsigned char const *buf, size_t len);
|
||||
~piped_proc();
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
GLenum gl::buffer::glenum_target(gl::buffer::targets target)
|
||||
{
|
||||
static GLenum mapping[13] =
|
||||
static std::array<GLenum, 13> const mapping =
|
||||
{
|
||||
GL_ARRAY_BUFFER,
|
||||
GL_ATOMIC_COUNTER_BUFFER,
|
||||
@@ -22,7 +22,7 @@ GLenum gl::buffer::glenum_target(gl::buffer::targets target)
|
||||
return mapping[target];
|
||||
}
|
||||
|
||||
void gl::buffer::bind(targets target)
|
||||
void gl::buffer::bind(targets target) const
|
||||
{
|
||||
if (binding_points[target] == *this)
|
||||
return;
|
||||
@@ -31,7 +31,7 @@ void gl::buffer::bind(targets target)
|
||||
binding_points[target] = *this;
|
||||
}
|
||||
|
||||
void gl::buffer::bind_base(targets target, GLuint index)
|
||||
void gl::buffer::bind_base(targets target, GLuint index) const
|
||||
{
|
||||
glBindBufferBase(glenum_target(target), index, *this);
|
||||
binding_points[target] = *this;
|
||||
@@ -47,7 +47,7 @@ void gl::buffer::unbind(targets target)
|
||||
|
||||
void gl::buffer::unbind()
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(binding_points) / sizeof(GLuint); i++)
|
||||
for (size_t i = 0; i < std::size(binding_points); i++)
|
||||
unbind((targets)i);
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ void gl::buffer::download(targets target, void *data, int offset, GLsizeiptr siz
|
||||
}
|
||||
else
|
||||
{
|
||||
void *glbuf = glMapBufferRange(glenum_target(target), offset, size, GL_MAP_READ_BIT);
|
||||
void const *glbuf = glMapBufferRange(glenum_target(target), offset, size, GL_MAP_READ_BIT);
|
||||
memcpy(data, glbuf, size);
|
||||
glUnmapBuffer(glenum_target(target));
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ namespace gl
|
||||
buffer();
|
||||
~buffer();
|
||||
|
||||
void bind(targets target);
|
||||
void bind_base(targets target, GLuint index);
|
||||
void bind(targets target) const;
|
||||
void bind_base(targets target, GLuint index) const;
|
||||
static void unbind(targets target);
|
||||
static void unbind();
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ gl::cubemap::~cubemap()
|
||||
glDeleteTextures(1, *this);
|
||||
}
|
||||
|
||||
void gl::cubemap::alloc(GLint format, int width, int height, GLenum components, GLenum type)
|
||||
void gl::cubemap::alloc(GLint format, int width, int height, GLenum components, GLenum type) const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, *this);
|
||||
for (GLuint tgt = GL_TEXTURE_CUBE_MAP_POSITIVE_X; tgt <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; tgt++)
|
||||
@@ -29,13 +29,13 @@ void gl::cubemap::alloc(GLint format, int width, int height, GLenum components,
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
}
|
||||
|
||||
void gl::cubemap::bind(int unit)
|
||||
void gl::cubemap::bind(int unit) const
|
||||
{
|
||||
glActiveTexture(unit);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, *this);
|
||||
}
|
||||
|
||||
void gl::cubemap::generate_mipmaps()
|
||||
void gl::cubemap::generate_mipmaps() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, *this);
|
||||
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
||||
|
||||
@@ -12,8 +12,8 @@ namespace gl
|
||||
cubemap();
|
||||
~cubemap();
|
||||
|
||||
void alloc(GLint format, int width, int height, GLenum components, GLenum type);
|
||||
void bind(int unit);
|
||||
void generate_mipmaps();
|
||||
void alloc(GLint format, int width, int height, GLenum components, GLenum type) const;
|
||||
void bind(int unit) const;
|
||||
void generate_mipmaps() const;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ void gl::framebuffer::blit_from(framebuffer *other, int w, int h, GLbitfield mas
|
||||
blit(other, this, 0, 0, w, h, mask, attachment);
|
||||
}
|
||||
|
||||
void gl::framebuffer::blit(framebuffer *src, framebuffer *dst, int sx, int sy, int w, int h, GLbitfield mask, GLenum attachment)
|
||||
void gl::framebuffer::blit(framebuffer const *src, framebuffer const *dst, int sx, int sy, int w, int h, GLbitfield mask, GLenum attachment)
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, src ? *src : 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst ? *dst : 0);
|
||||
@@ -90,17 +90,17 @@ void gl::framebuffer::blit(framebuffer *src, framebuffer *dst, int sx, int sy, i
|
||||
int attachment_n = attachment - GL_COLOR_ATTACHMENT0;
|
||||
|
||||
{
|
||||
GLenum outputs[8] = { GL_NONE };
|
||||
outputs[attachment_n] = src != 0 ? attachment : GL_BACK_LEFT;
|
||||
std::array<GLenum, 8> outputs{ GL_NONE };
|
||||
outputs[attachment_n] = src != nullptr ? attachment : GL_BACK_LEFT;
|
||||
|
||||
glReadBuffer(attachment);
|
||||
}
|
||||
|
||||
{
|
||||
GLenum outputs[8] = { GL_NONE };
|
||||
outputs[attachment_n] = dst != 0 ? attachment : GL_BACK_LEFT;
|
||||
std::array<GLenum, 8> outputs{ GL_NONE };
|
||||
outputs[attachment_n] = dst != nullptr ? attachment : GL_BACK_LEFT;
|
||||
|
||||
glDrawBuffers(attachment_n + 1, outputs);
|
||||
glDrawBuffers(attachment_n + 1, outputs.data());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace gl
|
||||
void blit_to(framebuffer *other, int w, int h, GLbitfield mask, GLenum attachment);
|
||||
void blit_from(framebuffer *other, int w, int h, GLbitfield mask, GLenum attachment);
|
||||
|
||||
static void blit(framebuffer *src, framebuffer *dst, int sx, int sy, int w, int h, GLbitfield mask, GLenum attachment);
|
||||
static void blit(framebuffer const *src, framebuffer const *dst, int sx, int sy, int w, int h, GLbitfield mask, GLenum attachment);
|
||||
|
||||
using bindable::bind;
|
||||
static void bind(GLuint id);
|
||||
|
||||
@@ -15,12 +15,12 @@ namespace gl
|
||||
return id;
|
||||
}
|
||||
|
||||
inline operator GLuint* const()
|
||||
inline operator GLuint*()
|
||||
{
|
||||
return &id;
|
||||
}
|
||||
|
||||
inline operator const GLuint* const() const
|
||||
inline operator const GLuint*() const
|
||||
{
|
||||
return &id;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ void gl::pbo::request_read(int x, int y, int lx, int ly, int pixsize, GLenum for
|
||||
sync.reset();
|
||||
|
||||
bind(PIXEL_PACK_BUFFER);
|
||||
glReadPixels(x, y, lx, ly, format, type, 0);
|
||||
glReadPixels(x, y, lx, ly, format, type, nullptr);
|
||||
unbind(PIXEL_PACK_BUFFER);
|
||||
|
||||
sync.emplace();
|
||||
|
||||
@@ -15,8 +15,8 @@ namespace gl
|
||||
static std::shared_ptr<gl::vao> vao;
|
||||
|
||||
public:
|
||||
postfx(const std::string &s);
|
||||
postfx(const shader &s);
|
||||
explicit postfx(const std::string &s);
|
||||
explicit postfx(const shader &s);
|
||||
|
||||
void attach();
|
||||
void apply(opengl_texture &src, framebuffer *dst);
|
||||
|
||||
@@ -49,9 +49,9 @@ std::optional<int64_t> gl::query::result()
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
GLenum gl::query::glenum_target(targets target)
|
||||
GLenum gl::query::glenum_target(targets Target) const
|
||||
{
|
||||
static GLenum mapping[6] =
|
||||
static std::array<GLenum, 6> const mapping =
|
||||
{
|
||||
GL_SAMPLES_PASSED,
|
||||
GL_ANY_SAMPLES_PASSED,
|
||||
@@ -60,7 +60,7 @@ GLenum gl::query::glenum_target(targets target)
|
||||
GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,
|
||||
GL_TIME_ELAPSED
|
||||
};
|
||||
return mapping[target];
|
||||
return mapping[Target];
|
||||
}
|
||||
|
||||
thread_local gl::query* gl::query::active_queries[6];
|
||||
|
||||
@@ -22,10 +22,10 @@ private:
|
||||
thread_local static query* active_queries[6];
|
||||
|
||||
protected:
|
||||
GLenum glenum_target(targets target);
|
||||
GLenum glenum_target(targets target) const;
|
||||
|
||||
public:
|
||||
query(targets target);
|
||||
explicit query(targets target);
|
||||
~query();
|
||||
|
||||
void begin();
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "glsl_common.h"
|
||||
#include "utilities/Logs.h"
|
||||
|
||||
inline bool strcend(std::string const &value, std::string const &ending)
|
||||
inline bool strcend(std::string_view value, std::string_view ending)
|
||||
{
|
||||
if (ending.size() > value.size())
|
||||
return false;
|
||||
@@ -41,7 +41,7 @@ bool has_gl_extension(char const *name) {
|
||||
GLint count = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &count);
|
||||
for (GLint i = 0; i < count; ++i) {
|
||||
char const *ext = reinterpret_cast<char const *>(glGetStringi(GL_EXTENSIONS, i));
|
||||
auto ext = reinterpret_cast<char const *>(glGetStringi(GL_EXTENSIONS, i));
|
||||
if (ext != nullptr && std::strcmp(ext, name) == 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -52,7 +52,7 @@ bool has_gl_extension(char const *name) {
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
std::string gl::shader::read_file(const std::string &filename)
|
||||
std::string gl::shader::read_file(const std::string &filename) const
|
||||
{
|
||||
std::stringstream stream;
|
||||
std::ifstream f;
|
||||
@@ -73,11 +73,11 @@ void gl::shader::expand_includes(std::string &str, const std::string &basedir)
|
||||
size_t start_pos = 0;
|
||||
|
||||
std::string magic = "#include";
|
||||
while ((start_pos = str.find(magic, start_pos)) != str.npos)
|
||||
while ((start_pos = str.find(magic, start_pos)) != std::string::npos)
|
||||
{
|
||||
size_t fp = str.find('<', start_pos);
|
||||
size_t fe = str.find('>', start_pos);
|
||||
if (fp == str.npos || fe == str.npos)
|
||||
if (fp == std::string::npos || fe == std::string::npos)
|
||||
return;
|
||||
|
||||
std::string filename = str.substr(fp + 1, fe - fp - 1);
|
||||
@@ -154,8 +154,7 @@ std::pair<GLuint, std::string> gl::shader::process_source(const std::string &fil
|
||||
// the driver advertises support (see desktop comment above).
|
||||
// (Glad config doesn't generate GLAD_GL_EXT_gpu_shader5 -- query
|
||||
// the live extension string the same way.)
|
||||
static bool const have_gpu_shader5 = has_gl_extension("GL_EXT_gpu_shader5");
|
||||
if (have_gpu_shader5)
|
||||
if (static bool const have_gpu_shader5 = has_gl_extension("GL_EXT_gpu_shader5"); have_gpu_shader5)
|
||||
str += "#extension GL_EXT_gpu_shader5 : enable\n";
|
||||
if (type == GL_GEOMETRY_SHADER)
|
||||
str += "#extension GL_EXT_geometry_shader : require\n";
|
||||
@@ -189,17 +188,17 @@ void gl::shader::parse_texture_entries(std::string &str)
|
||||
size_t start_pos = 0;
|
||||
|
||||
std::string magic = "#texture";
|
||||
while ((start_pos = str.find(magic, start_pos)) != str.npos)
|
||||
while ((start_pos = str.find(magic, start_pos)) != std::string::npos)
|
||||
{
|
||||
size_t fp = str.find('(', start_pos);
|
||||
size_t fe = str.find(')', start_pos);
|
||||
if (fp == str.npos || fe == str.npos)
|
||||
if (fp == std::string::npos || fe == std::string::npos)
|
||||
return;
|
||||
|
||||
std::istringstream ss(str.substr(fp + 1, fe - fp - 1));
|
||||
std::string token;
|
||||
|
||||
std::string name;
|
||||
std::string uniformname;
|
||||
texture_entry conf;
|
||||
|
||||
size_t arg = 0;
|
||||
@@ -207,14 +206,14 @@ void gl::shader::parse_texture_entries(std::string &str)
|
||||
{
|
||||
std::istringstream token_ss(token);
|
||||
if (arg == 0)
|
||||
token_ss >> name;
|
||||
token_ss >> uniformname;
|
||||
else if (arg == 1)
|
||||
token_ss >> conf.id;
|
||||
else if (arg == 2)
|
||||
{
|
||||
std::string comp;
|
||||
token_ss >> comp;
|
||||
if (components_mapping.find(comp) == components_mapping.end())
|
||||
if (!components_mapping.contains(comp))
|
||||
log_error("unknown components: " + comp);
|
||||
else
|
||||
conf.components = components_mapping[comp];
|
||||
@@ -224,12 +223,12 @@ void gl::shader::parse_texture_entries(std::string &str)
|
||||
|
||||
if (arg == 3)
|
||||
{
|
||||
if (name.empty())
|
||||
if (uniformname.empty())
|
||||
log_error("empty name");
|
||||
else if (conf.id >= gl::MAX_TEXTURES)
|
||||
log_error("invalid texture binding: " + std::to_string(conf.id));
|
||||
else
|
||||
texture_conf.emplace(std::make_pair(name, conf));
|
||||
texture_conf.try_emplace(uniformname, conf);
|
||||
}
|
||||
else
|
||||
log_error("invalid argument count to #texture");
|
||||
@@ -243,17 +242,17 @@ void gl::shader::parse_param_entries(std::string &str)
|
||||
size_t start_pos = 0;
|
||||
|
||||
std::string magic = "#param";
|
||||
while ((start_pos = str.find(magic, start_pos)) != str.npos)
|
||||
while ((start_pos = str.find(magic, start_pos)) != std::string::npos)
|
||||
{
|
||||
size_t fp = str.find('(', start_pos);
|
||||
size_t fe = str.find(')', start_pos);
|
||||
if (fp == str.npos || fe == str.npos)
|
||||
if (fp == std::string::npos || fe == std::string::npos)
|
||||
return;
|
||||
|
||||
std::istringstream ss(str.substr(fp + 1, fe - fp - 1));
|
||||
std::string token;
|
||||
|
||||
std::string name;
|
||||
std::string uniformname;
|
||||
param_entry conf;
|
||||
|
||||
size_t arg = 0;
|
||||
@@ -261,7 +260,7 @@ void gl::shader::parse_param_entries(std::string &str)
|
||||
{
|
||||
std::istringstream token_ss(token);
|
||||
if (arg == 0)
|
||||
token_ss >> name;
|
||||
token_ss >> uniformname;
|
||||
else if (arg == 1)
|
||||
token_ss >> conf.location;
|
||||
else if (arg == 2)
|
||||
@@ -272,7 +271,7 @@ void gl::shader::parse_param_entries(std::string &str)
|
||||
{
|
||||
std::string tok;
|
||||
token_ss >> tok;
|
||||
if (defaultparams_mapping.find(tok) == defaultparams_mapping.end())
|
||||
if (!defaultparams_mapping.contains(tok))
|
||||
log_error("unknown param default: " + tok);
|
||||
conf.defaultparam = defaultparams_mapping[tok];
|
||||
}
|
||||
@@ -281,7 +280,7 @@ void gl::shader::parse_param_entries(std::string &str)
|
||||
|
||||
if (arg == 5)
|
||||
{
|
||||
if (name.empty())
|
||||
if (uniformname.empty())
|
||||
log_error("empty name");
|
||||
else if (conf.location >= gl::MAX_PARAMS)
|
||||
log_error("invalid param binding: " + std::to_string(conf.location));
|
||||
@@ -290,7 +289,7 @@ void gl::shader::parse_param_entries(std::string &str)
|
||||
else if (conf.offset + conf.size > 4)
|
||||
log_error("invalid size: " + std::to_string(conf.size));
|
||||
else
|
||||
param_conf.emplace(std::make_pair(name, conf));
|
||||
param_conf.try_emplace(uniformname, conf);
|
||||
}
|
||||
else
|
||||
log_error("invalid argument count to #param");
|
||||
@@ -299,32 +298,31 @@ void gl::shader::parse_param_entries(std::string &str)
|
||||
}
|
||||
}
|
||||
|
||||
void gl::shader::log_error(const std::string &str)
|
||||
void gl::shader::log_error(const std::string &str) const
|
||||
{
|
||||
ErrorLog("bad shader: " + name + ": " + str, logtype::shader);
|
||||
}
|
||||
|
||||
gl::shader::shader(const std::string &filename)
|
||||
gl::shader::shader(const std::string &filename) : name(filename)
|
||||
{
|
||||
name = filename;
|
||||
|
||||
std::pair<GLuint, std::string> source = process_source(filename, "shaders/");
|
||||
auto [shadertype, shadersource] = process_source(filename, "shaders/");
|
||||
|
||||
const GLchar *cstr = source.second.c_str();
|
||||
const GLchar *cstr = shadersource.c_str();
|
||||
|
||||
**this = glCreateShader(source.first);
|
||||
glShaderSource(*this, 1, &cstr, 0);
|
||||
**this = glCreateShader(shadertype);
|
||||
glShaderSource(*this, 1, &cstr, nullptr);
|
||||
glCompileShader(*this);
|
||||
|
||||
GLint status;
|
||||
glGetShaderiv(*this, GL_COMPILE_STATUS, &status);
|
||||
if (!status)
|
||||
{
|
||||
GLchar info[512];
|
||||
glGetShaderInfoLog(*this, 512, 0, info);
|
||||
log_error(std::string(info));
|
||||
std::array<GLchar, 512> info{};
|
||||
glGetShaderInfoLog(*this, static_cast<GLsizei>(info.size()), nullptr, info.data());
|
||||
log_error(std::string(info.data()));
|
||||
|
||||
throw shader_exception("failed to compile " + filename + ": " + std::string(info));
|
||||
throw shader_exception("failed to compile " + filename + ": " + std::string(info.data()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,11 +337,11 @@ void gl::program::init()
|
||||
{
|
||||
bind();
|
||||
|
||||
for (auto it : texture_conf)
|
||||
for (auto const &[texturename, textureentry] : texture_conf)
|
||||
{
|
||||
shader::texture_entry &e = it.second;
|
||||
GLuint loc = glGetUniformLocation(*this, it.first.c_str());
|
||||
glUniform1i(loc, e.id);
|
||||
shader::texture_entry const &e = textureentry;
|
||||
GLuint loc = glGetUniformLocation(*this, texturename.c_str());
|
||||
glUniform1i(loc, static_cast<GLint>(e.id));
|
||||
}
|
||||
|
||||
glUniform1i(glGetUniformLocation(*this, "shadowmap"), gl::SHADOW_TEX);
|
||||
@@ -370,7 +368,7 @@ gl::program::program()
|
||||
**this = glCreateProgram();
|
||||
}
|
||||
|
||||
gl::program::program(std::vector<std::reference_wrapper<const gl::shader>> shaders) : program()
|
||||
gl::program::program(std::vector<std::reference_wrapper<const gl::shader>> const &shaders) : program()
|
||||
{
|
||||
for (const gl::shader &s : shaders)
|
||||
attach(s);
|
||||
@@ -379,10 +377,10 @@ gl::program::program(std::vector<std::reference_wrapper<const gl::shader>> shade
|
||||
|
||||
void gl::program::attach(const gl::shader &s)
|
||||
{
|
||||
for (auto it : s.texture_conf)
|
||||
texture_conf.emplace(std::make_pair(it.first, std::move(it.second)));
|
||||
for (auto it : s.param_conf)
|
||||
param_conf.emplace(std::make_pair(it.first, std::move(it.second)));
|
||||
for (auto [texturename, textureentry] : s.texture_conf)
|
||||
texture_conf.try_emplace(texturename, std::move(textureentry));
|
||||
for (auto [paramname, paramentry] : s.param_conf)
|
||||
param_conf.try_emplace(paramname, std::move(paramentry));
|
||||
glAttachShader(*this, *s);
|
||||
}
|
||||
|
||||
@@ -394,9 +392,9 @@ void gl::program::link()
|
||||
glGetProgramiv(*this, GL_LINK_STATUS, &status);
|
||||
if (!status)
|
||||
{
|
||||
GLchar info[512];
|
||||
glGetProgramInfoLog(*this, 512, 0, info);
|
||||
throw shader_exception("failed to link program: " + std::string(info));
|
||||
std::array<GLchar, 512> info{};
|
||||
glGetProgramInfoLog(*this, static_cast<GLsizei>(info.size()), nullptr, info.data());
|
||||
throw shader_exception("failed to link program: " + std::string(info.data()));
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace gl
|
||||
#ifdef SHADERVALIDATOR_STANDALONE
|
||||
shader() = default;
|
||||
#endif
|
||||
shader(const std::string &filename);
|
||||
explicit shader(const std::string &filename);
|
||||
~shader();
|
||||
|
||||
enum class components_e
|
||||
@@ -73,19 +73,19 @@ namespace gl
|
||||
void parse_texture_entries(std::string &str);
|
||||
void parse_param_entries(std::string &str);
|
||||
|
||||
std::string read_file(const std::string &filename);
|
||||
std::string read_file(const std::string &filename) const;
|
||||
|
||||
static std::unordered_map<std::string, components_e> components_mapping;
|
||||
static std::unordered_map<std::string, defaultparam_e> defaultparams_mapping;
|
||||
|
||||
void log_error(const std::string &str);
|
||||
void log_error(const std::string &str) const;
|
||||
};
|
||||
|
||||
class program : public object, public bindable<program>
|
||||
{
|
||||
public:
|
||||
program();
|
||||
program(std::vector<std::reference_wrapper<const gl::shader>>);
|
||||
explicit program(std::vector<std::reference_wrapper<const gl::shader>> const &);
|
||||
~program();
|
||||
|
||||
using bindable::bind;
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "ubo.h"
|
||||
|
||||
gl::ubo::ubo(size_t size, int idx, GLenum hint)
|
||||
gl::ubo::ubo(size_t size, int idx, GLenum hint) : index(idx)
|
||||
{
|
||||
allocate(buffer::UNIFORM_BUFFER, size, hint);
|
||||
index = idx;
|
||||
bind_uniform();
|
||||
}
|
||||
|
||||
|
||||
2
gl/ubo.h
2
gl/ubo.h
@@ -29,7 +29,7 @@ namespace gl
|
||||
void update(const uint8_t *data, int offset, GLsizeiptr size);
|
||||
template <typename T> void update(const T &data, size_t offset = 0)
|
||||
{
|
||||
update(reinterpret_cast<const uint8_t*>(&data), offset, sizeof(data));
|
||||
update(reinterpret_cast<const uint8_t*>(&data), static_cast<int>(offset), sizeof(data));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ void gl::vao::setup_attrib(gl::buffer &buffer, int attrib, int size, int type, i
|
||||
else {
|
||||
if (attrib == 0)
|
||||
params.clear();
|
||||
params.push_back({buffer, attrib, size, type, stride, offset});
|
||||
params.emplace_back(buffer, attrib, size, type, stride, offset);
|
||||
active = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -60,14 +60,14 @@ void gl::vao::bind()
|
||||
glBindVertexArray(*this);
|
||||
}
|
||||
else {
|
||||
for (attrib_params ¶m : params) {
|
||||
for (attrib_params const ¶m : params) {
|
||||
param.buffer.bind(gl::buffer::ARRAY_BUFFER);
|
||||
glVertexAttribPointer(param.attrib, param.size, param.type, GL_FALSE, param.stride, reinterpret_cast<void*>(param.offset));
|
||||
glEnableVertexAttribArray(param.attrib);
|
||||
}
|
||||
|
||||
for (size_t i = params.size(); i < 5; i++)
|
||||
glDisableVertexAttribArray(i);
|
||||
glDisableVertexAttribArray(static_cast<GLuint>(i));
|
||||
|
||||
if (ebo)
|
||||
ebo->bind(gl::buffer::ELEMENT_ARRAY_BUFFER);
|
||||
@@ -84,6 +84,6 @@ void gl::vao::unbind()
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
glDisableVertexAttribArray(i);
|
||||
glDisableVertexAttribArray(static_cast<GLuint>(i));
|
||||
}
|
||||
}
|
||||
|
||||
2
gl/vao.h
2
gl/vao.h
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace gl
|
||||
{
|
||||
class vao : object, public bindable<vao>
|
||||
class vao : private object, public bindable<vao>
|
||||
{
|
||||
struct attrib_params {
|
||||
// TBD: should be shared_ptr? (when buffer is destroyed by owner VAO could still potentially exist)
|
||||
|
||||
@@ -19,42 +19,44 @@ struct IMaterial
|
||||
virtual texture_handle GetTexture(int slot) const = 0;
|
||||
static IMaterial *null_material()
|
||||
{
|
||||
static struct NullMaterial : public IMaterial
|
||||
struct NullMaterial : public IMaterial
|
||||
{
|
||||
virtual void finalize(bool Loadnow) override {}
|
||||
virtual bool update() override
|
||||
void finalize(bool Loadnow) override { /* null implementation, nothing to do */ }
|
||||
bool update() override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual float get_or_guess_opacity() const override
|
||||
float get_or_guess_opacity() const override
|
||||
{
|
||||
return 1.f;
|
||||
}
|
||||
virtual bool is_translucent() const override
|
||||
bool is_translucent() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual glm::vec2 GetSize() const override
|
||||
glm::vec2 GetSize() const override
|
||||
{
|
||||
return {-1.f, -1.f};
|
||||
}
|
||||
virtual std::string GetName() const override
|
||||
std::string GetName() const override
|
||||
{
|
||||
return "";
|
||||
}
|
||||
virtual std::optional<float> GetSelfillum() const override
|
||||
std::optional<float> GetSelfillum() const override
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
virtual int GetShadowRank() const override
|
||||
int GetShadowRank() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual texture_handle GetTexture(int slot) const override
|
||||
texture_handle GetTexture(int slot) const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
} null_material{};
|
||||
};
|
||||
static NullMaterial null_material{};
|
||||
return &null_material;
|
||||
}
|
||||
virtual ~IMaterial() = default;
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
typedef int texture_handle;
|
||||
using texture_handle = int;
|
||||
|
||||
#define null_handle (0)
|
||||
|
||||
@@ -23,54 +23,56 @@ struct ITexture
|
||||
virtual void update_from_memory(size_t width, size_t height, const uint8_t *data) = 0;
|
||||
static ITexture *null_texture()
|
||||
{
|
||||
static struct NullTexture : public ITexture
|
||||
struct NullTexture : public ITexture
|
||||
{
|
||||
virtual bool create(bool Static = false) override
|
||||
bool create(bool Static = false) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool is_stub() const override
|
||||
bool is_stub() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual int get_width() const override
|
||||
int get_width() const override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
virtual int get_height() const override
|
||||
int get_height() const override
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
virtual size_t get_id() const override
|
||||
size_t get_id() const override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
virtual void release() override {}
|
||||
virtual void make_stub() override {}
|
||||
virtual std::string_view get_traits() const override
|
||||
void release() override { /* null implementation, nothing to do */ }
|
||||
void make_stub() override { /* null implementation, nothing to do */ }
|
||||
std::string_view get_traits() const override
|
||||
{
|
||||
return "";
|
||||
}
|
||||
virtual std::string_view get_name() const override
|
||||
std::string_view get_name() const override
|
||||
{
|
||||
return "";
|
||||
}
|
||||
virtual std::string_view get_type() const override
|
||||
std::string_view get_type() const override
|
||||
{
|
||||
return "";
|
||||
}
|
||||
virtual bool get_has_alpha() const override
|
||||
bool get_has_alpha() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool get_is_ready() const override
|
||||
bool get_is_ready() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void set_components_hint(int hint) override {}
|
||||
virtual void make_from_memory(size_t width, size_t height, const uint8_t *data) override {}
|
||||
virtual void update_from_memory(size_t width, size_t height, const uint8_t *data) override {}
|
||||
} null_texture{};
|
||||
void set_components_hint(int hint) override { /* null implementation, nothing to do */ }
|
||||
void make_from_memory(size_t width, size_t height, const uint8_t *data) override { /* null implementation, nothing to do */ }
|
||||
void update_from_memory(size_t width, size_t height, const uint8_t *data) override { /* null implementation, nothing to do */ }
|
||||
};
|
||||
static NullTexture null_texture{};
|
||||
return &null_texture;
|
||||
}
|
||||
virtual ~ITexture() = default;
|
||||
};
|
||||
@@ -408,7 +408,7 @@ commanddescription_sequence Commands_descriptions = {
|
||||
};
|
||||
|
||||
// Maps of command and coresponding strings
|
||||
std::unordered_map<std::string, user_command> commandMap = {
|
||||
std::unordered_map<std::string, user_command> const commandMap = {
|
||||
{"aidriverdisable", user_command::aidriverdisable},
|
||||
{"jointcontrollerset", user_command::jointcontrollerset},
|
||||
{"mastercontrollerincrease", user_command::mastercontrollerincrease},
|
||||
@@ -796,12 +796,12 @@ std::unordered_map<std::string, user_command> commandMap = {
|
||||
void command_queue::update()
|
||||
{
|
||||
double delta = Timer::GetDeltaTime();
|
||||
for (auto c : m_active_continuous)
|
||||
for (auto [activecommand, activerecipient] : m_active_continuous)
|
||||
{
|
||||
command_data data({c.first, GLFW_REPEAT, 0.0, 0.0, delta, false, glm::vec3()}); // todo: improve
|
||||
auto lookup = m_commands.emplace( c.second, commanddata_sequence() );
|
||||
command_data data({activecommand, GLFW_REPEAT, 0.0, 0.0, delta, false, glm::vec3()}); // todo: improve
|
||||
auto [queueiterator, queueinserted] = m_commands.try_emplace( activerecipient, commanddata_sequence() );
|
||||
// recipient stack was either located or created, so we can add to it quite safely
|
||||
lookup.first->second.emplace_back( data );
|
||||
queueiterator->second.emplace_back( data );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -809,16 +809,15 @@ void command_queue::update()
|
||||
void
|
||||
command_queue::push( command_data const &Command, uint32_t const Recipient ) {
|
||||
if (is_network_target(Recipient)) {
|
||||
auto lookup = m_intercept_queue.emplace(Recipient, commanddata_sequence());
|
||||
lookup.first->second.emplace_back(Command);
|
||||
auto [queueiterator, queueinserted] = m_intercept_queue.try_emplace(Recipient, commanddata_sequence());
|
||||
queueiterator->second.emplace_back(Command);
|
||||
} else {
|
||||
push_direct(Command, Recipient);
|
||||
}
|
||||
}
|
||||
|
||||
void command_queue::push_direct(const command_data &Command, const uint32_t Recipient) {
|
||||
auto const &desc = simulation::Commands_descriptions[ static_cast<std::size_t>( Command.command ) ];
|
||||
if (desc.mode == command_mode::continuous)
|
||||
if (auto const &desc = simulation::Commands_descriptions[ static_cast<std::size_t>( Command.command ) ]; desc.mode == command_mode::continuous)
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
m_active_continuous.emplace(std::make_pair(Command.command, Recipient));
|
||||
@@ -828,9 +827,9 @@ void command_queue::push_direct(const command_data &Command, const uint32_t Reci
|
||||
return;
|
||||
}
|
||||
|
||||
auto lookup = m_commands.emplace( Recipient, commanddata_sequence() );
|
||||
auto [queueiterator, queueinserted] = m_commands.try_emplace( Recipient, commanddata_sequence() );
|
||||
// recipient stack was either located or created, so we can add to it quite safely
|
||||
lookup.first->second.emplace_back( Command );
|
||||
queueiterator->second.emplace_back( Command );
|
||||
}
|
||||
|
||||
// retrieves oldest posted command for specified recipient, if any. returns: true on retrieval, false if there's nothing to retrieve
|
||||
@@ -854,10 +853,9 @@ command_queue::pop( command_data &Command, uint32_t const Recipient ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool command_queue::is_network_target(uint32_t const Recipient) {
|
||||
const command_target target = (command_target)(Recipient & ~0xffff);
|
||||
bool command_queue::is_network_target(uint32_t const Recipient) const {
|
||||
|
||||
if (target == command_target::entity)
|
||||
if (const auto target = (command_target)(Recipient & ~0xffff); target == command_target::entity)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -870,9 +868,9 @@ command_queue::commands_map command_queue::pop_intercept_queue() {
|
||||
}
|
||||
|
||||
void command_queue::push_commands(const commands_map &commands) {
|
||||
for (auto const &kv : commands)
|
||||
for (command_data const &data : kv.second)
|
||||
push_direct(data, kv.first);
|
||||
for (auto const &[recipient, sequence] : commands)
|
||||
for (command_data const &data : sequence)
|
||||
push_direct(data, recipient);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -455,8 +455,8 @@ class command_queue {
|
||||
|
||||
public:
|
||||
// types
|
||||
typedef std::deque<command_data> commanddata_sequence;
|
||||
typedef std::unordered_map<uint32_t, commanddata_sequence> commands_map;
|
||||
using commanddata_sequence = std::deque<command_data>;
|
||||
using commands_map = std::unordered_map<uint32_t, commanddata_sequence>;
|
||||
// methods
|
||||
// posts specified command for specified recipient into m_intercept_queue
|
||||
void
|
||||
@@ -469,7 +469,7 @@ public:
|
||||
update();
|
||||
// checks if given command must be scheduled on server
|
||||
bool
|
||||
is_network_target(const uint32_t Recipient);
|
||||
is_network_target(const uint32_t Recipient) const;
|
||||
|
||||
// pops commands from intercept queue
|
||||
commands_map pop_intercept_queue();
|
||||
@@ -511,13 +511,13 @@ void add_to_dequemap(std::unordered_map<A, std::deque<B>> &lhs, const std::unord
|
||||
// but realistically it's not like we're going to run more than one simulation at a time
|
||||
namespace simulation {
|
||||
|
||||
typedef std::vector<command_description> commanddescription_sequence;
|
||||
using commanddescription_sequence = std::vector<command_description>;
|
||||
|
||||
extern command_queue Commands;
|
||||
// TODO: add name to command map, and wrap these two into helper object
|
||||
extern commanddescription_sequence Commands_descriptions;
|
||||
|
||||
extern std::unordered_map<std::string, user_command> commandMap;
|
||||
extern std::unordered_map<std::string, user_command> const commandMap;
|
||||
}
|
||||
|
||||
// command_relay: composite class component, passes specified command to appropriate command stack
|
||||
@@ -530,7 +530,6 @@ public:
|
||||
void
|
||||
post(user_command const Command, double const Param1, double const Param2,
|
||||
int const Action, uint16_t Recipient, glm::vec3 Position = glm::vec3(0.0f) , const std::string *Payload = nullptr) const;
|
||||
private:
|
||||
// types
|
||||
// members
|
||||
};
|
||||
|
||||
@@ -22,276 +22,277 @@ driverkeyboard_input::init() {
|
||||
|
||||
void
|
||||
driverkeyboard_input::default_bindings() {
|
||||
using enum user_command;
|
||||
|
||||
m_bindingsetups = {
|
||||
{ user_command::aidriverenable, {GLFW_KEY_Q | keymodifier::shift, ""} },
|
||||
{ user_command::aidriverdisable, {GLFW_KEY_Q, ""} },
|
||||
{ aidriverenable, {GLFW_KEY_Q | keymodifier::shift, ""} },
|
||||
{ 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, ""} },
|
||||
{ user_command::mastercontrollerdecreasefast, {GLFW_KEY_KP_SUBTRACT | keymodifier::shift, ""} },
|
||||
{ mastercontrollerincrease, {GLFW_KEY_KP_ADD, ""} },
|
||||
{ mastercontrollerincreasefast, {GLFW_KEY_KP_ADD | keymodifier::shift, ""} },
|
||||
{ mastercontrollerdecrease, {GLFW_KEY_KP_SUBTRACT, ""} },
|
||||
{ mastercontrollerdecreasefast, {GLFW_KEY_KP_SUBTRACT | keymodifier::shift, ""} },
|
||||
// mastercontrollerset,
|
||||
|
||||
{ user_command::dynamicbrakecontrollerincrease, {GLFW_KEY_KP_3 | keymodifier::control, ""} },
|
||||
{ user_command::dynamicbrakecontrollerdecrease, {GLFW_KEY_KP_9 | keymodifier::control, ""} },
|
||||
{ dynamicbrakecontrollerincrease, {GLFW_KEY_KP_3 | keymodifier::control, ""} },
|
||||
{ dynamicbrakecontrollerdecrease, {GLFW_KEY_KP_9 | keymodifier::control, ""} },
|
||||
// mastercontrollerset,
|
||||
{ user_command::dynamicbrakecontrollerincreasefast, {GLFW_KEY_KP_3 | keymodifier::control | keymodifier::shift, ""} },
|
||||
{ user_command::dynamicbrakecontrollerdecreasefast, {GLFW_KEY_KP_9 | keymodifier::control | keymodifier::shift, ""} },
|
||||
{ dynamicbrakecontrollerincreasefast, {GLFW_KEY_KP_3 | keymodifier::control | keymodifier::shift, ""} },
|
||||
{ dynamicbrakecontrollerdecreasefast, {GLFW_KEY_KP_9 | keymodifier::control | keymodifier::shift, ""} },
|
||||
|
||||
{ user_command::secondcontrollerincrease, {GLFW_KEY_KP_DIVIDE, ""} },
|
||||
{ user_command::secondcontrollerincreasefast, {GLFW_KEY_KP_DIVIDE | keymodifier::shift, ""} },
|
||||
{ user_command::secondcontrollerdecrease, {GLFW_KEY_KP_MULTIPLY, ""} },
|
||||
{ user_command::secondcontrollerdecreasefast, {GLFW_KEY_KP_MULTIPLY | keymodifier::shift, ""} },
|
||||
{ secondcontrollerincrease, {GLFW_KEY_KP_DIVIDE, ""} },
|
||||
{ secondcontrollerincreasefast, {GLFW_KEY_KP_DIVIDE | keymodifier::shift, ""} },
|
||||
{ secondcontrollerdecrease, {GLFW_KEY_KP_MULTIPLY, ""} },
|
||||
{ secondcontrollerdecreasefast, {GLFW_KEY_KP_MULTIPLY | keymodifier::shift, ""} },
|
||||
// secondcontrollerset,
|
||||
{ user_command::mucurrentindicatorothersourceactivate, {GLFW_KEY_Z | keymodifier::shift, ""} },
|
||||
{ user_command::independentbrakeincrease, {GLFW_KEY_KP_1, ""} },
|
||||
{ user_command::independentbrakeincreasefast, {GLFW_KEY_KP_1 | keymodifier::shift, ""} },
|
||||
{ user_command::independentbrakedecrease, {GLFW_KEY_KP_7, ""} },
|
||||
{ user_command::independentbrakedecreasefast, {GLFW_KEY_KP_7 | keymodifier::shift, ""} },
|
||||
{ mucurrentindicatorothersourceactivate, {GLFW_KEY_Z | keymodifier::shift, ""} },
|
||||
{ independentbrakeincrease, {GLFW_KEY_KP_1, ""} },
|
||||
{ independentbrakeincreasefast, {GLFW_KEY_KP_1 | keymodifier::shift, ""} },
|
||||
{ independentbrakedecrease, {GLFW_KEY_KP_7, ""} },
|
||||
{ independentbrakedecreasefast, {GLFW_KEY_KP_7 | keymodifier::shift, ""} },
|
||||
// independentbrakeset,
|
||||
{ user_command::independentbrakebailoff, {GLFW_KEY_KP_4, ""} },
|
||||
{ independentbrakebailoff, {GLFW_KEY_KP_4, ""} },
|
||||
// universalbrakebutton1,
|
||||
// universalbrakebutton2,
|
||||
// universalbrakebutton3,
|
||||
{ user_command::trainbrakeincrease, {GLFW_KEY_KP_3, ""} },
|
||||
{ user_command::trainbrakedecrease, {GLFW_KEY_KP_9, ""} },
|
||||
{ trainbrakeincrease, {GLFW_KEY_KP_3, ""} },
|
||||
{ trainbrakedecrease, {GLFW_KEY_KP_9, ""} },
|
||||
// trainbrakeset,
|
||||
{ user_command::trainbrakecharging, {GLFW_KEY_KP_DECIMAL, ""} },
|
||||
{ user_command::trainbrakerelease, {GLFW_KEY_KP_6, ""} },
|
||||
{ user_command::trainbrakefirstservice, {GLFW_KEY_KP_8, ""} },
|
||||
{ user_command::trainbrakeservice, {GLFW_KEY_KP_5, ""} },
|
||||
{ user_command::trainbrakefullservice, {GLFW_KEY_KP_2, ""} },
|
||||
{ user_command::trainbrakehandleoff, {GLFW_KEY_KP_5 | keymodifier::control, ""} },
|
||||
{ user_command::trainbrakeemergency, {GLFW_KEY_KP_0, ""} },
|
||||
{ user_command::trainbrakebasepressureincrease, {GLFW_KEY_KP_3 | keymodifier::control, ""} },
|
||||
{ user_command::trainbrakebasepressuredecrease, {GLFW_KEY_KP_9 | keymodifier::control, ""} },
|
||||
{ user_command::trainbrakebasepressurereset, {GLFW_KEY_KP_6 | keymodifier::control, ""} },
|
||||
{ user_command::trainbrakeoperationtoggle, {GLFW_KEY_KP_4 | keymodifier::control, ""} },
|
||||
{ user_command::manualbrakeincrease, {GLFW_KEY_KP_1 | keymodifier::control, ""} },
|
||||
{ user_command::manualbrakedecrease, {GLFW_KEY_KP_7 | keymodifier::control, ""} },
|
||||
{ user_command::alarmchaintoggle, {GLFW_KEY_B | keymodifier::shift | keymodifier::control, ""} },
|
||||
{ trainbrakecharging, {GLFW_KEY_KP_DECIMAL, ""} },
|
||||
{ trainbrakerelease, {GLFW_KEY_KP_6, ""} },
|
||||
{ trainbrakefirstservice, {GLFW_KEY_KP_8, ""} },
|
||||
{ trainbrakeservice, {GLFW_KEY_KP_5, ""} },
|
||||
{ trainbrakefullservice, {GLFW_KEY_KP_2, ""} },
|
||||
{ trainbrakehandleoff, {GLFW_KEY_KP_5 | keymodifier::control, ""} },
|
||||
{ trainbrakeemergency, {GLFW_KEY_KP_0, ""} },
|
||||
{ trainbrakebasepressureincrease, {GLFW_KEY_KP_3 | keymodifier::control, ""} },
|
||||
{ trainbrakebasepressuredecrease, {GLFW_KEY_KP_9 | keymodifier::control, ""} },
|
||||
{ trainbrakebasepressurereset, {GLFW_KEY_KP_6 | keymodifier::control, ""} },
|
||||
{ trainbrakeoperationtoggle, {GLFW_KEY_KP_4 | keymodifier::control, ""} },
|
||||
{ manualbrakeincrease, {GLFW_KEY_KP_1 | keymodifier::control, ""} },
|
||||
{ manualbrakedecrease, {GLFW_KEY_KP_7 | keymodifier::control, ""} },
|
||||
{ alarmchaintoggle, {GLFW_KEY_B | keymodifier::shift | keymodifier::control, ""} },
|
||||
// alarmchainenable,
|
||||
// alarmchaindisable,
|
||||
{ user_command::wheelspinbrakeactivate, {GLFW_KEY_KP_ENTER, ""} },
|
||||
{ user_command::sandboxactivate, {GLFW_KEY_S | keymodifier::shift, ""} },
|
||||
{ wheelspinbrakeactivate, {GLFW_KEY_KP_ENTER, ""} },
|
||||
{ sandboxactivate, {GLFW_KEY_S | keymodifier::shift, ""} },
|
||||
// autosandboxtoggle,
|
||||
// autosandboxactivate,
|
||||
// autosandboxdeactivate,
|
||||
{ user_command::reverserincrease, {GLFW_KEY_D, ""} },
|
||||
{ user_command::reverserdecrease, {GLFW_KEY_R, ""} },
|
||||
{ reverserincrease, {GLFW_KEY_D, ""} },
|
||||
{ reverserdecrease, {GLFW_KEY_R, ""} },
|
||||
// reverserforwardhigh,
|
||||
// reverserforward,
|
||||
// reverserneutral,
|
||||
// reverserbackward,
|
||||
{ user_command::waterpumpbreakertoggle, {GLFW_KEY_W | keymodifier::control, ""} },
|
||||
{ waterpumpbreakertoggle, {GLFW_KEY_W | keymodifier::control, ""} },
|
||||
// waterpumpbreakerclose,
|
||||
// waterpumpbreakeropen,
|
||||
{ user_command::waterpumptoggle, {GLFW_KEY_W, ""} },
|
||||
{ waterpumptoggle, {GLFW_KEY_W, ""} },
|
||||
// waterpumpenable,
|
||||
// waterpumpdisable,
|
||||
{ user_command::waterheaterbreakertoggle, {GLFW_KEY_W | keymodifier::control | keymodifier::shift, ""} },
|
||||
{ waterheaterbreakertoggle, {GLFW_KEY_W | keymodifier::control | keymodifier::shift, ""} },
|
||||
// waterheaterbreakerclose,
|
||||
// waterheaterbreakeropen,
|
||||
{ user_command::waterheatertoggle, {GLFW_KEY_W | keymodifier::shift, ""} },
|
||||
{ waterheatertoggle, {GLFW_KEY_W | keymodifier::shift, ""} },
|
||||
// waterheaterenable,
|
||||
// waterheaterdisable,
|
||||
{ user_command::watercircuitslinktoggle, {GLFW_KEY_H | keymodifier::shift, ""} },
|
||||
{ watercircuitslinktoggle, {GLFW_KEY_H | keymodifier::shift, ""} },
|
||||
// watercircuitslinkenable,
|
||||
// watercircuitslinkdisable,
|
||||
{ user_command::fuelpumptoggle, {GLFW_KEY_F, ""} },
|
||||
{ fuelpumptoggle, {GLFW_KEY_F, ""} },
|
||||
// fuelpumpenable,
|
||||
// fuelpumpdisable,
|
||||
{ user_command::oilpumptoggle, {GLFW_KEY_F | keymodifier::shift, ""} },
|
||||
{ oilpumptoggle, {GLFW_KEY_F | keymodifier::shift, ""} },
|
||||
// oilpumpenable,
|
||||
// oilpumpdisable,
|
||||
{ user_command::linebreakertoggle, {GLFW_KEY_M, ""} },
|
||||
{ linebreakertoggle, {GLFW_KEY_M, ""} },
|
||||
// linebreakeropen,
|
||||
// linebreakerclose,
|
||||
{ user_command::convertertoggle, {GLFW_KEY_X, ""} },
|
||||
{ convertertoggle, {GLFW_KEY_X, ""} },
|
||||
// converterenable,
|
||||
// converterdisable,
|
||||
{ user_command::convertertogglelocal, {GLFW_KEY_X | keymodifier::shift, ""} },
|
||||
{ user_command::converteroverloadrelayreset, {GLFW_KEY_N | keymodifier::control, ""} },
|
||||
{ user_command::compressortoggle, {GLFW_KEY_C, ""} },
|
||||
{ convertertogglelocal, {GLFW_KEY_X | keymodifier::shift, ""} },
|
||||
{ converteroverloadrelayreset, {GLFW_KEY_N | keymodifier::control, ""} },
|
||||
{ compressortoggle, {GLFW_KEY_C, ""} },
|
||||
// compressorenable,
|
||||
// compressordisable,
|
||||
{ user_command::compressortogglelocal, {GLFW_KEY_C | keymodifier::shift, ""} },
|
||||
{ compressortogglelocal, {GLFW_KEY_C | keymodifier::shift, ""} },
|
||||
// compressorpresetactivatenext,
|
||||
// compressorpresetactivateprevious,
|
||||
// compressorpresetactivatedefault,
|
||||
{ user_command::motoroverloadrelaythresholdtoggle, {GLFW_KEY_F | keymodifier::control, ""} },
|
||||
{ motoroverloadrelaythresholdtoggle, {GLFW_KEY_F | keymodifier::control, ""} },
|
||||
// motoroverloadrelaythresholdsetlow,
|
||||
// motoroverloadrelaythresholdsethigh,
|
||||
{ user_command::motoroverloadrelayreset, {GLFW_KEY_N, ""} },
|
||||
{ motoroverloadrelayreset, {GLFW_KEY_N, ""} },
|
||||
// universalrelayreset1,
|
||||
// universalrelayreset2,
|
||||
// universalrelayreset3,
|
||||
{ user_command::notchingrelaytoggle, {GLFW_KEY_G, ""} },
|
||||
{ user_command::epbrakecontroltoggle, {GLFW_KEY_Z | keymodifier::control, ""} },
|
||||
{ notchingrelaytoggle, {GLFW_KEY_G, ""} },
|
||||
{ epbrakecontroltoggle, {GLFW_KEY_Z | keymodifier::control, ""} },
|
||||
// epbrakecontrolenable
|
||||
// epbrakecontroldisable
|
||||
{ user_command::trainbrakeoperationmodeincrease, {GLFW_KEY_KP_2 | keymodifier::control, ""} },
|
||||
{ user_command::trainbrakeoperationmodedecrease, {GLFW_KEY_KP_8 | keymodifier::control, ""} },
|
||||
{ user_command::brakeactingspeedincrease, {GLFW_KEY_B | keymodifier::shift, ""} },
|
||||
{ user_command::brakeactingspeeddecrease, {GLFW_KEY_B, ""} },
|
||||
{ trainbrakeoperationmodeincrease, {GLFW_KEY_KP_2 | keymodifier::control, ""} },
|
||||
{ trainbrakeoperationmodedecrease, {GLFW_KEY_KP_8 | keymodifier::control, ""} },
|
||||
{ brakeactingspeedincrease, {GLFW_KEY_B | keymodifier::shift, ""} },
|
||||
{ brakeactingspeeddecrease, {GLFW_KEY_B, ""} },
|
||||
// brakeactingspeedsetcargo,
|
||||
// brakeactingspeedsetpassenger,
|
||||
// brakeactingspeedsetrapid,
|
||||
{ user_command::brakeloadcompensationincrease, {GLFW_KEY_H | keymodifier::shift | keymodifier::control, ""} },
|
||||
{ user_command::brakeloadcompensationdecrease, {GLFW_KEY_H | keymodifier::control, ""} },
|
||||
{ user_command::mubrakingindicatortoggle, {GLFW_KEY_L | keymodifier::shift, ""} },
|
||||
{ user_command::alerteracknowledge, {GLFW_KEY_SPACE, ""} },
|
||||
{ user_command::hornlowactivate, {GLFW_KEY_A, ""} },
|
||||
{ user_command::hornhighactivate, {GLFW_KEY_S, ""} },
|
||||
{ user_command::whistleactivate, {GLFW_KEY_Z, ""} },
|
||||
{ user_command::radiotoggle, {GLFW_KEY_R | keymodifier::control, ""} },
|
||||
{ brakeloadcompensationincrease, {GLFW_KEY_H | keymodifier::shift | keymodifier::control, ""} },
|
||||
{ brakeloadcompensationdecrease, {GLFW_KEY_H | keymodifier::control, ""} },
|
||||
{ mubrakingindicatortoggle, {GLFW_KEY_L | keymodifier::shift, ""} },
|
||||
{ alerteracknowledge, {GLFW_KEY_SPACE, ""} },
|
||||
{ hornlowactivate, {GLFW_KEY_A, ""} },
|
||||
{ hornhighactivate, {GLFW_KEY_S, ""} },
|
||||
{ whistleactivate, {GLFW_KEY_Z, ""} },
|
||||
{ radiotoggle, {GLFW_KEY_R | keymodifier::control, ""} },
|
||||
// radioenable
|
||||
// radiodisable
|
||||
{ user_command::radiochannelincrease, {GLFW_KEY_EQUAL, ""} },
|
||||
{ user_command::radiochanneldecrease, {GLFW_KEY_MINUS, ""} },
|
||||
{ radiochannelincrease, {GLFW_KEY_EQUAL, ""} },
|
||||
{ radiochanneldecrease, {GLFW_KEY_MINUS, ""} },
|
||||
// radiochannelset
|
||||
{ user_command::radiostopsend, {GLFW_KEY_PAUSE | keymodifier::shift | keymodifier::control, ""} },
|
||||
{ radiostopsend, {GLFW_KEY_PAUSE | keymodifier::shift | keymodifier::control, ""} },
|
||||
// radiostopenable
|
||||
// radiostopdisable
|
||||
{ user_command::radiostoptest, {GLFW_KEY_R | keymodifier::shift | keymodifier::control, ""} },
|
||||
{ user_command::radiocall3send, {GLFW_KEY_BACKSPACE, ""} },
|
||||
{ radiostoptest, {GLFW_KEY_R | keymodifier::shift | keymodifier::control, ""} },
|
||||
{ radiocall3send, {GLFW_KEY_BACKSPACE, ""} },
|
||||
// radiovolumeincrease,
|
||||
// radiovolumedecrease,
|
||||
// radiovolumeset,
|
||||
{ user_command::cabchangeforward, {GLFW_KEY_HOME, ""} },
|
||||
{ user_command::cabchangebackward, {GLFW_KEY_END, ""} },
|
||||
{ cabchangeforward, {GLFW_KEY_HOME, ""} },
|
||||
{ cabchangebackward, {GLFW_KEY_END, ""} },
|
||||
// viewturn,
|
||||
// movehorizontal,
|
||||
// movehorizontalfast,
|
||||
// movevertical,
|
||||
// moveverticalfast,
|
||||
{ user_command::moveleft, {GLFW_KEY_LEFT, "Move left"} },
|
||||
{ user_command::moveright, {GLFW_KEY_RIGHT, "Move right"} },
|
||||
{ user_command::moveforward, {GLFW_KEY_UP, "Move forwards"} },
|
||||
{ user_command::moveback, {GLFW_KEY_DOWN, "Move backwards"} },
|
||||
{ user_command::moveup, {GLFW_KEY_PAGE_UP, "Move up"} },
|
||||
{ user_command::movedown, {GLFW_KEY_PAGE_DOWN, "Move down"} },
|
||||
{ user_command::nearestcarcouplingincrease, {GLFW_KEY_INSERT, ""} },
|
||||
{ user_command::nearestcarcouplingdisconnect, {GLFW_KEY_DELETE, ""} },
|
||||
{ user_command::nearestcarcoupleradapterattach, {GLFW_KEY_INSERT | keymodifier::control, ""} },
|
||||
{ user_command::nearestcarcoupleradapterremove, {GLFW_KEY_DELETE | keymodifier::control, ""} },
|
||||
{ user_command::occupiedcarcouplingdisconnect, {GLFW_KEY_DELETE | keymodifier::shift, ""} },
|
||||
{ user_command::doortoggleleft, {GLFW_KEY_COMMA, ""} },
|
||||
{ user_command::doortoggleright, {GLFW_KEY_PERIOD, ""} },
|
||||
{ user_command::doorpermitleft, {GLFW_KEY_COMMA | keymodifier::shift, ""} },
|
||||
{ user_command::doorpermitright, {GLFW_KEY_PERIOD | keymodifier::shift, ""} },
|
||||
{ user_command::doorpermitpresetactivatenext, {GLFW_KEY_PERIOD | keymodifier::shift | keymodifier::control, ""} },
|
||||
{ user_command::doorpermitpresetactivateprevious, {GLFW_KEY_COMMA | keymodifier::shift | keymodifier::control, ""} },
|
||||
{ moveleft, {GLFW_KEY_LEFT, "Move left"} },
|
||||
{ moveright, {GLFW_KEY_RIGHT, "Move right"} },
|
||||
{ moveforward, {GLFW_KEY_UP, "Move forwards"} },
|
||||
{ moveback, {GLFW_KEY_DOWN, "Move backwards"} },
|
||||
{ moveup, {GLFW_KEY_PAGE_UP, "Move up"} },
|
||||
{ movedown, {GLFW_KEY_PAGE_DOWN, "Move down"} },
|
||||
{ nearestcarcouplingincrease, {GLFW_KEY_INSERT, ""} },
|
||||
{ nearestcarcouplingdisconnect, {GLFW_KEY_DELETE, ""} },
|
||||
{ nearestcarcoupleradapterattach, {GLFW_KEY_INSERT | keymodifier::control, ""} },
|
||||
{ nearestcarcoupleradapterremove, {GLFW_KEY_DELETE | keymodifier::control, ""} },
|
||||
{ occupiedcarcouplingdisconnect, {GLFW_KEY_DELETE | keymodifier::shift, ""} },
|
||||
{ doortoggleleft, {GLFW_KEY_COMMA, ""} },
|
||||
{ doortoggleright, {GLFW_KEY_PERIOD, ""} },
|
||||
{ doorpermitleft, {GLFW_KEY_COMMA | keymodifier::shift, ""} },
|
||||
{ doorpermitright, {GLFW_KEY_PERIOD | keymodifier::shift, ""} },
|
||||
{ doorpermitpresetactivatenext, {GLFW_KEY_PERIOD | keymodifier::shift | keymodifier::control, ""} },
|
||||
{ doorpermitpresetactivateprevious, {GLFW_KEY_COMMA | keymodifier::shift | keymodifier::control, ""} },
|
||||
// dooropenleft,
|
||||
// dooropenright,
|
||||
{ user_command::dooropenall, {GLFW_KEY_SLASH | keymodifier::shift, ""} },
|
||||
{ dooropenall, {GLFW_KEY_SLASH | keymodifier::shift, ""} },
|
||||
// doorcloseleft,
|
||||
// doorcloseright,
|
||||
{ user_command::doorcloseall, {GLFW_KEY_SLASH | keymodifier::control, ""} },
|
||||
{ doorcloseall, {GLFW_KEY_SLASH | keymodifier::control, ""} },
|
||||
// doorsteptoggle,
|
||||
{ user_command::doormodetoggle, {GLFW_KEY_SLASH | keymodifier::shift | keymodifier::control, ""} },
|
||||
{ doormodetoggle, {GLFW_KEY_SLASH | keymodifier::shift | keymodifier::control, ""} },
|
||||
// mirrorstoggle,
|
||||
{ user_command::departureannounce, {GLFW_KEY_SLASH, ""} },
|
||||
{ user_command::doorlocktoggle, {GLFW_KEY_S | keymodifier::control, ""} },
|
||||
{ user_command::pantographcompressorvalvetoggle, {GLFW_KEY_V | keymodifier::control, ""} },
|
||||
{ departureannounce, {GLFW_KEY_SLASH, ""} },
|
||||
{ doorlocktoggle, {GLFW_KEY_S | keymodifier::control, ""} },
|
||||
{ pantographcompressorvalvetoggle, {GLFW_KEY_V | keymodifier::control, ""} },
|
||||
// pantographcompressorvalveenable,
|
||||
// pantographcompressorvalvedisable,
|
||||
{ user_command::pantographcompressoractivate, {GLFW_KEY_V | keymodifier::shift, ""} },
|
||||
{ user_command::pantographtogglefront, {GLFW_KEY_P, ""} },
|
||||
{ user_command::pantographtogglerear, {GLFW_KEY_O, ""} },
|
||||
{ pantographcompressoractivate, {GLFW_KEY_V | keymodifier::shift, ""} },
|
||||
{ pantographtogglefront, {GLFW_KEY_P, ""} },
|
||||
{ pantographtogglerear, {GLFW_KEY_O, ""} },
|
||||
// pantographraisefront,
|
||||
// pantographraiserear,
|
||||
// pantographlowerfront,
|
||||
// pantographlowerrear,
|
||||
{ user_command::pantographlowerall, {GLFW_KEY_P | keymodifier::control, ""} },
|
||||
{ user_command::pantographselectnext, {GLFW_KEY_P | keymodifier::shift, ""} },
|
||||
{ user_command::pantographselectprevious, {GLFW_KEY_O | keymodifier::shift, ""} },
|
||||
{ user_command::pantographtoggleselected, {GLFW_KEY_O | keymodifier::shift | keymodifier::control, ""} },
|
||||
{ pantographlowerall, {GLFW_KEY_P | keymodifier::control, ""} },
|
||||
{ pantographselectnext, {GLFW_KEY_P | keymodifier::shift, ""} },
|
||||
{ pantographselectprevious, {GLFW_KEY_O | keymodifier::shift, ""} },
|
||||
{ pantographtoggleselected, {GLFW_KEY_O | keymodifier::shift | keymodifier::control, ""} },
|
||||
// pantographraiseselected,
|
||||
// pantographlowerselected,
|
||||
// pantographvalvesupdate,
|
||||
// pantographvalvesoff,
|
||||
{ user_command::heatingtoggle, {GLFW_KEY_H, ""} },
|
||||
{ heatingtoggle, {GLFW_KEY_H, ""} },
|
||||
// heatingenable,
|
||||
// heatingdisable,
|
||||
{ user_command::lightspresetactivatenext, {GLFW_KEY_T | keymodifier::shift, ""} },
|
||||
{ user_command::lightspresetactivateprevious, {GLFW_KEY_T, ""} },
|
||||
{ user_command::headlighttoggleleft, {GLFW_KEY_Y, ""} },
|
||||
{ lightspresetactivatenext, {GLFW_KEY_T | keymodifier::shift, ""} },
|
||||
{ lightspresetactivateprevious, {GLFW_KEY_T, ""} },
|
||||
{ headlighttoggleleft, {GLFW_KEY_Y, ""} },
|
||||
// headlightenableleft,
|
||||
// headlightdisableleft,
|
||||
{ user_command::headlighttoggleright, {GLFW_KEY_I, ""} },
|
||||
{ headlighttoggleright, {GLFW_KEY_I, ""} },
|
||||
// headlightenableright,
|
||||
// headlightdisableright,
|
||||
{ user_command::headlighttoggleupper, {GLFW_KEY_U, ""} },
|
||||
{ headlighttoggleupper, {GLFW_KEY_U, ""} },
|
||||
// headlightenableupper,
|
||||
// headlightdisableupper,
|
||||
{ user_command::redmarkertoggleleft, {GLFW_KEY_Y | keymodifier::shift, ""} },
|
||||
{ redmarkertoggleleft, {GLFW_KEY_Y | keymodifier::shift, ""} },
|
||||
// redmarkerenableleft,
|
||||
// redmarkerdisableleft,
|
||||
{ user_command::redmarkertoggleright, {GLFW_KEY_I | keymodifier::shift, ""} },
|
||||
{ redmarkertoggleright, {GLFW_KEY_I | keymodifier::shift, ""} },
|
||||
// redmarkerenableright,
|
||||
// redmarkerdisableright,
|
||||
{ user_command::headlighttogglerearleft, {GLFW_KEY_Y | keymodifier::control, ""} },
|
||||
{ headlighttogglerearleft, {GLFW_KEY_Y | keymodifier::control, ""} },
|
||||
// headlightenablerearleft
|
||||
// headlightdisablerearleft
|
||||
{ user_command::headlighttogglerearright, {GLFW_KEY_I | keymodifier::control, ""} },
|
||||
{ headlighttogglerearright, {GLFW_KEY_I | keymodifier::control, ""} },
|
||||
// headlightenablerearright
|
||||
// headlightdisablerearright
|
||||
{ user_command::headlighttogglerearupper, {GLFW_KEY_U | keymodifier::control, ""} },
|
||||
{ headlighttogglerearupper, {GLFW_KEY_U | keymodifier::control, ""} },
|
||||
// headlightenablerearupper
|
||||
// headlightdisablerearupper
|
||||
{ user_command::redmarkertogglerearleft, {GLFW_KEY_Y | keymodifier::control | keymodifier::shift, ""} },
|
||||
{ redmarkertogglerearleft, {GLFW_KEY_Y | keymodifier::control | keymodifier::shift, ""} },
|
||||
// redmarkerenablerearleft
|
||||
// redmarkerdisablerearleft
|
||||
{ user_command::redmarkertogglerearright, {GLFW_KEY_I | keymodifier::control | keymodifier::shift, ""} },
|
||||
{ redmarkertogglerearright, {GLFW_KEY_I | keymodifier::control | keymodifier::shift, ""} },
|
||||
// redmarkerenablerearright
|
||||
// redmarkerdisablerearright
|
||||
{ user_command::redmarkerstoggle, {GLFW_KEY_E | keymodifier::shift, ""} },
|
||||
{ user_command::endsignalstoggle, {GLFW_KEY_E, ""} },
|
||||
{ user_command::headlightsdimtoggle, {GLFW_KEY_L | keymodifier::control, ""} },
|
||||
{ redmarkerstoggle, {GLFW_KEY_E | keymodifier::shift, ""} },
|
||||
{ endsignalstoggle, {GLFW_KEY_E, ""} },
|
||||
{ headlightsdimtoggle, {GLFW_KEY_L | keymodifier::control, ""} },
|
||||
// headlightsdimenable,
|
||||
// headlightsdimdisable,
|
||||
{ user_command::motorconnectorsopen, {GLFW_KEY_L, ""} },
|
||||
{ motorconnectorsopen, {GLFW_KEY_L, ""} },
|
||||
// motorconnectorsclose,
|
||||
{ user_command::motordisconnect, {GLFW_KEY_E | keymodifier::control, ""} },
|
||||
{ user_command::interiorlighttoggle, {GLFW_KEY_APOSTROPHE, ""} },
|
||||
{ motordisconnect, {GLFW_KEY_E | keymodifier::control, ""} },
|
||||
{ interiorlighttoggle, {GLFW_KEY_APOSTROPHE, ""} },
|
||||
// interiorlightenable,
|
||||
// interiorlightdisable,
|
||||
{ user_command::interiorlightdimtoggle, {GLFW_KEY_APOSTROPHE | keymodifier::control, ""} },
|
||||
{ interiorlightdimtoggle, {GLFW_KEY_APOSTROPHE | keymodifier::control, ""} },
|
||||
// interiorlightdimenable,
|
||||
// interiorlightdimdisable,
|
||||
// compartmentlightstoggle,
|
||||
// compartmentlightsenable,
|
||||
// compartmentlightsdisable,
|
||||
{ user_command::instrumentlighttoggle, {GLFW_KEY_SEMICOLON, ""} },
|
||||
{ instrumentlighttoggle, {GLFW_KEY_SEMICOLON, ""} },
|
||||
// instrumentlightenable,
|
||||
// instrumentlightdisable,
|
||||
{ user_command::dashboardlighttoggle, {GLFW_KEY_SEMICOLON | keymodifier::shift, ""} },
|
||||
{ dashboardlighttoggle, {GLFW_KEY_SEMICOLON | keymodifier::shift, ""} },
|
||||
// dashboardlightenable
|
||||
// dashboardlightdisable
|
||||
{ user_command::timetablelighttoggle, {GLFW_KEY_APOSTROPHE | keymodifier::shift, ""} },
|
||||
{ timetablelighttoggle, {GLFW_KEY_APOSTROPHE | keymodifier::shift, ""} },
|
||||
// timetablelightenable
|
||||
// timetablelightdisable
|
||||
{ user_command::generictoggle0, {GLFW_KEY_0, ""} },
|
||||
{ user_command::generictoggle1, {GLFW_KEY_1, ""} },
|
||||
{ user_command::generictoggle2, {GLFW_KEY_2, ""} },
|
||||
{ user_command::generictoggle3, {GLFW_KEY_3, ""} },
|
||||
{ user_command::generictoggle4, {GLFW_KEY_4, ""} },
|
||||
{ user_command::generictoggle5, {GLFW_KEY_5, ""} },
|
||||
{ user_command::generictoggle6, {GLFW_KEY_6, ""} },
|
||||
{ user_command::generictoggle7, {GLFW_KEY_7, ""} },
|
||||
{ user_command::generictoggle8, {GLFW_KEY_8, ""} },
|
||||
{ user_command::generictoggle9, {GLFW_KEY_9, ""} },
|
||||
{ user_command::batterytoggle, {GLFW_KEY_J, ""} },
|
||||
{ generictoggle0, {GLFW_KEY_0, ""} },
|
||||
{ generictoggle1, {GLFW_KEY_1, ""} },
|
||||
{ generictoggle2, {GLFW_KEY_2, ""} },
|
||||
{ generictoggle3, {GLFW_KEY_3, ""} },
|
||||
{ generictoggle4, {GLFW_KEY_4, ""} },
|
||||
{ generictoggle5, {GLFW_KEY_5, ""} },
|
||||
{ generictoggle6, {GLFW_KEY_6, ""} },
|
||||
{ generictoggle7, {GLFW_KEY_7, ""} },
|
||||
{ generictoggle8, {GLFW_KEY_8, ""} },
|
||||
{ generictoggle9, {GLFW_KEY_9, ""} },
|
||||
{ batterytoggle, {GLFW_KEY_J, ""} },
|
||||
// batteryenable,
|
||||
// batterydisable,
|
||||
// cabactivationtoggle,
|
||||
// cabactivationenable,
|
||||
// cabactivationdisable,
|
||||
{ user_command::motorblowerstogglefront, {GLFW_KEY_N | keymodifier::shift, ""} },
|
||||
{ user_command::motorblowerstogglerear, {GLFW_KEY_M | keymodifier::shift, ""} },
|
||||
{ user_command::motorblowersdisableall, {GLFW_KEY_M | keymodifier::control, ""} },
|
||||
{ motorblowerstogglefront, {GLFW_KEY_N | keymodifier::shift, ""} },
|
||||
{ motorblowerstogglerear, {GLFW_KEY_M | keymodifier::shift, ""} },
|
||||
{ motorblowersdisableall, {GLFW_KEY_M | keymodifier::control, ""} },
|
||||
// coolingfanstoggle,
|
||||
// tempomattoggle,
|
||||
// springbraketoggle,
|
||||
@@ -317,14 +318,14 @@ driverkeyboard_input::default_bindings() {
|
||||
// speedcontrolbutton8,
|
||||
// speedcontrolbutton9,
|
||||
// admin_timejump,
|
||||
{ user_command::timejumplarge, {GLFW_KEY_F1 | keymodifier::control, "Big time jump (Debug Mode only)"} },
|
||||
{ user_command::timejumpsmall, {GLFW_KEY_F1 | keymodifier::shift, "Small time jump (Debug Mode only)"} },
|
||||
{ timejumplarge, {GLFW_KEY_F1 | keymodifier::control, "Big time jump (Debug Mode only)"} },
|
||||
{ timejumpsmall, {GLFW_KEY_F1 | keymodifier::shift, "Small time jump (Debug Mode only)"} },
|
||||
// admin_vehiclemove,
|
||||
{ user_command::vehiclemoveforwards, {GLFW_KEY_LEFT_BRACKET | keymodifier::control, "Move the train forwards (Debug Mode only)"} },
|
||||
{ user_command::vehiclemovebackwards, {GLFW_KEY_RIGHT_BRACKET | keymodifier::control, "Move the train backwards (Debug Mode only)"} },
|
||||
{ user_command::vehicleboost, {GLFW_KEY_TAB | keymodifier::control, "Boost the train (Debug Mode only)"} },
|
||||
{ user_command::debugtoggle, {GLFW_KEY_F12 | keymodifier::control | keymodifier::shift, "Toggle Debug Mode"} },
|
||||
{ user_command::pausetoggle, {GLFW_KEY_ESCAPE, "Pause the game"} }
|
||||
{ vehiclemoveforwards, {GLFW_KEY_LEFT_BRACKET | keymodifier::control, "Move the train forwards (Debug Mode only)"} },
|
||||
{ vehiclemovebackwards, {GLFW_KEY_RIGHT_BRACKET | keymodifier::control, "Move the train backwards (Debug Mode only)"} },
|
||||
{ vehicleboost, {GLFW_KEY_TAB | keymodifier::control, "Boost the train (Debug Mode only)"} },
|
||||
{ debugtoggle, {GLFW_KEY_F12 | keymodifier::control | keymodifier::shift, "Toggle Debug Mode"} },
|
||||
{ pausetoggle, {GLFW_KEY_ESCAPE, "Pause the game"} }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
protected:
|
||||
// methods
|
||||
void
|
||||
default_bindings();
|
||||
default_bindings() override;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -84,14 +84,14 @@ private:
|
||||
user_command down;
|
||||
};
|
||||
|
||||
typedef std::unordered_map<std::string, button_bindings> buttonbindings_map;
|
||||
using buttonbindings_map = std::unordered_map<std::string, button_bindings>;
|
||||
|
||||
// methods
|
||||
void
|
||||
default_bindings();
|
||||
// potentially replaces supplied command with a more relevant one
|
||||
user_command
|
||||
adjust_command( user_command Command );
|
||||
adjust_command( user_command Command ) const;
|
||||
|
||||
// members
|
||||
command_relay m_relay;
|
||||
|
||||
@@ -31,25 +31,26 @@ editorkeyboard_input::apply_scheme() {
|
||||
|
||||
void
|
||||
editorkeyboard_input::default_bindings() {
|
||||
using enum user_command;
|
||||
|
||||
if (EditorSettings.movement() == editorSettings::movement_scheme::legacy) {
|
||||
m_bindingsetups = {
|
||||
{ user_command::moveleft, {GLFW_KEY_LEFT, "Move left"} },
|
||||
{ user_command::moveright, {GLFW_KEY_RIGHT, "Move right"} },
|
||||
{ user_command::moveforward, {GLFW_KEY_UP, "Move forwards"} },
|
||||
{ user_command::moveback, {GLFW_KEY_DOWN, "Move backwards"} },
|
||||
{ user_command::moveup, {GLFW_KEY_PAGE_UP, "Move up"} },
|
||||
{ user_command::movedown, {GLFW_KEY_PAGE_DOWN, "Move down"} },
|
||||
{ moveleft, {GLFW_KEY_LEFT, "Move left"} },
|
||||
{ moveright, {GLFW_KEY_RIGHT, "Move right"} },
|
||||
{ moveforward, {GLFW_KEY_UP, "Move forwards"} },
|
||||
{ moveback, {GLFW_KEY_DOWN, "Move backwards"} },
|
||||
{ moveup, {GLFW_KEY_PAGE_UP, "Move up"} },
|
||||
{ movedown, {GLFW_KEY_PAGE_DOWN, "Move down"} },
|
||||
};
|
||||
}
|
||||
else {
|
||||
m_bindingsetups = {
|
||||
{ user_command::moveleft, {GLFW_KEY_A, "Move left"} },
|
||||
{ user_command::moveright, {GLFW_KEY_D, "Move right"} },
|
||||
{ user_command::moveforward, {GLFW_KEY_W, "Move forwards"} },
|
||||
{ user_command::moveback, {GLFW_KEY_S, "Move backwards"} },
|
||||
{ user_command::moveup, {GLFW_KEY_E, "Move up"} },
|
||||
{ user_command::movedown, {GLFW_KEY_Q, "Move down"} },
|
||||
{ moveleft, {GLFW_KEY_A, "Move left"} },
|
||||
{ moveright, {GLFW_KEY_D, "Move right"} },
|
||||
{ moveforward, {GLFW_KEY_W, "Move forwards"} },
|
||||
{ moveback, {GLFW_KEY_S, "Move backwards"} },
|
||||
{ moveup, {GLFW_KEY_E, "Move up"} },
|
||||
{ movedown, {GLFW_KEY_Q, "Move down"} },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,8 +51,7 @@ gamepad_input::init() {
|
||||
m_inputbuttons.clear();
|
||||
// NOTE: we're only checking for joystick_1 and rely for it to stay connected throughout.
|
||||
// not exactly flexible, but for quick hack it'll do
|
||||
auto const name = glfwGetJoystickName( GLFW_JOYSTICK_1 );
|
||||
if( name != nullptr ) {
|
||||
if( auto const name = glfwGetJoystickName( GLFW_JOYSTICK_1 ); name != nullptr ) {
|
||||
WriteLog( "Connected gamepad: " + std::string( name ) );
|
||||
m_deviceid = GLFW_JOYSTICK_1;
|
||||
}
|
||||
@@ -94,7 +93,7 @@ gamepad_input::poll() {
|
||||
if( button.state != buttons[ idx ] ) {
|
||||
// button pressed or released, both are important
|
||||
on_button(
|
||||
idx,
|
||||
static_cast<int>(idx),
|
||||
buttons[idx] == 1 ? GLFW_PRESS : GLFW_RELEASE);
|
||||
}
|
||||
else {
|
||||
@@ -102,7 +101,7 @@ gamepad_input::poll() {
|
||||
if( button.state == GLFW_PRESS ) {
|
||||
|
||||
on_button(
|
||||
idx,
|
||||
static_cast<int>(idx),
|
||||
GLFW_REPEAT );
|
||||
}
|
||||
}
|
||||
@@ -125,9 +124,9 @@ gamepad_input::poll() {
|
||||
}
|
||||
|
||||
void
|
||||
gamepad_input::bind( std::vector< std::reference_wrapper<user_command> > &Targets, cParser &Input, std::unordered_map<std::string, user_command> const &Translator, std::string const Point ) {
|
||||
gamepad_input::bind( std::vector< std::reference_wrapper<user_command> > const &Targets, cParser &Input, std::unordered_map<std::string, user_command> const &Translator, std::string const &Point ) const {
|
||||
|
||||
for( auto &bindingtarget : Targets ) {
|
||||
for( auto const &bindingtarget : Targets ) {
|
||||
// grab command(s) associated with the input pin
|
||||
auto const bindingcommandname{ Input.getToken<std::string>() };
|
||||
if( true == bindingcommandname.empty() ) {
|
||||
@@ -154,12 +153,11 @@ bool
|
||||
gamepad_input::recall_bindings() {
|
||||
std::string filePath = "eu07_input-gamepad.ini";
|
||||
|
||||
fs::path appPath = user_config_path("eu07_input-gamepad.ini");
|
||||
if (!appPath.empty() && fs::exists(appPath))
|
||||
if (fs::path appPath = user_config_path("eu07_input-gamepad.ini"); !appPath.empty() && fs::exists(appPath))
|
||||
filePath = appPath.string();
|
||||
|
||||
// bindingparser tworzony zawsze, z wybran<61> <20>cie<69>k<EFBFBD>
|
||||
cParser bindingparser(filePath.c_str(), cParser::buffer_FILE);
|
||||
cParser bindingparser(filePath, cParser::buffer_FILE);
|
||||
|
||||
if( false == bindingparser.ok() ) {
|
||||
return false;
|
||||
@@ -169,7 +167,7 @@ gamepad_input::recall_bindings() {
|
||||
std::unordered_map<std::string, user_command> nametocommandmap;
|
||||
std::size_t commandid = 0;
|
||||
for( auto const &description : simulation::Commands_descriptions ) {
|
||||
nametocommandmap.emplace(
|
||||
nametocommandmap.try_emplace(
|
||||
description.name,
|
||||
static_cast<user_command>( commandid ) );
|
||||
++commandid;
|
||||
@@ -191,16 +189,16 @@ gamepad_input::recall_bindings() {
|
||||
|
||||
std::string bindingpoint {};
|
||||
entryparser >> bindingpoint;
|
||||
auto const splitbindingpoint { split_string_and_number( bindingpoint ) };
|
||||
auto const [pointtype, pointindex]{ split_string_and_number( bindingpoint ) };
|
||||
|
||||
if( splitbindingpoint.first == "axis" ) {
|
||||
if( pointtype == "axis" ) {
|
||||
// one or more sets of: [modeIDX] input type, parameters
|
||||
// [optional] modeIDX associates the set with control mode IDX
|
||||
// input types:
|
||||
// -- range commandname IDX; axis value is passed as paramIDX of commandname
|
||||
// -- 3state commandname commandname; positive axis value issues first commandname, negative value issues second commandname
|
||||
|
||||
auto const axisindex { splitbindingpoint.second };
|
||||
auto const axisindex { pointindex };
|
||||
// sanity check, connected gamepad isn't guaranteed to have that many axes
|
||||
if( axisindex >= m_inputaxes.size() ) { continue; }
|
||||
|
||||
@@ -211,8 +209,7 @@ gamepad_input::recall_bindings() {
|
||||
std::string key {};
|
||||
entryparser >> key;
|
||||
// check for potential mode indicator
|
||||
auto const splitkey { split_string_and_number( key ) };
|
||||
if( splitkey.first == "mode" ) {
|
||||
if( auto const splitkey { split_string_and_number( key ) }; splitkey.first == "mode" ) {
|
||||
// indicate we'll be processing specified mode
|
||||
controlmode = splitkey.second;
|
||||
continue;
|
||||
@@ -231,12 +228,13 @@ gamepad_input::recall_bindings() {
|
||||
std::get<0>( m_inputaxes[ axisindex ].bindings[ controlmode ] ) = bindingtype;
|
||||
// retrieve regular commands associated with the axis and mode
|
||||
switch( bindingtype ) {
|
||||
case input_type::value:
|
||||
case input_type::value_invert: {
|
||||
using enum gamepad_input::input_type;
|
||||
case value:
|
||||
case value_invert: {
|
||||
bindingtargets.emplace_back( std::ref( std::get<1>( m_inputaxes[ axisindex ].bindings[ controlmode ] ) ) );
|
||||
break;
|
||||
}
|
||||
case input_type::threestate: {
|
||||
case threestate: {
|
||||
bindingtargets.emplace_back( std::ref( std::get<1>( m_inputaxes[ axisindex ].bindings[ controlmode ] ) ) );
|
||||
bindingtargets.emplace_back( std::ref( std::get<2>( m_inputaxes[ axisindex ].bindings[ controlmode ] ) ) );
|
||||
break;
|
||||
@@ -267,9 +265,9 @@ gamepad_input::recall_bindings() {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( splitbindingpoint.first == "button" ) {
|
||||
else if( pointtype == "button" ) {
|
||||
|
||||
auto const buttonindex { splitbindingpoint.second };
|
||||
auto const buttonindex { pointindex };
|
||||
// sanity check, connected gamepad isn't guaranteed to have that many buttons
|
||||
if( buttonindex >= m_inputbuttons.size() ) { continue; }
|
||||
|
||||
@@ -345,7 +343,8 @@ void
|
||||
gamepad_input::process_axes() {
|
||||
|
||||
input_type inputtype;
|
||||
user_command boundcommand1, boundcommand2;
|
||||
user_command boundcommand1;
|
||||
user_command boundcommand2;
|
||||
auto binding { std::tie( inputtype, boundcommand1, boundcommand2 ) };
|
||||
|
||||
// since some commands can potentially collect values from two different axes we can't post them directly
|
||||
@@ -369,20 +368,18 @@ gamepad_input::process_axes() {
|
||||
auto const deltatime { Timer::GetDeltaTime() * 15.0 };
|
||||
if( axis.state >= 0.0f ) {
|
||||
// first bound command selected
|
||||
if( axis.accumulator < 0.0f ) {
|
||||
// we were issuing the other command, post notification that's no longer the case
|
||||
if( boundcommand2 != user_command::none ) {
|
||||
m_relay.post(
|
||||
boundcommand2,
|
||||
0, 0,
|
||||
GLFW_RELEASE,
|
||||
0 );
|
||||
axis.accumulator = 0.0f;
|
||||
}
|
||||
// we were issuing the other command, post notification that's no longer the case
|
||||
if (axis.accumulator < 0.0f && boundcommand2 != user_command::none) {
|
||||
m_relay.post(
|
||||
boundcommand2,
|
||||
0, 0,
|
||||
GLFW_RELEASE,
|
||||
0 );
|
||||
axis.accumulator = 0.0f;
|
||||
}
|
||||
if( boundcommand1 != user_command::none ) {
|
||||
if( axis.state > m_deadzone ) {
|
||||
axis.accumulator += ( axis.state - m_deadzone ) / ( 1.0 - m_deadzone ) * deltatime;
|
||||
axis.accumulator += static_cast<float>(( axis.state - m_deadzone ) / ( 1.0 - m_deadzone ) * deltatime);
|
||||
// we're making sure there's always a positive charge left in the accumulator,
|
||||
// to more reliably decect when the stick goes from active to dead zone, below
|
||||
while( axis.accumulator > 1.0f ) {
|
||||
@@ -409,20 +406,18 @@ gamepad_input::process_axes() {
|
||||
}
|
||||
else {
|
||||
// second bound command selected
|
||||
if( axis.accumulator > 0.0f ) {
|
||||
// we were issuing the other command, post notification that's no longer the case
|
||||
if( boundcommand1 != user_command::none ) {
|
||||
m_relay.post(
|
||||
boundcommand1,
|
||||
0, 0,
|
||||
GLFW_RELEASE,
|
||||
0 );
|
||||
axis.accumulator = 0.0f;
|
||||
}
|
||||
// we were issuing the other command, post notification that's no longer the case
|
||||
if (axis.accumulator > 0.0f && boundcommand1 != user_command::none) {
|
||||
m_relay.post(
|
||||
boundcommand1,
|
||||
0, 0,
|
||||
GLFW_RELEASE,
|
||||
0 );
|
||||
axis.accumulator = 0.0f;
|
||||
}
|
||||
if( boundcommand1 != user_command::none ) {
|
||||
if( axis.state < -m_deadzone ) {
|
||||
axis.accumulator += ( axis.state + m_deadzone ) / ( 1.0 - m_deadzone ) * deltatime;
|
||||
axis.accumulator += static_cast<float>(( axis.state + m_deadzone ) / ( 1.0 - m_deadzone ) * deltatime);
|
||||
// we're making sure there's always a positive charge left in the accumulator,
|
||||
// to more reliably decect when the stick goes from active to dead zone, below
|
||||
while( axis.accumulator < -1.0f ) {
|
||||
@@ -464,19 +459,18 @@ gamepad_input::process_axes() {
|
||||
else {
|
||||
param = param > 0.0 ? (param - m_deadzone) / (1.0 - m_deadzone) : (param + m_deadzone) / (1.0 - m_deadzone);
|
||||
}
|
||||
if( param != 0.0 ) {
|
||||
if( inputtype == input_type::value_invert ) {
|
||||
param *= -1.0;
|
||||
}
|
||||
if (param != 0.0 && inputtype == input_type::value_invert) {
|
||||
param *= -1.0;
|
||||
}
|
||||
// scale passed value according to command type
|
||||
switch( boundcommand1 ) {
|
||||
case user_command::viewturn: {
|
||||
using enum user_command;
|
||||
case viewturn: {
|
||||
param *= 10.0 * ( Timer::GetDeltaRenderTime() * 60.0 );
|
||||
break;
|
||||
}
|
||||
case user_command::movehorizontal:
|
||||
case user_command::movehorizontalfast: {
|
||||
case movehorizontal:
|
||||
case movehorizontalfast: {
|
||||
// these expect value in -1:1 range
|
||||
break;
|
||||
}
|
||||
@@ -494,17 +488,17 @@ gamepad_input::process_axes() {
|
||||
}
|
||||
}
|
||||
// issue remaining, assembled commands
|
||||
for( auto const &command : commands ) {
|
||||
auto const param1 { std::get<0>( command.second ) };
|
||||
auto const param2 { std::get<1>( command.second ) };
|
||||
auto &lastparams { m_lastcommandparams[ command.first ] };
|
||||
for( auto const &[commandid, commandparams] : commands ) {
|
||||
auto const param1 { std::get<0>( commandparams ) };
|
||||
auto const param2 { std::get<1>( commandparams ) };
|
||||
auto &lastparams { m_lastcommandparams[ commandid ] };
|
||||
if( param1 != 0.0 || std::get<0>(lastparams) != 0.0
|
||||
|| param2 != 0.0 || std::get<1>(lastparams) != 0.0 ) {
|
||||
m_relay.post(
|
||||
command.first,
|
||||
commandid,
|
||||
param1,
|
||||
param2,
|
||||
std::get<2>( command.second ),
|
||||
std::get<2>( commandparams ),
|
||||
// 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
|
||||
0 );
|
||||
|
||||
@@ -77,7 +77,7 @@ private:
|
||||
using inputaxis_sequence = std::vector<input_axis>;
|
||||
// methods
|
||||
bool recall_bindings();
|
||||
void bind( std::vector< std::reference_wrapper<user_command> > &Targets, cParser &Input, std::unordered_map<std::string, user_command> const &Translator, std::string const Point );
|
||||
void bind( std::vector< std::reference_wrapper<user_command> > const &Targets, cParser &Input, std::unordered_map<std::string, user_command> const &Translator, std::string const &Point ) const;
|
||||
void on_button( int const Button, int const Action );
|
||||
void process_axes();
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ keyboard_input::recall_bindings() {
|
||||
// Fallback <20> plik w folderze symulatora
|
||||
path = "eu07_input-keyboard.ini";
|
||||
}
|
||||
cParser bindingparser(path.c_str(), cParser::buffer_FILE);
|
||||
cParser bindingparser(path, cParser::buffer_FILE);
|
||||
|
||||
bindingparser.skipComments = false;
|
||||
if( false == bindingparser.ok() ) {
|
||||
@@ -147,7 +147,7 @@ keyboard_input::recall_bindings() {
|
||||
std::unordered_map<std::string, user_command> nametocommandmap;
|
||||
std::size_t commandid = 0;
|
||||
for( auto const &description : simulation::Commands_descriptions ) {
|
||||
nametocommandmap.emplace(
|
||||
nametocommandmap.try_emplace(
|
||||
description.name,
|
||||
static_cast<user_command>( commandid ) );
|
||||
++commandid;
|
||||
@@ -155,7 +155,7 @@ keyboard_input::recall_bindings() {
|
||||
std::unordered_map<std::string, int> nametokeymap;
|
||||
|
||||
for (const std::pair<int, std::string> &key : keytonamemap) {
|
||||
nametokeymap.emplace(key.second, key.first);
|
||||
nametokeymap.try_emplace(key.second, key.first);
|
||||
}
|
||||
|
||||
// NOTE: to simplify things we expect one entry per line, and whole entry in one line
|
||||
@@ -225,7 +225,7 @@ keyboard_input::recall_bindings() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void keyboard_input::dump_bindings()
|
||||
void keyboard_input::dump_bindings() const
|
||||
{
|
||||
std::fstream stream("eu07_input-keyboard.ini",
|
||||
std::ios_base::binary | std::ios_base::trunc | std::ios_base::out);
|
||||
@@ -239,8 +239,7 @@ void keyboard_input::dump_bindings()
|
||||
stream << simulation::Commands_descriptions[static_cast<std::size_t>(binding.first)].name << ' ';
|
||||
|
||||
int keycode = std::get<int>(binding.second);
|
||||
auto it = keytonamemap.find(keycode & 0xFFFF);
|
||||
if (it != keytonamemap.end()) {
|
||||
if (auto it = keytonamemap.find(keycode & 0xFFFF); it != keytonamemap.end()) {
|
||||
if (keycode & keymodifier::control)
|
||||
stream << "ctrl ";
|
||||
if (keycode & keymodifier::shift)
|
||||
@@ -284,7 +283,7 @@ keyboard_input::key( int const Key, int const Action ) {
|
||||
if( Key == -1 ) { return false; }
|
||||
|
||||
// store key state
|
||||
input::keys[ Key ] = Action;
|
||||
input::keys[ Key ] = static_cast<char>( Action );
|
||||
|
||||
if( true == is_movement_key( Key ) ) {
|
||||
// if the received key was one of movement keys, it's been handled and we don't need to bother further
|
||||
@@ -298,8 +297,7 @@ keyboard_input::key( int const Key, int const Action ) {
|
||||
| ( modifier ? 0 : input::key_ctrl ? keymodifier::control : 0 );
|
||||
|
||||
if( Action == GLFW_RELEASE ) {
|
||||
auto const stored = m_modsforkeys.find( Key );
|
||||
if( stored != m_modsforkeys.end() ) {
|
||||
if( auto const stored = m_modsforkeys.find( Key ); stored != m_modsforkeys.end() ) {
|
||||
key = stored->second;
|
||||
}
|
||||
m_modsforkeys.erase( Key );
|
||||
@@ -330,28 +328,29 @@ keyboard_input::key( int const Key ) const {
|
||||
|
||||
void
|
||||
keyboard_input::bind() {
|
||||
using enum user_command;
|
||||
m_bindings.clear();
|
||||
|
||||
for( auto const &bindingsetup : m_bindingsetups ) {
|
||||
for( auto const &[setupcommand, setupbinding] : m_bindingsetups ) {
|
||||
|
||||
m_bindings[ std::get<int>(bindingsetup.second) ] = bindingsetup.first;
|
||||
m_bindings[ std::get<int>(setupbinding) ] = setupcommand;
|
||||
}
|
||||
|
||||
// cache movement key bindings
|
||||
m_bindingscache.forward = binding( user_command::moveforward );
|
||||
m_bindingscache.back = binding( user_command::moveback );
|
||||
m_bindingscache.left = binding( user_command::moveleft );
|
||||
m_bindingscache.right = binding( user_command::moveright );
|
||||
m_bindingscache.up = binding( user_command::moveup );
|
||||
m_bindingscache.down = binding( user_command::movedown );
|
||||
m_bindingscache.forward = binding( moveforward );
|
||||
m_bindingscache.back = binding( moveback );
|
||||
m_bindingscache.left = binding( moveleft );
|
||||
m_bindingscache.right = binding( moveright );
|
||||
m_bindingscache.up = binding( moveup );
|
||||
m_bindingscache.down = binding( movedown );
|
||||
}
|
||||
|
||||
int
|
||||
keyboard_input::binding( user_command const Command ) const {
|
||||
|
||||
for( auto const &binding : m_bindings ) {
|
||||
if( binding.second == Command ) {
|
||||
return binding.first;
|
||||
for( auto const &[bindingkey, bindingcommand] : m_bindings ) {
|
||||
if( bindingcommand == Command ) {
|
||||
return bindingkey;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@@ -413,7 +412,7 @@ keyboard_input::poll() {
|
||||
m_movementvertical = movementvertical;
|
||||
}
|
||||
|
||||
std::unordered_map<int, std::string> keytonamemap = {
|
||||
std::unordered_map<int, std::string> const keytonamemap = {
|
||||
{ GLFW_KEY_0, "0" }, { GLFW_KEY_1, "1" }, { GLFW_KEY_2, "2" }, { GLFW_KEY_3, "3" }, { GLFW_KEY_4, "4" },
|
||||
{ GLFW_KEY_5, "5" }, { GLFW_KEY_6, "6" }, { GLFW_KEY_7, "7" }, { GLFW_KEY_8, "8" }, { GLFW_KEY_9, "9" },
|
||||
{ GLFW_KEY_MINUS, "-" }, { GLFW_KEY_EQUAL, "=" },
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
void
|
||||
poll();
|
||||
inline
|
||||
user_command const
|
||||
user_command
|
||||
command() const {
|
||||
return m_command; }
|
||||
bindingsetup_sequence&
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
std::string
|
||||
binding_hint( user_command const Command ) const;
|
||||
void
|
||||
dump_bindings();
|
||||
dump_bindings() const;
|
||||
|
||||
// members
|
||||
static std::unordered_map<int, std::string> keytonamemap;
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace multiplayer {
|
||||
std::uint32_t const EU07_MESSAGEHEADER { MAKE_ID4( 'E','U','0','7' ) };
|
||||
|
||||
void
|
||||
Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam) {
|
||||
Navigate([[maybe_unused]] std::string const &ClassName, [[maybe_unused]] UINT Msg, [[maybe_unused]] WPARAM wParam, [[maybe_unused]] LPARAM lParam) {
|
||||
#ifdef _WIN32
|
||||
// wysłanie komunikatu do sterującego
|
||||
HWND h = FindWindow(ClassName.c_str(), 0); // można by to zapamiętać
|
||||
@@ -43,7 +43,7 @@ Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam) {
|
||||
}
|
||||
|
||||
void
|
||||
OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
||||
OnCommandGet(multiplayer::DaneRozkaz const *pRozkaz)
|
||||
{ // odebranie komunikatu z serwera
|
||||
if (pRozkaz->iSygn == EU07_MESSAGEHEADER )
|
||||
switch (pRozkaz->iComm)
|
||||
@@ -62,15 +62,13 @@ OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
||||
std::string( pRozkaz->cString + 1, (unsigned)pRozkaz->cString[0] ) + " rcvd" );
|
||||
|
||||
if( Global.iMultiplayer ) {
|
||||
auto *event = simulation::Events.FindEvent( std::string( pRozkaz->cString + 1, (unsigned)pRozkaz->cString[0] ) );
|
||||
if( event != nullptr ) {
|
||||
if( typeid(*event) == typeid(multi_event)
|
||||
|| typeid(*event) == typeid(lights_event)
|
||||
|| event->m_sibling != 0 ) {
|
||||
// tylko jawne albo niejawne Multiple
|
||||
command_relay relay;
|
||||
relay.post(user_command::queueevent, 0.0, 0.0, GLFW_PRESS, 0, glm::vec3(0.0f), &event->name());
|
||||
}
|
||||
auto const *foundevent = simulation::Events.FindEvent( std::string( pRozkaz->cString + 1, (unsigned)pRozkaz->cString[0] ) );
|
||||
if (foundevent != nullptr && (typeid(*foundevent) == typeid(multi_event)
|
||||
|| typeid(*foundevent) == typeid(lights_event)
|
||||
|| foundevent->m_sibling != nullptr)) {
|
||||
// tylko jawne albo niejawne Multiple
|
||||
command_relay commandrelay;
|
||||
commandrelay.post(user_command::queueevent, 0.0, 0.0, GLFW_PRESS, 0, glm::vec3(0.0f), &foundevent->name());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -78,7 +76,7 @@ OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
||||
case 3: // rozkaz dla AI
|
||||
if (Global.iMultiplayer)
|
||||
{
|
||||
int i = int(pRozkaz->cString[8]); // długość pierwszego łańcucha (z przodu dwa floaty)
|
||||
auto i = int(pRozkaz->cString[8]); // długość pierwszego łańcucha (z przodu dwa floaty)
|
||||
CommLog(
|
||||
Now() + " " + std::to_string(pRozkaz->iComm) + " " +
|
||||
std::string(pRozkaz->cString + 11 + i, (unsigned)pRozkaz->cString[10 + i]) +
|
||||
@@ -110,21 +108,21 @@ OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
||||
break;
|
||||
case 5: // ustawienie parametrów
|
||||
{
|
||||
CommLog(Now() + " " + std::to_string(pRozkaz->iComm) + " params " + std::to_string(*pRozkaz->iPar) + " rcvd");
|
||||
if (*pRozkaz->iPar == 0) // sprawdzenie czasu
|
||||
if (*pRozkaz->iPar & 1) // ustawienie czasu
|
||||
{
|
||||
auto t = pRozkaz->fPar[1];
|
||||
simulation::Time.data().wDay = std::floor(t); // niby nie powinno być dnia, ale...
|
||||
if (Global.fMoveLight >= 0)
|
||||
Global.fMoveLight = t; // trzeba by deklinację Słońca przeliczyć
|
||||
simulation::Time.data().wHour = std::floor(24 * t) - 24.0 * simulation::Time.data().wDay;
|
||||
simulation::Time.data().wMinute = std::floor(60 * 24 * t) - 60.0 * (24.0 * simulation::Time.data().wDay + simulation::Time.data().wHour);
|
||||
simulation::Time.data().wSecond = std::floor( 60 * 60 * 24 * t ) - 60.0 * ( 60.0 * ( 24.0 * simulation::Time.data().wDay + simulation::Time.data().wHour ) + simulation::Time.data().wMinute );
|
||||
}
|
||||
if (*pRozkaz->iPar & 2)
|
||||
CommLog(Now() + " " + std::to_string(pRozkaz->iComm) + " params " + std::to_string(pRozkaz->iPar[0]) + " rcvd");
|
||||
// sprawdzenie czasu
|
||||
if (pRozkaz->iPar[0] == 0 && pRozkaz->iPar[0] & 1) // ustawienie czasu
|
||||
{
|
||||
auto t = pRozkaz->fPar[1];
|
||||
simulation::Time.data().wDay = static_cast<uint16_t>(std::floor(t)); // niby nie powinno być dnia, ale...
|
||||
if (Global.fMoveLight >= 0)
|
||||
Global.fMoveLight = t; // trzeba by deklinację Słońca przeliczyć
|
||||
simulation::Time.data().wHour = static_cast<uint16_t>(std::floor(24 * t) - 24.0 * simulation::Time.data().wDay);
|
||||
simulation::Time.data().wMinute = static_cast<uint16_t>(std::floor(60 * 24 * t) - 60.0 * (24.0 * simulation::Time.data().wDay + simulation::Time.data().wHour));
|
||||
simulation::Time.data().wSecond = static_cast<uint16_t>(std::floor( 60 * 60 * 24 * t ) - 60.0 * ( 60.0 * ( 24.0 * simulation::Time.data().wDay + simulation::Time.data().wHour ) + simulation::Time.data().wMinute ));
|
||||
}
|
||||
if (pRozkaz->iPar[0] & 2)
|
||||
{ // ustawienie flag zapauzowania
|
||||
Global.iPause = pRozkaz->fPar[2]; // zakładamy, że wysyłający wie, co robi
|
||||
Global.iPause = static_cast<int>(pRozkaz->fPar[2]); // zakładamy, że wysyłający wie, co robi
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -138,7 +136,7 @@ OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
||||
+ " rcvd" );
|
||||
if (pRozkaz->cString[0]) {
|
||||
// jeśli długość nazwy jest niezerowa szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #7
|
||||
auto *vehicle = pRozkaz->cString[1] == '*' ? simulation::Train->Dynamic() : simulation::Vehicles.find(std::string{pRozkaz->cString + 1, (unsigned)pRozkaz->cString[0]});
|
||||
auto const *vehicle = pRozkaz->cString[1] == '*' ? simulation::Train->Dynamic() : simulation::Vehicles.find(std::string{pRozkaz->cString + 1, (unsigned)pRozkaz->cString[0]});
|
||||
if( vehicle != nullptr ) {
|
||||
WyslijNamiary( vehicle ); // wysłanie informacji o pojeździe
|
||||
}
|
||||
@@ -189,7 +187,7 @@ OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
||||
d->Damage( pRozkaz->cString[ 0 ] );
|
||||
d = d->Prev(); // w drugą stronę też
|
||||
}
|
||||
WyslijUszkodzenia( lookup->asName, lookup->MoverParameters->EngDmgFlag ); // zwrot informacji o pojeździe
|
||||
WyslijUszkodzenia( lookup->asName, static_cast<char>(lookup->MoverParameters->EngDmgFlag) ); // zwrot informacji o pojeździe
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -198,7 +196,7 @@ OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
|
||||
}
|
||||
|
||||
void
|
||||
WyslijEvent(const std::string &e, const std::string &d)
|
||||
WyslijEvent([[maybe_unused]] const std::string &e, [[maybe_unused]] const std::string &d)
|
||||
{ // Ra: jeszcze do wyczyszczenia
|
||||
#ifdef _WIN32
|
||||
DaneRozkaz r;
|
||||
@@ -219,7 +217,7 @@ WyslijEvent(const std::string &e, const std::string &d)
|
||||
}
|
||||
|
||||
void
|
||||
WyslijUszkodzenia(const std::string &t, char fl)
|
||||
WyslijUszkodzenia([[maybe_unused]] const std::string &t, [[maybe_unused]] char fl)
|
||||
{ // wysłanie informacji w postaci pojedynczego tekstu
|
||||
#ifdef _WIN32
|
||||
DaneRozkaz r;
|
||||
@@ -239,7 +237,7 @@ WyslijUszkodzenia(const std::string &t, char fl)
|
||||
}
|
||||
|
||||
void
|
||||
WyslijString(const std::string &t, int n)
|
||||
WyslijString([[maybe_unused]] const std::string &t, [[maybe_unused]] int n)
|
||||
{ // wysłanie informacji w postaci pojedynczego tekstu
|
||||
#ifdef _WIN32
|
||||
DaneRozkaz r;
|
||||
@@ -264,7 +262,7 @@ WyslijWolny(const std::string &t)
|
||||
}
|
||||
|
||||
void
|
||||
WyslijNamiary(TDynamicObject const *Vehicle)
|
||||
WyslijNamiary([[maybe_unused]] TDynamicObject const *Vehicle)
|
||||
{ // wysłanie informacji o pojeździe - (float), długość ramki będzie zwiększana w miarę potrzeby
|
||||
#ifdef _WIN32
|
||||
DaneRozkaz r;
|
||||
@@ -395,7 +393,7 @@ WyslijObsadzone()
|
||||
}
|
||||
|
||||
void
|
||||
WyslijParam(int nr, int fl)
|
||||
WyslijParam([[maybe_unused]] int nr, [[maybe_unused]] int fl)
|
||||
{ // wysłanie parametrów symulacji w ramce (nr) z flagami (fl)
|
||||
#ifdef _WIN32
|
||||
DaneRozkaz r;
|
||||
|
||||
@@ -38,7 +38,7 @@ struct DaneRozkaz2 { // struktura komunikacji z EU07.EXE
|
||||
|
||||
void Navigate( std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam );
|
||||
|
||||
void OnCommandGet( multiplayer::DaneRozkaz *pRozkaz );
|
||||
void OnCommandGet( multiplayer::DaneRozkaz const *pRozkaz );
|
||||
|
||||
void WyslijEvent( const std::string &e, const std::string &d );
|
||||
void WyslijString( const std::string &t, int n );
|
||||
|
||||
@@ -11,11 +11,11 @@ public:
|
||||
static constexpr GLuint invalid_id { std::numeric_limits<GLuint>::max() };
|
||||
|
||||
deferred_image() = default;
|
||||
deferred_image(const std::string &p) : path(p) { }
|
||||
explicit deferred_image(const std::string &p) : path(p) { }
|
||||
deferred_image(const deferred_image&) = delete;
|
||||
deferred_image(deferred_image&&) = default;
|
||||
deferred_image &operator=(deferred_image&&) = default;
|
||||
operator bool() const
|
||||
explicit operator bool() const
|
||||
{
|
||||
return image != null_handle || !path.empty();
|
||||
}
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
tex.create();
|
||||
|
||||
if (tex.get_is_ready())
|
||||
return tex.get_id();
|
||||
return static_cast<GLuint>(tex.get_id());
|
||||
}
|
||||
|
||||
return invalid_id;
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
glm::ivec2 size() const
|
||||
{
|
||||
if (image != null_handle) {
|
||||
auto &tex = GfxRenderer->Texture(image);
|
||||
auto const &tex = GfxRenderer->Texture(image);
|
||||
return glm::ivec2(tex.get_width(), tex.get_height());
|
||||
}
|
||||
return glm::ivec2();
|
||||
|
||||
@@ -29,7 +29,7 @@ void launcher_mode::enter()
|
||||
|
||||
void launcher_mode::exit()
|
||||
{
|
||||
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
void launcher_mode::on_key(const int Key, const int Scancode, const int Action, const int Mods)
|
||||
|
||||
@@ -27,10 +27,10 @@ public:
|
||||
void exit() override;
|
||||
// input handlers
|
||||
void on_key( int Key, int Scancode, int Action, int Mods ) override;
|
||||
void on_cursor_pos( double const Horizontal, double const Vertical ) override { ; }
|
||||
void on_mouse_button( int const Button, int const Action, int const Mods ) override { ; }
|
||||
void on_scroll( double const Xoffset, double const Yoffset ) override { ; }
|
||||
void on_cursor_pos( double const Horizontal, double const Vertical ) override { /* not handled by the launcher */ }
|
||||
void on_mouse_button( int const Button, int const Action, int const Mods ) override { /* not handled by the launcher */ }
|
||||
void on_scroll( double const Xoffset, double const Yoffset ) override { /* not handled by the launcher */ }
|
||||
void on_window_resize( int w, int h ) override;
|
||||
void on_event_poll() override { ; }
|
||||
void on_event_poll() override { /* not handled by the launcher */ }
|
||||
bool is_command_processor() const override { return false; }
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ void ui::vehicles_bank::parse_entry(const std::string &line)
|
||||
|
||||
if (line[0] == '!')
|
||||
parse_category_entry(param);
|
||||
else if (line[0] == '*' && line[1] == '*')
|
||||
else if (line.starts_with("**"))
|
||||
parse_texture_rule(target.substr(2), param);
|
||||
else if (line[0] == '*')
|
||||
parse_coupling_rule(target.substr(1), param);
|
||||
@@ -60,23 +60,24 @@ void ui::vehicles_bank::parse_entry(const std::string &line)
|
||||
|
||||
void ui::vehicles_bank::parse_category_entry(const std::string ¶m)
|
||||
{
|
||||
using enum ui::vehicle_type;
|
||||
static std::unordered_map<char, vehicle_type> type_map = {
|
||||
{ 'e', vehicle_type::electric_loco },
|
||||
{ 's', vehicle_type::diesel_loco },
|
||||
{ 'p', vehicle_type::steam_loco },
|
||||
{ 'a', vehicle_type::railcar },
|
||||
{ 'z', vehicle_type::emu },
|
||||
{ 'r', vehicle_type::utility },
|
||||
{ 'd', vehicle_type::draisine },
|
||||
{ 't', vehicle_type::tram },
|
||||
{ 'c', vehicle_type::truck },
|
||||
{ 'b', vehicle_type::bus },
|
||||
{ 'o', vehicle_type::car },
|
||||
{ 'h', vehicle_type::man },
|
||||
{ 'f', vehicle_type::animal },
|
||||
{ 'e', electric_loco },
|
||||
{ 's', diesel_loco },
|
||||
{ 'p', steam_loco },
|
||||
{ 'a', railcar },
|
||||
{ 'z', emu },
|
||||
{ 'r', utility },
|
||||
{ 'd', draisine },
|
||||
{ 't', tram },
|
||||
{ 'c', truck },
|
||||
{ 'b', bus },
|
||||
{ 'o', car },
|
||||
{ 'h', man },
|
||||
{ 'f', animal },
|
||||
};
|
||||
|
||||
ctx_type = vehicle_type::unknown;
|
||||
ctx_type = unknown;
|
||||
|
||||
std::istringstream stream(param);
|
||||
|
||||
@@ -86,16 +87,15 @@ void ui::vehicles_bank::parse_category_entry(const std::string ¶m)
|
||||
if (tok.size() < 1)
|
||||
return;
|
||||
|
||||
auto it = type_map.find(tok[0]);
|
||||
if (it != type_map.end())
|
||||
if (auto it = type_map.find(tok[0]); it != type_map.end())
|
||||
ctx_type = it->second;
|
||||
else if (tok[0] >= 'A' && tok[0] <= 'Z')
|
||||
ctx_type = vehicle_type::carriage;
|
||||
ctx_type = carriage;
|
||||
|
||||
std::string mini;
|
||||
std::getline(stream, mini, ',');
|
||||
|
||||
category_icons.emplace(ctx_type, "textures/mini/" + ToLower(mini) + ".bmp");
|
||||
category_icons.try_emplace(ctx_type, "textures/mini/" + ToLower(mini) + ".bmp");
|
||||
}
|
||||
|
||||
void ui::vehicles_bank::parse_controllable_entry(const std::string &target, const std::string ¶m)
|
||||
@@ -108,7 +108,9 @@ void ui::vehicles_bank::parse_texture_info(const std::string &target, const std:
|
||||
{
|
||||
std::istringstream stream(param);
|
||||
|
||||
std::string model, mini, miniplus;
|
||||
std::string model;
|
||||
std::string mini;
|
||||
std::string miniplus;
|
||||
|
||||
std::getline(stream, model, ',');
|
||||
std::getline(stream, mini, ',');
|
||||
@@ -122,12 +124,12 @@ void ui::vehicles_bank::parse_texture_info(const std::string &target, const std:
|
||||
set.meta = meta;
|
||||
|
||||
if (!mini.empty())
|
||||
group_icons.emplace(mini, std::move(deferred_image("textures/mini/" + ToLower(mini) + ".bmp")));
|
||||
group_icons.try_emplace(mini, deferred_image("textures/mini/" + ToLower(mini) + ".bmp"));
|
||||
|
||||
if (!miniplus.empty())
|
||||
set.mini = std::move(deferred_image("textures/mini/" + ToLower(miniplus) + ".bmp"));
|
||||
set.mini = deferred_image("textures/mini/" + ToLower(miniplus) + ".bmp");
|
||||
else if (!mini.empty())
|
||||
set.mini = std::move(deferred_image("textures/mini/" + ToLower(mini) + ".bmp"));
|
||||
set.mini = deferred_image("textures/mini/" + ToLower(mini) + ".bmp");
|
||||
|
||||
set.skin = ToLower(target);
|
||||
erase_extension(set.skin);
|
||||
@@ -143,7 +145,7 @@ void ui::vehicles_bank::parse_texture_info(const std::string &target, const std:
|
||||
vehicle->matching_skinsets.push_back(std::make_shared<skin_set>(std::move(set)));
|
||||
}
|
||||
|
||||
std::shared_ptr<ui::skin_meta> ui::vehicles_bank::parse_meta(const std::string &str)
|
||||
std::shared_ptr<ui::skin_meta> ui::vehicles_bank::parse_meta(const std::string &str) const
|
||||
{
|
||||
std::istringstream stream(str);
|
||||
|
||||
@@ -171,19 +173,20 @@ std::shared_ptr<ui::skin_meta> ui::vehicles_bank::parse_meta(const std::string &
|
||||
ToLower("n:" + meta->name + ":i:" + meta->short_id + ":d:" + meta->location +
|
||||
":r:" + meta->rev_date + ":c:" + meta->rev_company + ":t:" + meta->texture_author + ":p:" + meta->photo_author);
|
||||
|
||||
std::replace(std::begin(meta->location), std::end(meta->location), '_', ' ');
|
||||
std::replace(std::begin(meta->rev_company), std::end(meta->rev_company), '_', ' ');
|
||||
std::replace(std::begin(meta->texture_author), std::end(meta->texture_author), '_', ' ');
|
||||
std::replace(std::begin(meta->photo_author), std::end(meta->photo_author), '_', ' ');
|
||||
std::ranges::replace(meta->location, '_', ' ');
|
||||
std::ranges::replace(meta->rev_company, '_', ' ');
|
||||
std::ranges::replace(meta->texture_author, '_', ' ');
|
||||
std::ranges::replace(meta->photo_author, '_', ' ');
|
||||
|
||||
if (!meta->rev_date.empty() && meta->rev_date != "?") {
|
||||
std::istringstream stream(meta->rev_date);
|
||||
std::string day, month;
|
||||
std::istringstream datestream(meta->rev_date);
|
||||
std::string day;
|
||||
std::string month;
|
||||
|
||||
std::getline(stream, day, '.');
|
||||
std::getline(stream, month, '.');
|
||||
std::getline(datestream, day, '.');
|
||||
std::getline(datestream, month, '.');
|
||||
|
||||
stream >> meta->rev_year;
|
||||
datestream >> meta->rev_year;
|
||||
}
|
||||
|
||||
return meta;
|
||||
@@ -205,7 +208,8 @@ void ui::vehicles_bank::parse_coupling_rule(const std::string &target, const std
|
||||
std::string connected;
|
||||
std::getline(stream, connected, ',');
|
||||
|
||||
std::string param1, param2;
|
||||
std::string param1;
|
||||
std::string param2;
|
||||
std::getline(stream, param1, ',');
|
||||
std::getline(stream, param2, ',');
|
||||
|
||||
@@ -232,7 +236,8 @@ void ui::vehicles_bank::parse_texture_rule(const std::string &target, const std:
|
||||
|
||||
std::istringstream rule_stream(replace_rule);
|
||||
|
||||
std::string src, dst;
|
||||
std::string src;
|
||||
std::string dst;
|
||||
std::getline(rule_stream, src, '-');
|
||||
std::getline(rule_stream, dst, '-');
|
||||
|
||||
@@ -257,7 +262,7 @@ std::shared_ptr<ui::vehicle_desc> ui::vehicles_bank::get_vehicle(const std::stri
|
||||
auto desc = std::make_shared<vehicle_desc>();
|
||||
desc->type = ctx_type;
|
||||
desc->path = path;
|
||||
vehicles.emplace(path, desc);
|
||||
vehicles.try_emplace(path, desc);
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ private:
|
||||
void parse_texture_rule(const std::string &target, const std::string ¶m);
|
||||
void parse_texture_info(const std::string &target, const std::string ¶m, std::shared_ptr<skin_meta> meta);
|
||||
|
||||
std::shared_ptr<skin_meta> parse_meta(const std::string &str);
|
||||
std::shared_ptr<skin_meta> parse_meta(const std::string &str) const;
|
||||
std::shared_ptr<vehicle_desc> get_vehicle(const std::string &name);
|
||||
|
||||
vehicle_type ctx_type = vehicle_type::unknown;
|
||||
|
||||
@@ -47,11 +47,11 @@ TModelsManager::LoadModel(std::string const &Name, std::string const &virtualNam
|
||||
m_models.emplace_back();
|
||||
auto model = m_models.back().LoadModel( Name, dynamic );
|
||||
if( model != nullptr ) {
|
||||
m_modelsmap.emplace( virtualName, m_models.size() - 1 );
|
||||
m_modelsmap.try_emplace( virtualName, m_models.size() - 1 );
|
||||
}
|
||||
else {
|
||||
m_models.pop_back();
|
||||
m_modelsmap.emplace( virtualName, null_handle );
|
||||
m_modelsmap.try_emplace( virtualName, null_handle );
|
||||
}
|
||||
return model;
|
||||
}
|
||||
@@ -95,17 +95,16 @@ TModelsManager::GetModel(std::string const &Name, bool const Dynamic, bool const
|
||||
postfix = "^^" + std::to_string(uid);
|
||||
|
||||
// see if we have it in the databank
|
||||
auto banklookup { find_in_databank( filename + postfix ) };
|
||||
TModel3d *model { banklookup.second };
|
||||
if( true == banklookup.first ) {
|
||||
auto [banklookupfound, banklookupmodel]{ find_in_databank( filename + postfix ) };
|
||||
TModel3d *model { banklookupmodel };
|
||||
if( true == banklookupfound ) {
|
||||
Global.asCurrentTexturePath = buftp;
|
||||
return model;
|
||||
}
|
||||
|
||||
// first load attempt, check if it's on disk
|
||||
std::string disklookup { find_on_disk( filename ) };
|
||||
|
||||
if( false == disklookup.empty() ) {
|
||||
if( std::string disklookup { find_on_disk( filename ) }; false == disklookup.empty() ) {
|
||||
model = LoadModel( disklookup, disklookup + postfix, Dynamic ); // model nie znaleziony, to wczytać
|
||||
}
|
||||
else {
|
||||
@@ -114,7 +113,7 @@ TModelsManager::GetModel(std::string const &Name, bool const Dynamic, bool const
|
||||
ErrorLog( "Bad file: failed to locate 3d model file \"" + filename + "\"", logtype::file );
|
||||
}
|
||||
// ...and link it with the error model slot
|
||||
m_modelsmap.emplace( filename + postfix, null_handle );
|
||||
m_modelsmap.try_emplace( filename + postfix, null_handle );
|
||||
}
|
||||
Global.asCurrentTexturePath = buftp; // odtworzenie ścieżki do tekstur
|
||||
return model; // NULL jeśli błąd
|
||||
|
||||
@@ -12,7 +12,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
class TMdlContainer {
|
||||
friend class TModelsManager;
|
||||
private:
|
||||
TModel3d *LoadModel( std::string const &Name, bool const Dynamic );
|
||||
std::shared_ptr<TModel3d> Model { nullptr };
|
||||
std::string m_name;
|
||||
@@ -26,8 +25,8 @@ public:
|
||||
|
||||
private:
|
||||
// types:
|
||||
typedef std::deque<TMdlContainer> modelcontainer_sequence;
|
||||
typedef std::unordered_map<std::string, modelcontainer_sequence::size_type> stringmodelcontainerindex_map;
|
||||
using modelcontainer_sequence = std::deque<TMdlContainer>;
|
||||
using stringmodelcontainerindex_map = std::unordered_map<std::string, modelcontainer_sequence::size_type>;
|
||||
// members:
|
||||
static modelcontainer_sequence m_models;
|
||||
static stringmodelcontainerindex_map m_modelsmap;
|
||||
|
||||
@@ -19,7 +19,7 @@ struct world_vertex {
|
||||
|
||||
static world_vertex lerp(world_vertex const &a, world_vertex const &b, double factor)
|
||||
{
|
||||
return static_cast<world_vertex>(a * (1.0f - factor) + b * factor);
|
||||
return a * (1.0f - factor) + b * factor;
|
||||
}
|
||||
|
||||
// overloads
|
||||
|
||||
@@ -37,8 +37,7 @@ void network::tcp::connection::connected()
|
||||
void network::tcp::connection::read_header()
|
||||
{
|
||||
asio::async_read(m_socket, asio::buffer(m_header_buffer),
|
||||
std::bind(&connection::handle_header, this,
|
||||
std::placeholders::_1, std::placeholders::_2));
|
||||
std::bind_front(&connection::handle_header, this));
|
||||
}
|
||||
|
||||
void network::tcp::connection::handle_header(const asio::error_code &err, size_t bytes_transferred)
|
||||
@@ -54,8 +53,7 @@ void network::tcp::connection::handle_header(const asio::error_code &err, size_t
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t sig = sn_utils::ld_uint32(header);
|
||||
if (sig != NETWORK_MAGIC) {
|
||||
if (uint32_t sig = sn_utils::ld_uint32(header); sig != NETWORK_MAGIC) {
|
||||
disconnect();
|
||||
return;
|
||||
}
|
||||
@@ -68,7 +66,7 @@ void network::tcp::connection::handle_header(const asio::error_code &err, size_t
|
||||
}
|
||||
|
||||
asio::async_read(m_socket, asio::buffer(m_body_buffer),
|
||||
std::bind(&connection::handle_data, this, std::placeholders::_1, std::placeholders::_2));
|
||||
std::bind_front(&connection::handle_data, this));
|
||||
}
|
||||
|
||||
void network::tcp::connection::handle_data(const asio::error_code &err, size_t bytes_transferred)
|
||||
@@ -91,9 +89,9 @@ void network::tcp::connection::handle_data(const asio::error_code &err, size_t b
|
||||
read_header();
|
||||
}
|
||||
|
||||
void network::tcp::connection::write_message(const message &msg, std::ostream &stream)
|
||||
void network::tcp::connection::write_message(const message &msg, std::ostream &stream) const
|
||||
{
|
||||
size_t beg = (size_t)stream.tellp();
|
||||
auto beg = (size_t)stream.tellp();
|
||||
|
||||
sn_utils::ls_uint32(stream, NETWORK_MAGIC);
|
||||
sn_utils::ls_uint32(stream, 0);
|
||||
@@ -106,14 +104,14 @@ void network::tcp::connection::write_message(const message &msg, std::ostream &s
|
||||
return;
|
||||
}
|
||||
stream.seekp(beg + 4, std::ios_base::beg);
|
||||
sn_utils::ls_uint32(stream, size);
|
||||
sn_utils::ls_uint32(stream, static_cast<uint32_t>(size));
|
||||
|
||||
stream.seekp(0, std::ios_base::end);
|
||||
}
|
||||
|
||||
void network::tcp::connection::send_messages(const std::vector<std::shared_ptr<message> > &messages)
|
||||
{
|
||||
if (messages.size() == 0)
|
||||
if (messages.empty())
|
||||
return;
|
||||
|
||||
std::ostringstream stream;
|
||||
@@ -138,7 +136,7 @@ void network::tcp::connection::send_message(const message &msg)
|
||||
network::tcp::server::server(std::shared_ptr<std::istream> buf, asio::io_context &io_ctx, const std::string &host, uint32_t port)
|
||||
: network::server(buf), m_acceptor(io_ctx), m_io_ctx(io_ctx)
|
||||
{
|
||||
auto endpoint = asio::ip::tcp::endpoint(asio::ip::make_address(host), port);
|
||||
auto endpoint = asio::ip::tcp::endpoint(asio::ip::make_address(host), static_cast<asio::ip::port_type>(port));
|
||||
m_acceptor.open(endpoint.protocol());
|
||||
m_acceptor.set_option(asio::socket_base::reuse_address(true));
|
||||
m_acceptor.set_option(asio::ip::tcp::no_delay(true));
|
||||
@@ -150,10 +148,10 @@ network::tcp::server::server(std::shared_ptr<std::istream> buf, asio::io_context
|
||||
|
||||
void network::tcp::server::accept_conn()
|
||||
{
|
||||
std::shared_ptr<connection> conn = std::make_shared<connection>(m_io_ctx);
|
||||
conn->set_handler(std::bind(&server::handle_message, this, conn, std::placeholders::_1));
|
||||
auto conn = std::make_shared<connection>(m_io_ctx);
|
||||
conn->set_handler(std::bind_front(&server::handle_message, this, conn));
|
||||
|
||||
m_acceptor.async_accept(conn->m_socket, std::bind(&server::handle_accept, this, conn, std::placeholders::_1));
|
||||
m_acceptor.async_accept(conn->m_socket, std::bind_front(&server::handle_accept, this, conn));
|
||||
}
|
||||
|
||||
void network::tcp::server::handle_accept(std::shared_ptr<connection> conn, const asio::error_code &err)
|
||||
@@ -175,7 +173,7 @@ void network::tcp::server::handle_accept(std::shared_ptr<connection> conn, const
|
||||
// ------------------
|
||||
|
||||
network::tcp::client::client(asio::io_context &io_ctxx, const std::string &hostarg, uint32_t portarg)
|
||||
: host(hostarg), port(portarg), io_ctx(io_ctxx)
|
||||
: io_ctx(io_ctxx), host(hostarg), port(portarg)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -184,21 +182,21 @@ void network::tcp::client::connect()
|
||||
if (this->conn)
|
||||
return;
|
||||
|
||||
std::shared_ptr<connection> conn = std::make_shared<connection>(io_ctx, true, resume_frame_counter);
|
||||
conn->set_handler(std::bind(&client::handle_message, this, conn, std::placeholders::_1));
|
||||
auto newconnection = std::make_shared<connection>(io_ctx, true, resume_frame_counter);
|
||||
newconnection->set_handler(std::bind_front(&client::handle_message, this, newconnection));
|
||||
|
||||
asio::ip::tcp::endpoint endpoint(
|
||||
asio::ip::make_address(host), port);
|
||||
conn->m_socket.open(endpoint.protocol());
|
||||
conn->m_socket.set_option(asio::ip::tcp::no_delay(true));
|
||||
conn->m_socket.async_connect(endpoint,
|
||||
std::bind(&client::handle_accept, this, std::placeholders::_1));
|
||||
asio::ip::make_address(host), static_cast<asio::ip::port_type>(port));
|
||||
newconnection->m_socket.open(endpoint.protocol());
|
||||
newconnection->m_socket.set_option(asio::ip::tcp::no_delay(true));
|
||||
newconnection->m_socket.async_connect(endpoint,
|
||||
std::bind_front(&client::handle_accept, this));
|
||||
|
||||
this->conn = conn;
|
||||
this->conn = newconnection;
|
||||
|
||||
}
|
||||
|
||||
void network::tcp::client::handle_accept(const asio::error_code &err)
|
||||
void network::tcp::client::handle_accept(const asio::error_code &err) const
|
||||
{
|
||||
if (!err)
|
||||
{
|
||||
@@ -212,7 +210,7 @@ void network::tcp::client::handle_accept(const asio::error_code &err)
|
||||
}
|
||||
|
||||
network::tcp::asio_manager::asio_manager() {
|
||||
backend_list().emplace("tcp", this);
|
||||
backend_list().try_emplace("tcp", this);
|
||||
}
|
||||
|
||||
std::shared_ptr<network::server> network::tcp::asio_manager::create_server(std::shared_ptr<std::fstream> backbuffer, const std::string &conf) {
|
||||
|
||||
@@ -18,13 +18,13 @@ namespace network::tcp
|
||||
friend class client;
|
||||
|
||||
public:
|
||||
connection(asio::io_context &io_ctx, bool client = false, size_t counter = 0);
|
||||
explicit connection(asio::io_context &io_ctx, bool client = false, size_t counter = 0);
|
||||
~connection();
|
||||
|
||||
virtual void connected() override;
|
||||
virtual void disconnect() override;
|
||||
virtual void send_messages(const std::vector<std::shared_ptr<message> > &messages) override;
|
||||
virtual void send_message(const message &msg) override;
|
||||
void connected() override;
|
||||
void disconnect() override;
|
||||
void send_messages(const std::vector<std::shared_ptr<message> > &messages) override;
|
||||
void send_message(const message &msg) override;
|
||||
|
||||
asio::ip::tcp::socket m_socket;
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace network::tcp
|
||||
std::string m_header_buffer;
|
||||
std::string m_body_buffer;
|
||||
|
||||
void write_message(const message &msg, std::ostream &stream);
|
||||
void write_message(const message &msg, std::ostream &stream) const;
|
||||
void send_data(std::shared_ptr<std::string> buffer);
|
||||
void read_header();
|
||||
void handle_header(const asio::error_code &err, size_t bytes_transferred);
|
||||
@@ -55,13 +55,13 @@ namespace network::tcp
|
||||
class client : public network::client
|
||||
{
|
||||
private:
|
||||
void handle_accept(const asio::error_code &err);
|
||||
void handle_accept(const asio::error_code &err) const;
|
||||
asio::io_context &io_ctx;
|
||||
std::string host;
|
||||
uint32_t port;
|
||||
|
||||
protected:
|
||||
virtual void connect() override;
|
||||
void connect() override;
|
||||
|
||||
public:
|
||||
client(asio::io_context &io_ctx, const std::string &host, uint32_t port);
|
||||
@@ -73,9 +73,9 @@ namespace network::tcp
|
||||
public:
|
||||
asio_manager();
|
||||
|
||||
virtual std::shared_ptr<network::server> create_server(std::shared_ptr<std::fstream>, const std::string &conf) override;
|
||||
virtual std::shared_ptr<network::client> create_client(const std::string &conf) override;
|
||||
virtual void update() override;
|
||||
std::shared_ptr<network::server> create_server(std::shared_ptr<std::fstream>, const std::string &conf) override;
|
||||
std::shared_ptr<network::client> create_client(const std::string &conf) override;
|
||||
void update() override;
|
||||
};
|
||||
|
||||
asio_manager manager;
|
||||
|
||||
@@ -17,7 +17,7 @@ network::server_manager::server_manager()
|
||||
backbuffer = std::make_shared<std::fstream>("backbuffer.bin", std::ios::out | std::ios::in | std::ios::trunc | std::ios::binary);
|
||||
}
|
||||
|
||||
command_queue::commands_map network::server_manager::pop_commands()
|
||||
command_queue::commands_map network::server_manager::pop_commands() const
|
||||
{
|
||||
command_queue::commands_map map;
|
||||
|
||||
@@ -27,7 +27,7 @@ command_queue::commands_map network::server_manager::pop_commands()
|
||||
return map;
|
||||
}
|
||||
|
||||
void network::server_manager::push_delta(double render_dt, double dt, double sync, const command_queue::commands_map &commands)
|
||||
void network::server_manager::push_delta(double render_dt, double dt, double sync, const command_queue::commands_map &commands) const
|
||||
{
|
||||
if (dt == 0.0 && commands.empty())
|
||||
return;
|
||||
@@ -55,14 +55,12 @@ void network::server_manager::create_server(const std::string &backend, const st
|
||||
servers.emplace_back(it->second->create_server(backbuffer, conf));
|
||||
}
|
||||
|
||||
network::manager::manager()
|
||||
{
|
||||
}
|
||||
network::manager::manager() = default;
|
||||
|
||||
void network::manager::update()
|
||||
{
|
||||
for (auto &backend : backend_list())
|
||||
backend.second->update();
|
||||
for (auto const &[backendname, backendinstance] : backend_list())
|
||||
backendinstance->update();
|
||||
|
||||
if (client)
|
||||
client->update();
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace network
|
||||
public:
|
||||
server_manager();
|
||||
|
||||
void push_delta(double render_dt, double dt, double sync, const command_queue::commands_map &commands);
|
||||
command_queue::commands_map pop_commands();
|
||||
void push_delta(double render_dt, double dt, double sync, const command_queue::commands_map &commands) const;
|
||||
command_queue::commands_map pop_commands() const;
|
||||
void create_server(const std::string &backend, const std::string &conf);
|
||||
};
|
||||
|
||||
|
||||
@@ -32,12 +32,12 @@ void network::server_hello::deserialize(std::istream &stream)
|
||||
|
||||
void ::network::request_command::serialize(std::ostream &stream) const
|
||||
{
|
||||
sn_utils::ls_uint32(stream, commands.size());
|
||||
for (auto const &kv : commands)
|
||||
sn_utils::ls_uint32(stream, static_cast<uint32_t>(commands.size()));
|
||||
for (auto const &[recipient, sequence] : commands)
|
||||
{
|
||||
sn_utils::ls_uint32(stream, kv.first);
|
||||
sn_utils::ls_uint32(stream, kv.second.size());
|
||||
for (command_data const &data : kv.second)
|
||||
sn_utils::ls_uint32(stream, recipient);
|
||||
sn_utils::ls_uint32(stream, static_cast<uint32_t>(sequence.size()));
|
||||
for (command_data const &data : sequence)
|
||||
{
|
||||
sn_utils::ls_uint32(stream, (uint32_t)data.command);
|
||||
sn_utils::ls_int32(stream, data.action);
|
||||
@@ -62,7 +62,7 @@ void network::request_command::deserialize(std::istream &stream)
|
||||
uint32_t sequence_size = sn_utils::ld_uint32(stream);
|
||||
|
||||
command_queue::commanddata_sequence sequence;
|
||||
for (uint32_t i = 0; i < sequence_size; i++)
|
||||
for (uint32_t j = 0; j < sequence_size; j++)
|
||||
{
|
||||
command_data data;
|
||||
data.command = (user_command)sn_utils::ld_uint32(stream);
|
||||
@@ -79,7 +79,7 @@ void network::request_command::deserialize(std::istream &stream)
|
||||
sequence.emplace_back(data);
|
||||
}
|
||||
|
||||
commands.emplace(recipient, sequence);
|
||||
commands.try_emplace(recipient, sequence);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ void network::frame_info::deserialize(std::istream &stream)
|
||||
|
||||
std::shared_ptr<network::message> network::deserialize_message(std::istream &stream)
|
||||
{
|
||||
message::type_e type = (message::type_e)sn_utils::ld_uint16(stream);
|
||||
auto type = (message::type_e)sn_utils::ld_uint16(stream);
|
||||
|
||||
std::shared_ptr<message> msg;
|
||||
|
||||
|
||||
@@ -18,17 +18,18 @@ struct message
|
||||
|
||||
type_e type;
|
||||
|
||||
message(type_e t) : type(t) {}
|
||||
virtual void serialize(std::ostream &stream) const {}
|
||||
virtual void deserialize(std::istream &stream) {}
|
||||
explicit message(type_e t) : type(t) {}
|
||||
virtual void serialize(std::ostream &stream) const { /* message carries no payload */ }
|
||||
virtual void deserialize(std::istream &stream) { /* message carries no payload */ }
|
||||
virtual ~message() = default;
|
||||
};
|
||||
|
||||
struct client_hello : public message
|
||||
{
|
||||
client_hello() : message(CLIENT_HELLO) {}
|
||||
|
||||
virtual void serialize(std::ostream &stream) const override;
|
||||
virtual void deserialize(std::istream &stream) override;
|
||||
void serialize(std::ostream &stream) const override;
|
||||
void deserialize(std::istream &stream) override;
|
||||
|
||||
int32_t version{0};
|
||||
uint32_t start_packet{0};
|
||||
@@ -43,19 +44,19 @@ struct server_hello : public message
|
||||
int64_t config{0};
|
||||
std::string scenario;
|
||||
|
||||
virtual void serialize(std::ostream &stream) const override;
|
||||
virtual void deserialize(std::istream &stream) override;
|
||||
void serialize(std::ostream &stream) const override;
|
||||
void deserialize(std::istream &stream) override;
|
||||
};
|
||||
|
||||
struct request_command : public message
|
||||
{
|
||||
request_command(type_e type) : message(type) {}
|
||||
using message::message;
|
||||
request_command() : message(REQUEST_COMMAND) {}
|
||||
|
||||
command_queue::commands_map commands;
|
||||
|
||||
virtual void serialize(std::ostream &stream) const override;
|
||||
virtual void deserialize(std::istream &stream) override;
|
||||
void serialize(std::ostream &stream) const override;
|
||||
void deserialize(std::istream &stream) override;
|
||||
};
|
||||
|
||||
struct frame_info : public request_command
|
||||
@@ -66,8 +67,8 @@ struct frame_info : public request_command
|
||||
double dt{0.0};
|
||||
double sync{0.0};
|
||||
|
||||
virtual void serialize(std::ostream &stream) const override;
|
||||
virtual void deserialize(std::istream &stream) override;
|
||||
void serialize(std::ostream &stream) const override;
|
||||
void deserialize(std::istream &stream) override;
|
||||
};
|
||||
|
||||
std::shared_ptr<message> deserialize_message(std::istream &stream);
|
||||
|
||||
@@ -30,9 +30,7 @@ void network::connection::set_handler(std::function<void (const message &)> hand
|
||||
message_handler = handler;
|
||||
}
|
||||
|
||||
network::connection::connection(bool client, size_t counter) {
|
||||
packet_counter = counter;
|
||||
is_client = client;
|
||||
network::connection::connection(bool client, size_t counter) : is_client(client), packet_counter(counter) {
|
||||
state = AWAITING_HELLO;
|
||||
}
|
||||
|
||||
@@ -43,7 +41,7 @@ void network::connection::connected()
|
||||
if (is_client) {
|
||||
client_hello msg;
|
||||
msg.version = EU07_NETWORK_VERSION;
|
||||
msg.start_packet = packet_counter;
|
||||
msg.start_packet = static_cast<uint32_t>(packet_counter);
|
||||
send_message(msg);
|
||||
}
|
||||
}
|
||||
@@ -79,7 +77,7 @@ void network::connection::catch_up()
|
||||
send_messages(messages);
|
||||
}
|
||||
|
||||
void network::connection::send_complete(std::shared_ptr<std::string> buf)
|
||||
void network::connection::send_complete(std::shared_ptr<std::string> /*buf*/)
|
||||
{
|
||||
if (!is_client && state == CATCHING_UP) {
|
||||
catch_up();
|
||||
@@ -151,7 +149,7 @@ void network::server::handle_message(std::shared_ptr<connection> conn, const mes
|
||||
const auto& cmd = dynamic_cast<const request_command&>(msg);
|
||||
|
||||
for (auto const &kv : cmd.commands)
|
||||
client_commands_queue.emplace(kv);
|
||||
client_commands_queue.try_emplace(kv.first, kv.second);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,9 +186,9 @@ std::tuple<double, double, command_queue::commands_map> network::client::get_nex
|
||||
}
|
||||
|
||||
|
||||
float size = delta_queue.size() - consume_counter;
|
||||
float size = static_cast<float>(delta_queue.size()) - consume_counter;
|
||||
const auto& entry = delta_queue.front();
|
||||
float mult = entry.render_dt / std::chrono::duration_cast<std::chrono::duration<float>>(frame_time).count();
|
||||
auto mult = static_cast<float>(entry.render_dt / std::chrono::duration_cast<std::chrono::duration<float>>(frame_time).count());
|
||||
|
||||
if (counter == 1 && size < MAX_BUFFER_SIZE * 2.0f) {
|
||||
last_target = last_target * TARGET_MIX +
|
||||
@@ -220,7 +218,7 @@ std::tuple<double, double, command_queue::commands_map> network::client::get_nex
|
||||
}
|
||||
}
|
||||
|
||||
void network::client::send_commands(command_queue::commands_map commands)
|
||||
void network::client::send_commands(command_queue::commands_map const &commands) const
|
||||
{
|
||||
if (!conn || conn->state == connection::DEAD || commands.empty())
|
||||
return;
|
||||
@@ -232,17 +230,17 @@ void network::client::send_commands(command_queue::commands_map commands)
|
||||
conn->send_message(msg);
|
||||
}
|
||||
|
||||
void network::client::handle_message(std::shared_ptr<connection> conn, const message &msg)
|
||||
void network::client::handle_message(std::shared_ptr<connection> Connection, const message &msg)
|
||||
{
|
||||
if (msg.type >= message::TYPE_MAX)
|
||||
{
|
||||
conn->disconnect();
|
||||
Connection->disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.type == message::SERVER_HELLO) {
|
||||
const auto& cmd = dynamic_cast<const server_hello&>(msg);
|
||||
conn->state = connection::ACTIVE;
|
||||
Connection->state = connection::ACTIVE;
|
||||
|
||||
if (!Global.ready_to_load) {
|
||||
Global.random_seed = cmd.seed;
|
||||
@@ -253,14 +251,14 @@ void network::client::handle_message(std::shared_ptr<connection> conn, const mes
|
||||
Global.ready_to_load = true;
|
||||
} else if (Global.random_seed != cmd.seed) {
|
||||
ErrorLog("net: seed mismatch", logtype::net);
|
||||
conn->disconnect();
|
||||
Connection->disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
WriteLog("net: accept received", logtype::net);
|
||||
}
|
||||
|
||||
if (conn->state != connection::ACTIVE)
|
||||
if (Connection->state != connection::ACTIVE)
|
||||
return;
|
||||
|
||||
if (msg.type == message::FRAME_INFO) {
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace network
|
||||
virtual void send_message(const message &msg) = 0;
|
||||
virtual void send_messages(const std::vector<std::shared_ptr<message>> &messages) = 0;
|
||||
|
||||
connection(bool client = false, size_t counter = 0);
|
||||
explicit connection(bool client = false, size_t counter = 0);
|
||||
void set_handler(std::function<void(const message &msg)> handler);
|
||||
|
||||
virtual void disconnect() = 0;
|
||||
@@ -47,6 +47,7 @@ namespace network
|
||||
DEAD
|
||||
};
|
||||
peer_state state;
|
||||
virtual ~connection() = default;
|
||||
};
|
||||
|
||||
class server
|
||||
@@ -62,7 +63,7 @@ namespace network
|
||||
command_queue::commands_map client_commands_queue;
|
||||
|
||||
public:
|
||||
server(std::shared_ptr<std::istream> buf);
|
||||
explicit server(std::shared_ptr<std::istream> buf);
|
||||
void push_delta(const frame_info &msg);
|
||||
command_queue::commands_map pop_commands();
|
||||
};
|
||||
@@ -97,13 +98,14 @@ namespace network
|
||||
public:
|
||||
void update();
|
||||
std::tuple<double, double, command_queue::commands_map> get_next_delta(int counter);
|
||||
void send_commands(command_queue::commands_map commands);
|
||||
int get_frame_counter() {
|
||||
return resume_frame_counter;
|
||||
void send_commands(command_queue::commands_map const &commands) const;
|
||||
int get_frame_counter() const {
|
||||
return static_cast<int>(resume_frame_counter);
|
||||
}
|
||||
int get_awaiting_frames() {
|
||||
return delta_queue.size();
|
||||
int get_awaiting_frames() const {
|
||||
return static_cast<int>(delta_queue.size());
|
||||
}
|
||||
virtual ~client() = default;
|
||||
};
|
||||
|
||||
class backend_manager
|
||||
@@ -112,6 +114,7 @@ namespace network
|
||||
virtual std::shared_ptr<server> create_server(std::shared_ptr<std::fstream>, const std::string &conf) = 0;
|
||||
virtual std::shared_ptr<client> create_client(const std::string &conf) = 0;
|
||||
virtual void update() = 0;
|
||||
virtual ~backend_manager() = default;
|
||||
};
|
||||
|
||||
// HACK: static initialization order fiasco fix
|
||||
|
||||
@@ -14,39 +14,43 @@ namespace flip_s3tc
|
||||
|
||||
struct dxt1_block
|
||||
{
|
||||
uint16_t c0, c1;
|
||||
uint8_t dcba,
|
||||
hgfe,
|
||||
lkji,
|
||||
ponm;
|
||||
uint16_t c0;
|
||||
uint16_t c1;
|
||||
uint8_t dcba;
|
||||
uint8_t hgfe;
|
||||
uint8_t lkji;
|
||||
uint8_t ponm;
|
||||
};
|
||||
|
||||
struct dxt23_block
|
||||
{
|
||||
uint16_t adacabaa,
|
||||
ahagafae,
|
||||
alakajai,
|
||||
apaoanam;
|
||||
uint16_t c0, c1;
|
||||
uint8_t dcba,
|
||||
hgfe,
|
||||
lkji,
|
||||
ponm;
|
||||
uint16_t adacabaa;
|
||||
uint16_t ahagafae;
|
||||
uint16_t alakajai;
|
||||
uint16_t apaoanam;
|
||||
uint16_t c0;
|
||||
uint16_t c1;
|
||||
uint8_t dcba;
|
||||
uint8_t hgfe;
|
||||
uint8_t lkji;
|
||||
uint8_t ponm;
|
||||
};
|
||||
|
||||
struct dxt45_block
|
||||
{
|
||||
uint8_t a0, a1;
|
||||
uint8_t a0;
|
||||
uint8_t a1;
|
||||
struct
|
||||
{
|
||||
uint8_t alpha[3];
|
||||
} ahagafaeadacabaa,
|
||||
apaoanamalakajai;
|
||||
uint16_t c0, c1;
|
||||
uint8_t dcba,
|
||||
hgfe,
|
||||
lkji,
|
||||
ponm;
|
||||
uint16_t c0;
|
||||
uint16_t c1;
|
||||
uint8_t dcba;
|
||||
uint8_t hgfe;
|
||||
uint8_t lkji;
|
||||
uint8_t ponm;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
@@ -123,16 +127,16 @@ void flip_dxt45_block(struct dxt45_block *block)
|
||||
*/
|
||||
void flip_dxt1_image(void *data, int width, int height)
|
||||
{
|
||||
int x, y;
|
||||
struct dxt1_block temp1, temp2;
|
||||
struct dxt1_block *blocks = (struct dxt1_block *)data;
|
||||
struct dxt1_block temp1;
|
||||
struct dxt1_block temp2;
|
||||
auto blocks = (struct dxt1_block *)data;
|
||||
|
||||
width = (width + 3) / 4;
|
||||
height = (height + 3) / 4;
|
||||
|
||||
for (y = 0; y < height / 2; ++y)
|
||||
for (int y = 0; y < height / 2; ++y)
|
||||
{
|
||||
for (x = 0; x < width; ++x)
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
temp1 = blocks[y * width + x];
|
||||
temp2 = blocks[(height - y - 1) * width + x];
|
||||
@@ -152,16 +156,16 @@ void flip_dxt1_image(void *data, int width, int height)
|
||||
*/
|
||||
void flip_dxt23_image(void *data, int width, int height)
|
||||
{
|
||||
int x, y;
|
||||
struct dxt23_block temp1, temp2;
|
||||
struct dxt23_block *blocks = (struct dxt23_block *)data;
|
||||
struct dxt23_block temp1;
|
||||
struct dxt23_block temp2;
|
||||
auto blocks = (struct dxt23_block *)data;
|
||||
|
||||
width = (width + 3) / 4;
|
||||
height = (height + 3) / 4;
|
||||
|
||||
for (y = 0; y < height / 2; ++y)
|
||||
for (int y = 0; y < height / 2; ++y)
|
||||
{
|
||||
for (x = 0; x < width; ++x)
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
temp1 = blocks[y * width + x];
|
||||
temp2 = blocks[(height - y - 1) * width + x];
|
||||
@@ -181,16 +185,16 @@ void flip_dxt23_image(void *data, int width, int height)
|
||||
*/
|
||||
void flip_dxt45_image(void *data, int width, int height)
|
||||
{
|
||||
int x, y;
|
||||
struct dxt45_block temp1, temp2;
|
||||
struct dxt45_block *blocks = (struct dxt45_block *)data;
|
||||
struct dxt45_block temp1;
|
||||
struct dxt45_block temp2;
|
||||
auto blocks = (struct dxt45_block *)data;
|
||||
|
||||
width = (width + 3) / 4;
|
||||
height = (height + 3) / 4;
|
||||
|
||||
for (y = 0; y < height / 2; ++y)
|
||||
for (int y = 0; y < height / 2; ++y)
|
||||
{
|
||||
for (x = 0; x < width; ++x)
|
||||
for (int x = 0; x < width; ++x)
|
||||
{
|
||||
temp1 = blocks[y * width + x];
|
||||
temp2 = blocks[(height - y - 1) * width + x];
|
||||
|
||||
@@ -24,7 +24,7 @@ cFrustum::calculate( glm::mat4 const &Projection, glm::mat4 const &Modelview ) {
|
||||
|
||||
// multiply the matrices to retrieve clipping planes (column-major, same layout as the old float[16] form)
|
||||
auto const clipmatrix { Projection * Modelview };
|
||||
float clip[ 16 ];
|
||||
std::array<float, 16> clip{};
|
||||
for( int column = 0; column < 4; ++column ) {
|
||||
for( int row = 0; row < 4; ++row ) {
|
||||
clip[ column * 4 + row ] = clipmatrix[ column ][ row ];
|
||||
@@ -73,16 +73,11 @@ bool
|
||||
cFrustum::point_inside( float const X, float const Y, float const Z ) const {
|
||||
|
||||
// cycle through the sides of the frustum, checking if the point is behind them
|
||||
for( int idx = 0; idx < 6; ++idx ) {
|
||||
if( m_frustum[ idx ][ plane_A ] * X
|
||||
+ m_frustum[ idx ][ plane_B ] * Y
|
||||
+ m_frustum[ idx ][ plane_C ] * Z
|
||||
+ m_frustum[ idx ][ plane_D ] <= 0 )
|
||||
return false;
|
||||
}
|
||||
|
||||
// the point is in front of each frustum plane, i.e. inside of the frustum
|
||||
return true;
|
||||
return std::ranges::all_of( m_frustum, [&]( auto const &frustumplane ) {
|
||||
return frustumplane[ plane_A ] * X
|
||||
+ frustumplane[ plane_B ] * Y
|
||||
+ frustumplane[ plane_C ] * Z
|
||||
+ frustumplane[ plane_D ] > 0; } );
|
||||
}
|
||||
|
||||
float
|
||||
@@ -90,12 +85,12 @@ cFrustum::sphere_inside( float const X, float const Y, float const Z, float cons
|
||||
|
||||
float distance;
|
||||
// go through all the sides of the frustum. bail out as soon as possible
|
||||
for( int idx = 0; idx < 6; ++idx ) {
|
||||
for (auto &frustumplane : m_frustum) {
|
||||
distance =
|
||||
m_frustum[ idx ][ plane_A ] * X
|
||||
+ m_frustum[ idx ][ plane_B ] * Y
|
||||
+ m_frustum[ idx ][ plane_C ] * Z
|
||||
+ m_frustum[ idx ][ plane_D ];
|
||||
frustumplane[ plane_A ] * X
|
||||
+ frustumplane[ plane_B ] * Y
|
||||
+ frustumplane[ plane_C ] * Z
|
||||
+ frustumplane[ plane_D ];
|
||||
if( distance <= -Radius )
|
||||
return 0.0f;
|
||||
}
|
||||
@@ -105,52 +100,50 @@ cFrustum::sphere_inside( float const X, float const Y, float const Z, float cons
|
||||
bool
|
||||
cFrustum::cube_inside( float const X, float const Y, float const Z, float const Size ) const {
|
||||
|
||||
for( int idx = 0; idx < 6; ++idx ) {
|
||||
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
|
||||
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
|
||||
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
|
||||
+ m_frustum[ idx ][ plane_D ] > 0 )
|
||||
continue;
|
||||
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
|
||||
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
|
||||
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
|
||||
+ m_frustum[ idx ][ plane_D ] > 0 )
|
||||
continue;
|
||||
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
|
||||
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
|
||||
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
|
||||
+ m_frustum[ idx ][ plane_D ] > 0 )
|
||||
continue;
|
||||
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
|
||||
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
|
||||
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
|
||||
+ m_frustum[ idx ][ plane_D ] > 0 )
|
||||
continue;
|
||||
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
|
||||
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
|
||||
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
|
||||
+ m_frustum[ idx ][ plane_D ] > 0 )
|
||||
continue;
|
||||
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
|
||||
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
|
||||
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
|
||||
+ m_frustum[ idx ][ plane_D ] > 0 )
|
||||
continue;
|
||||
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
|
||||
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
|
||||
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
|
||||
+ m_frustum[ idx ][ plane_D ] > 0 )
|
||||
continue;
|
||||
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
|
||||
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
|
||||
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
|
||||
+ m_frustum[ idx ][ plane_D ] > 0 )
|
||||
continue;
|
||||
// the cube is inside unless all of its corners lie behind one of the frustum planes
|
||||
return std::ranges::all_of( m_frustum, [&]( auto const &frustumplane ) {
|
||||
if( frustumplane[ plane_A ] * ( X - Size )
|
||||
+ frustumplane[ plane_B ] * ( Y - Size )
|
||||
+ frustumplane[ plane_C ] * ( Z - Size )
|
||||
+ frustumplane[ plane_D ] > 0 )
|
||||
return true;
|
||||
if( frustumplane[ plane_A ] * ( X + Size )
|
||||
+ frustumplane[ plane_B ] * ( Y - Size )
|
||||
+ frustumplane[ plane_C ] * ( Z - Size )
|
||||
+ frustumplane[ plane_D ] > 0 )
|
||||
return true;
|
||||
if( frustumplane[ plane_A ] * ( X - Size )
|
||||
+ frustumplane[ plane_B ] * ( Y + Size )
|
||||
+ frustumplane[ plane_C ] * ( Z - Size )
|
||||
+ frustumplane[ plane_D ] > 0 )
|
||||
return true;
|
||||
if( frustumplane[ plane_A ] * ( X + Size )
|
||||
+ frustumplane[ plane_B ] * ( Y + Size )
|
||||
+ frustumplane[ plane_C ] * ( Z - Size )
|
||||
+ frustumplane[ plane_D ] > 0 )
|
||||
return true;
|
||||
if( frustumplane[ plane_A ] * ( X - Size )
|
||||
+ frustumplane[ plane_B ] * ( Y - Size )
|
||||
+ frustumplane[ plane_C ] * ( Z + Size )
|
||||
+ frustumplane[ plane_D ] > 0 )
|
||||
return true;
|
||||
if( frustumplane[ plane_A ] * ( X + Size )
|
||||
+ frustumplane[ plane_B ] * ( Y - Size )
|
||||
+ frustumplane[ plane_C ] * ( Z + Size )
|
||||
+ frustumplane[ plane_D ] > 0 )
|
||||
return true;
|
||||
if( frustumplane[ plane_A ] * ( X - Size )
|
||||
+ frustumplane[ plane_B ] * ( Y + Size )
|
||||
+ frustumplane[ plane_C ] * ( Z + Size )
|
||||
+ frustumplane[ plane_D ] > 0 )
|
||||
return true;
|
||||
if( frustumplane[ plane_A ] * ( X + Size )
|
||||
+ frustumplane[ plane_B ] * ( Y + Size )
|
||||
+ frustumplane[ plane_C ] * ( Z + Size )
|
||||
+ frustumplane[ plane_D ] > 0 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false; } );
|
||||
}
|
||||
|
||||
void cFrustum::normalize_plane( cFrustum::side const Side ) {
|
||||
|
||||
@@ -29,12 +29,7 @@ light_array::insert( TDynamicObject const *Owner ) {
|
||||
void
|
||||
light_array::remove( TDynamicObject const *Owner ) {
|
||||
|
||||
data.erase(
|
||||
std::remove_if(
|
||||
data.begin(),
|
||||
data.end(),
|
||||
[=]( light_record const &light ){ return light.owner == Owner; } ),
|
||||
data.end() );
|
||||
std::erase_if( data, [=]( light_record const &light ){ return light.owner == Owner; } );
|
||||
}
|
||||
|
||||
// updates records in the collection
|
||||
@@ -75,13 +70,13 @@ light_array::update() {
|
||||
|
||||
light.intensity = std::max(0.0f, std::log((float)light.count + 1.0f));
|
||||
if (light.owner->DimHeadlights && !light.owner->HighBeamLights && isEnabled) // tylko przyciemnione
|
||||
light.intensity *= light.owner->MoverParameters->dimMultiplier;
|
||||
light.intensity *= static_cast<float>(light.owner->MoverParameters->dimMultiplier);
|
||||
else if (!light.owner->DimHeadlights && !light.owner->HighBeamLights && isEnabled) // normalne
|
||||
light.intensity *= light.owner->MoverParameters->normMultiplier;
|
||||
light.intensity *= static_cast<float>(light.owner->MoverParameters->normMultiplier);
|
||||
else if (light.owner->DimHeadlights && light.owner->HighBeamLights && isEnabled) // przyciemnione dlugie
|
||||
light.intensity *= light.owner->MoverParameters->highDimMultiplier;
|
||||
light.intensity *= static_cast<float>(light.owner->MoverParameters->highDimMultiplier);
|
||||
else if (!light.owner->DimHeadlights && light.owner->HighBeamLights && isEnabled) // dlugie zwykle
|
||||
light.intensity *= light.owner->MoverParameters->highMultiplier;
|
||||
light.intensity *= static_cast<float>(light.owner->MoverParameters->highMultiplier);
|
||||
else if (!isEnabled)
|
||||
{
|
||||
light.intensity = 0.0f;
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
update();
|
||||
|
||||
// types
|
||||
typedef std::vector<light_record> lightrecord_array;
|
||||
using lightrecord_array = std::vector<light_record>;
|
||||
|
||||
// members
|
||||
lightrecord_array data;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
std::unique_ptr<gfx_renderer> null_renderer::create_func()
|
||||
{
|
||||
return std::unique_ptr<null_renderer>(new null_renderer());
|
||||
return std::make_unique<null_renderer>();
|
||||
}
|
||||
|
||||
bool null_renderer::renderer_register = gfx_renderer_factory::get_instance()->register_backend("null", null_renderer::create_func);
|
||||
|
||||
@@ -17,22 +17,22 @@ public:
|
||||
// constructors:
|
||||
null_geometrybank() = default;
|
||||
// destructor
|
||||
~null_geometrybank() {};
|
||||
~null_geometrybank() = default;
|
||||
|
||||
private:
|
||||
// methods:
|
||||
// create() subclass details
|
||||
void
|
||||
create_( gfx::geometry_handle const &Geometry ) override {}
|
||||
create_( gfx::geometry_handle const &Geometry ) override { /* null implementation, nothing to do */ }
|
||||
// replace() subclass details
|
||||
void
|
||||
replace_( gfx::geometry_handle const &Geometry ) override {}
|
||||
replace_( gfx::geometry_handle const &Geometry ) override { /* null implementation, nothing to do */ }
|
||||
// draw() subclass details
|
||||
auto
|
||||
draw_( gfx::geometry_handle const &Geometry, gfx::stream_units const &Units, unsigned int const Streams ) -> std::size_t override { return 0; }
|
||||
// release() subclass details
|
||||
void
|
||||
release_() override {}
|
||||
release_() override { /* null implementation, nothing to do */ }
|
||||
};
|
||||
|
||||
// bare-bones render controller, in lack of anything better yet
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
// constructors
|
||||
null_renderer() = default;
|
||||
// destructor
|
||||
~null_renderer() { }
|
||||
~null_renderer() = default;
|
||||
// methods
|
||||
bool
|
||||
Init( GLFWwindow *Window ) override { return true; }
|
||||
@@ -51,14 +51,14 @@ public:
|
||||
bool
|
||||
Render() override { return true; }
|
||||
void
|
||||
SwapBuffers() override {}
|
||||
SwapBuffers() override { /* null implementation, nothing to do */ }
|
||||
inline
|
||||
float
|
||||
Framerate() override { return 10.0f; }
|
||||
|
||||
bool AddViewport(const global_settings::extraviewport_config &conf) override { return false; }
|
||||
bool Debug_Ui_State(std::optional<bool>) override { return false; }
|
||||
void Shutdown() override {}
|
||||
void Shutdown() override { /* null implementation, nothing to do */ }
|
||||
|
||||
// geometry methods
|
||||
// NOTE: hands-on geometry management is exposed as a temporary measure; ultimately all visualization data should be generated/handled automatically by the renderer itself
|
||||
@@ -100,10 +100,10 @@ public:
|
||||
Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override {
|
||||
m_materials.push_back(std::make_shared<opengl_material>());
|
||||
m_materials.back()->name = Filename;
|
||||
return m_materials.size();
|
||||
return static_cast<material_handle>(m_materials.size());
|
||||
}
|
||||
void
|
||||
Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) override {}
|
||||
Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) override { /* null implementation, nothing to do */ }
|
||||
IMaterial const *
|
||||
Material( material_handle const Material ) const override { return m_materials.at(Material - 1).get(); }
|
||||
// shader methods
|
||||
@@ -112,18 +112,18 @@ public:
|
||||
texture_handle
|
||||
Fetch_Texture( std::string const &Filename, bool const Loadnow = true, GLint format_hint = GL_SRGB_ALPHA ) override { throw std::runtime_error("not impl"); }
|
||||
void
|
||||
Bind_Texture( texture_handle const Texture ) override {}
|
||||
Bind_Texture( texture_handle const Texture ) override { /* null implementation, nothing to do */ }
|
||||
void
|
||||
Bind_Texture( std::size_t const Unit, texture_handle const Texture ) override {}
|
||||
Bind_Texture( std::size_t const Unit, texture_handle const Texture ) override { /* null implementation, nothing to do */ }
|
||||
opengl_texture &
|
||||
Texture( texture_handle const Texture ) override { throw std::runtime_error("not impl"); }
|
||||
opengl_texture const &
|
||||
Texture( texture_handle const Texture ) const override { throw std::runtime_error("not impl"); }
|
||||
// utility methods
|
||||
void
|
||||
Pick_Control_Callback( std::function<void( TSubModel const *, const glm::vec2 )> Callback ) override {}
|
||||
Pick_Control_Callback( std::function<void( TSubModel const *, const glm::vec2 )> Callback ) override { /* null implementation, nothing to do */ }
|
||||
void
|
||||
Pick_Node_Callback( std::function<void( scene::basic_node * )> Callback ) override {}
|
||||
Pick_Node_Callback( std::function<void( scene::basic_node * )> Callback ) override { /* null implementation, nothing to do */ }
|
||||
TSubModel const *
|
||||
Pick_Control() const override { return nullptr; }
|
||||
scene::basic_node const *
|
||||
@@ -132,11 +132,11 @@ public:
|
||||
Mouse_Position() const override { return glm::dvec3(); }
|
||||
// maintenance methods
|
||||
void
|
||||
Update( double const Deltatime ) override {}
|
||||
Update( double const Deltatime ) override { /* null implementation, nothing to do */ }
|
||||
void
|
||||
Update_Pick_Control() override {}
|
||||
Update_Pick_Control() override { /* null implementation, nothing to do */ }
|
||||
void
|
||||
Update_Pick_Node() override {}
|
||||
Update_Pick_Node() override { /* null implementation, nothing to do */ }
|
||||
glm::dvec3
|
||||
Update_Mouse_Position() override { return glm::dvec3(); }
|
||||
// debug methods
|
||||
@@ -144,13 +144,13 @@ public:
|
||||
info_times() const override { return empty_str; }
|
||||
std::string const &
|
||||
info_stats() const override { return empty_str; }
|
||||
void MakeScreenshot() override {}
|
||||
void MakeScreenshot() override { /* null implementation, nothing to do */ }
|
||||
|
||||
static std::unique_ptr<gfx_renderer> create_func();
|
||||
|
||||
static bool renderer_register;
|
||||
|
||||
virtual imgui_renderer *GetImguiRenderer()
|
||||
imgui_renderer *GetImguiRenderer() override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ void opengl33_light::apply_intensity(float const Factor) {
|
||||
factor = Factor;
|
||||
}
|
||||
|
||||
void opengl33_light::apply_angle() {}
|
||||
void opengl33_light::apply_angle() const { /* nothing to do */ }
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -18,7 +18,7 @@ struct opengl33_light : public basic_light {
|
||||
float factor;
|
||||
|
||||
void apply_intensity(float const Factor = 1.0f);
|
||||
void apply_angle();
|
||||
void apply_angle() const;
|
||||
|
||||
opengl33_light &operator=(basic_light const &Right) {
|
||||
basic_light::operator=(Right);
|
||||
|
||||
@@ -49,19 +49,19 @@ opengl33_particles::update( opengl_camera const &Camera ) {
|
||||
// build billboard data for particles from visible sources
|
||||
auto const camerarotation { glm::mat3( Camera.modelview() ) };
|
||||
particle_vertex vertex;
|
||||
for( auto const &source : sources ) {
|
||||
for( auto const &[sourcekey, sourcedata] : sources ) {
|
||||
|
||||
auto const particlecolor {
|
||||
glm::clamp(
|
||||
source.second.color()
|
||||
sourcedata.color()
|
||||
* ( glm::vec3 { Global.DayLight.ambient }
|
||||
+ 0.35f * glm::vec3{ Global.DayLight.diffuse } ) * simulation::Environment.light_intensity(),
|
||||
glm::vec3{ 0.f }, glm::vec3{ 1.f } ) };
|
||||
auto const &particles { source.second.sequence() };
|
||||
auto const &particles { sourcedata.sequence() };
|
||||
// TODO: put sanity cap on the overall amount of particles that can be drawn
|
||||
auto const sizestep { 256.0 * billboard_vertices.size() };
|
||||
m_particlevertices.reserve(
|
||||
sizestep * std::ceil( m_particlevertices.size() + ( particles.size() * billboard_vertices.size() ) / sizestep ) );
|
||||
static_cast<std::size_t>( sizestep * std::ceil( static_cast<double>(m_particlevertices.size()) + ( static_cast<double>(particles.size() * billboard_vertices.size()) ) / sizestep ) ) );
|
||||
for( auto const &particle : particles ) {
|
||||
// TODO: particle color support
|
||||
vertex.color[ 0 ] = particlecolor.r;
|
||||
@@ -72,9 +72,9 @@ opengl33_particles::update( opengl_camera const &Camera ) {
|
||||
auto const offset { glm::vec3{ particle.position - Camera.position() } };
|
||||
auto const rotation { glm::angleAxis( particle.rotation, glm::vec3{ 0.f, 0.f, 1.f } ) };
|
||||
|
||||
for( auto const &billboardvertex : billboard_vertices ) {
|
||||
vertex.position = offset + ( rotation * billboardvertex.first * particle.size ) * camerarotation;
|
||||
vertex.texture = billboardvertex.second;
|
||||
for( auto const &[billboardoffset, billboardtexture] : billboard_vertices ) {
|
||||
vertex.position = offset + ( rotation * billboardoffset * particle.size ) * camerarotation;
|
||||
vertex.texture = billboardtexture;
|
||||
|
||||
m_particlevertices.emplace_back( vertex );
|
||||
}
|
||||
@@ -113,14 +113,14 @@ opengl33_particles::render() {
|
||||
m_vao->setup_attrib(*m_buffer, 1, 4, GL_FLOAT, sizeof(particle_vertex), 12);
|
||||
m_vao->setup_attrib(*m_buffer, 2, 2, GL_FLOAT, sizeof(particle_vertex), 28);
|
||||
|
||||
m_buffer->unbind(gl::buffer::ARRAY_BUFFER);
|
||||
m_vao->unbind();
|
||||
gl::buffer::unbind(gl::buffer::ARRAY_BUFFER);
|
||||
gl::vao::unbind();
|
||||
}
|
||||
|
||||
if (!m_shader) {
|
||||
gl::shader vert("smoke.vert");
|
||||
gl::shader frag("smoke.frag");
|
||||
gl::program *prog = new gl::program({vert, frag});
|
||||
auto prog = new gl::program({vert, frag});
|
||||
m_shader = std::unique_ptr<gl::program>(prog);
|
||||
}
|
||||
|
||||
@@ -128,11 +128,11 @@ opengl33_particles::render() {
|
||||
m_shader->bind();
|
||||
m_vao->bind();
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, m_particlevertices.size());
|
||||
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(m_particlevertices.size()));
|
||||
|
||||
m_shader->unbind();
|
||||
m_vao->unbind();
|
||||
m_buffer->unbind(gl::buffer::ARRAY_BUFFER);
|
||||
gl::program::unbind();
|
||||
gl::vao::unbind();
|
||||
gl::buffer::unbind(gl::buffer::ARRAY_BUFFER);
|
||||
|
||||
return m_particlevertices.size() / 6;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ opengl33_precipitation::create( int const Tesselation ) {
|
||||
std::uint16_t index = 0;
|
||||
|
||||
// auto const radius { 25.f }; // cylinder radius
|
||||
std::vector<float> radii { 25.f, 10.f, 5.f, 1.f };
|
||||
std::vector radii { 25.f, 10.f, 5.f, 1.f };
|
||||
for( auto radius : radii ) {
|
||||
|
||||
for( int i = 0; i <= latitudes; ++i ) {
|
||||
@@ -121,7 +121,7 @@ opengl33_precipitation::update() {
|
||||
m_indexbuffer->upload(gl::buffer::ELEMENT_ARRAY_BUFFER, m_indices.data(), 0, m_indices.size() * sizeof( unsigned short ));
|
||||
m_vao->setup_ebo(*m_indexbuffer);
|
||||
|
||||
m_vao->unbind();
|
||||
gl::vao::unbind();
|
||||
// NOTE: vertex and index source data is superfluous past this point, but, eh
|
||||
}
|
||||
|
||||
@@ -155,5 +155,5 @@ opengl33_precipitation::render() {
|
||||
|
||||
::glDrawElements( GL_TRIANGLES, static_cast<GLsizei>( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast<void const*>( 0 ) );
|
||||
|
||||
m_vao->unbind();
|
||||
gl::vao::unbind();
|
||||
}
|
||||
|
||||
@@ -44,15 +44,13 @@ void opengl33_skydome::update() {
|
||||
m_indexbuffer->upload(gl::buffer::ELEMENT_ARRAY_BUFFER, skydome.indices().data(), 0, skydome.indices().size() * sizeof( unsigned short ));
|
||||
m_vao->setup_ebo(*m_indexbuffer);
|
||||
|
||||
m_vao->unbind();
|
||||
gl::vao::unbind();
|
||||
}
|
||||
// ship the current dynamic data to the gpu
|
||||
if( true == skydome.is_dirty() ) {
|
||||
if( m_coloursbuffer ) {
|
||||
// the colour buffer was already initialized, so on this run we update its content
|
||||
m_coloursbuffer->upload( gl::buffer::ARRAY_BUFFER, skydome.colors().data(), 0, skydome.colors().size() * sizeof( glm::vec3 ) );
|
||||
skydome.is_dirty() = false;
|
||||
}
|
||||
if (true == skydome.is_dirty() && m_coloursbuffer) {
|
||||
// the colour buffer was already initialized, so on this run we update its content
|
||||
m_coloursbuffer->upload( gl::buffer::ARRAY_BUFFER, skydome.colors().data(), 0, skydome.colors().size() * sizeof( glm::vec3 ) );
|
||||
skydome.is_dirty() = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
// constructors
|
||||
opengl33_skydome() = default;
|
||||
// destructor
|
||||
~opengl33_skydome() {;}
|
||||
~opengl33_skydome() = default;
|
||||
// methods
|
||||
// updates data stores on the opengl end. NOTE: unbinds buffers
|
||||
void update();
|
||||
|
||||
@@ -38,7 +38,7 @@ opengl_camera::visible( TDynamicObject const *Dynamic ) const {
|
||||
|
||||
// sphere test is faster than AABB, so we'll use it here
|
||||
// we're giving vehicles some extra padding, to allow for things like shared bogeys extending past the main body
|
||||
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), Dynamic->radius() * 1.25 ) > 0.0f );
|
||||
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), static_cast<float>(Dynamic->radius() * 1.25) ) > 0.0f );
|
||||
}
|
||||
|
||||
// debug helper, draws shape of frustum in world space
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
update_frustum() { update_frustum( m_projection, m_modelview ); }
|
||||
inline
|
||||
void
|
||||
update_frustum(glm::mat4 frustumtest_proj) {
|
||||
update_frustum(glm::mat4 const &frustumtest_proj) {
|
||||
update_frustum(frustumtest_proj, m_modelview); }
|
||||
void
|
||||
update_frustum( glm::mat4 const &Projection, glm::mat4 const &Modelview );
|
||||
|
||||
@@ -90,23 +90,23 @@ opengl_vbogeometrybank::draw_( gfx::geometry_handle const &Geometry, gfx::stream
|
||||
}
|
||||
::glDrawRangeElementsBaseVertex(
|
||||
chunk.type,
|
||||
0, chunkrecord.vertex_count,
|
||||
chunkrecord.index_count, GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
|
||||
chunkrecord.vertex_offset );
|
||||
0, static_cast<GLuint>(chunkrecord.vertex_count),
|
||||
static_cast<GLsizei>(chunkrecord.index_count), GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
|
||||
static_cast<GLint>(chunkrecord.vertex_offset) );
|
||||
}
|
||||
else {
|
||||
bind_streams( Units, Streams, chunkrecord.vertex_offset );
|
||||
::glDrawRangeElements(
|
||||
chunk.type,
|
||||
0, chunkrecord.vertex_count,
|
||||
chunkrecord.index_count, GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ) );
|
||||
0, static_cast<GLuint>(chunkrecord.vertex_count),
|
||||
static_cast<GLsizei>(chunkrecord.index_count), GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( m_activestreams != Streams ) {
|
||||
bind_streams( Units, Streams );
|
||||
}
|
||||
::glDrawArrays( chunk.type, chunkrecord.vertex_offset, chunkrecord.vertex_count );
|
||||
::glDrawArrays( chunk.type, static_cast<GLint>(chunkrecord.vertex_offset), static_cast<GLsizei>(chunkrecord.vertex_count) );
|
||||
}
|
||||
// ...post-render cleanup
|
||||
/*
|
||||
@@ -139,9 +139,8 @@ opengl_vbogeometrybank::setup_buffer() {
|
||||
// may be better to initiate upload earlier (during update phase) and trust this effort won't go to waste
|
||||
if( true == m_chunks.empty() ) { return; }
|
||||
|
||||
std::size_t
|
||||
vertexcount{ 0 },
|
||||
indexcount{ 0 };
|
||||
std::size_t vertexcount{ 0 };
|
||||
std::size_t indexcount{ 0 };
|
||||
auto chunkiterator = m_chunks.cbegin();
|
||||
for( auto &chunkrecord : m_chunkrecords ) {
|
||||
// fill records for all chunks, based on the chunk data
|
||||
@@ -195,7 +194,7 @@ opengl_vbogeometrybank::setup_buffer() {
|
||||
}
|
||||
|
||||
void
|
||||
opengl_vbogeometrybank::bind_buffer() {
|
||||
opengl_vbogeometrybank::bind_buffer() const {
|
||||
|
||||
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
|
||||
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );
|
||||
|
||||
@@ -58,7 +58,7 @@ private:
|
||||
void
|
||||
setup_buffer();
|
||||
void
|
||||
bind_buffer();
|
||||
bind_buffer() const;
|
||||
void
|
||||
delete_buffer();
|
||||
static
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
opengl_dlgeometrybank() = default;
|
||||
// destructor:
|
||||
~opengl_dlgeometrybank() {
|
||||
for( auto &chunkrecord : m_chunkrecords ) {
|
||||
for( auto const &chunkrecord : m_chunkrecords ) {
|
||||
::glDeleteLists( chunkrecord.list, 1 ); } }
|
||||
|
||||
private:
|
||||
|
||||
@@ -90,7 +90,7 @@ private:
|
||||
};
|
||||
|
||||
enum stack_mode { gl_modelview = 0, gl_projection = 1, gl_texture = 2 };
|
||||
typedef std::vector<opengl_stack> openglstack_array;
|
||||
using openglstack_array = std::vector<opengl_stack>;
|
||||
|
||||
public:
|
||||
// constructors:
|
||||
|
||||
@@ -47,19 +47,19 @@ opengl_particles::update( opengl_camera const &Camera ) {
|
||||
// build billboard data for particles from visible sources
|
||||
auto const camerarotation { glm::mat3( Camera.modelview() ) };
|
||||
particle_vertex vertex;
|
||||
for( auto const &source : sources ) {
|
||||
for( auto const &[sourcekey, sourcedata] : sources ) {
|
||||
|
||||
auto const particlecolor {
|
||||
glm::clamp(
|
||||
source.second.color()
|
||||
sourcedata.color()
|
||||
* ( glm::vec3 { Global.DayLight.ambient } + 0.35f * glm::vec3{ Global.DayLight.diffuse } )
|
||||
* 255.f,
|
||||
glm::vec3{ 0.f }, glm::vec3{ 255.f } ) };
|
||||
auto const &particles { source.second.sequence() };
|
||||
auto const &particles { sourcedata.sequence() };
|
||||
// TODO: put sanity cap on the overall amount of particles that can be drawn
|
||||
auto const sizestep { 256.0 * billboard_vertices.size() };
|
||||
m_particlevertices.reserve(
|
||||
sizestep * std::ceil( m_particlevertices.size() + ( particles.size() * billboard_vertices.size() ) / sizestep ) );
|
||||
static_cast<std::size_t>( sizestep * std::ceil( static_cast<double>(m_particlevertices.size()) + ( static_cast<double>(particles.size() * billboard_vertices.size()) ) / sizestep ) ) );
|
||||
for( auto const &particle : particles ) {
|
||||
// TODO: particle color support
|
||||
vertex.color[ 0 ] = static_cast<std::uint_fast8_t>( particlecolor.r );
|
||||
@@ -70,9 +70,9 @@ opengl_particles::update( opengl_camera const &Camera ) {
|
||||
auto const offset { glm::vec3{ particle.position - Camera.position() } };
|
||||
auto const rotation { glm::angleAxis( particle.rotation, glm::vec3{ 0.f, 0.f, 1.f } ) };
|
||||
|
||||
for( auto const &billboardvertex : billboard_vertices ) {
|
||||
vertex.position = offset + ( rotation * billboardvertex.first * particle.size ) * camerarotation;
|
||||
vertex.texture = billboardvertex.second;
|
||||
for( auto const &[billboardoffset, billboardtexture] : billboard_vertices ) {
|
||||
vertex.position = offset + ( rotation * billboardoffset * particle.size ) * camerarotation;
|
||||
vertex.texture = billboardtexture;
|
||||
|
||||
m_particlevertices.emplace_back( vertex );
|
||||
}
|
||||
@@ -147,7 +147,7 @@ opengl_particles::render( GLint const Textureunit ) {
|
||||
::glTexCoordPointer( 2, GL_FLOAT, sizeof( particle_vertex ), reinterpret_cast<void const *>( sizeof( float ) * 3 + sizeof( std::uint8_t ) * 4 ) );
|
||||
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
|
||||
// ...draw...
|
||||
::glDrawArrays( GL_QUADS, 0, m_particlevertices.size() );
|
||||
::glDrawArrays( GL_QUADS, 0, static_cast<GLsizei>(m_particlevertices.size()) );
|
||||
// ...and cleanup
|
||||
::glPopClientAttrib();
|
||||
::glBindBuffer( GL_ARRAY_BUFFER, 0 );
|
||||
|
||||
@@ -39,7 +39,7 @@ opengl_precipitation::create( int const Tesselation ) {
|
||||
std::uint16_t index = 0;
|
||||
|
||||
// auto const radius { 25.f }; // cylinder radius
|
||||
std::vector<float> radii { 25.f, 10.f, 5.f, 1.f };
|
||||
std::vector radii { 25.f, 10.f, 5.f, 1.f };
|
||||
for( auto radius : radii ) {
|
||||
|
||||
for( int i = 0; i <= latitudes; ++i ) {
|
||||
|
||||
@@ -54,20 +54,18 @@ void opengl_skydome::update() {
|
||||
}
|
||||
// ship the current dynamic data to the gpu
|
||||
// TODO: ship the data if it changed since the last update
|
||||
if( true == skydome.is_dirty() ) {
|
||||
if( ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 ) ) {
|
||||
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
|
||||
auto &colors{ skydome.colors() };
|
||||
/*
|
||||
float twilightfactor = std::clamp( -simulation::Environment.sun().getAngle(), 0.0f, 18.0f ) / 18.0f;
|
||||
auto gamma = std::lerp( glm::vec3( 0.45f ), glm::vec3( 1.0f ), twilightfactor );
|
||||
for( auto & color : colors ) {
|
||||
color = glm::pow( color, gamma );
|
||||
}
|
||||
*/
|
||||
::glBufferSubData( GL_ARRAY_BUFFER, 0, colors.size() * sizeof( glm::vec3 ), colors.data() );
|
||||
skydome.is_dirty() = false;
|
||||
if (true == skydome.is_dirty() && ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 )) {
|
||||
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
|
||||
auto &colors{ skydome.colors() };
|
||||
/*
|
||||
float twilightfactor = std::clamp( -simulation::Environment.sun().getAngle(), 0.0f, 18.0f ) / 18.0f;
|
||||
auto gamma = std::lerp( glm::vec3( 0.45f ), glm::vec3( 1.0f ), twilightfactor );
|
||||
for( auto & color : colors ) {
|
||||
color = glm::pow( color, gamma );
|
||||
}
|
||||
*/
|
||||
::glBufferSubData( GL_ARRAY_BUFFER, 0, colors.size() * sizeof( glm::vec3 ), colors.data() );
|
||||
skydome.is_dirty() = false;
|
||||
}
|
||||
// cleanup
|
||||
::glPopClientAttrib();
|
||||
|
||||
@@ -56,7 +56,7 @@ smoke_source::particle_emitter::deserialize( cParser &Input ) {
|
||||
}
|
||||
|
||||
void
|
||||
smoke_source::particle_emitter::initialize( smoke_particle &Particle ) {
|
||||
smoke_source::particle_emitter::initialize( smoke_particle &Particle ) const {
|
||||
|
||||
auto const polarangle { glm::radians( LocalRandom( inclination[ value_limit::min ], inclination[ value_limit::max ] ) ) }; // theta
|
||||
auto const azimuthalangle { glm::radians( LocalRandom( -180, 180 ) ) }; // phi
|
||||
@@ -69,9 +69,9 @@ smoke_source::particle_emitter::initialize( smoke_particle &Particle ) {
|
||||
|
||||
Particle.velocity = launchvector * launchvelocity;
|
||||
|
||||
Particle.rotation = glm::radians( LocalRandom( 0, 360 ) );
|
||||
Particle.size = LocalRandom( size[ value_limit::min ], size[ value_limit::max ] );
|
||||
Particle.opacity = LocalRandom( opacity[ value_limit::min ], opacity[ value_limit::max ] ) / Global.SmokeFidelity;
|
||||
Particle.rotation = static_cast<float>(glm::radians( LocalRandom( 0, 360 ) ));
|
||||
Particle.size = static_cast<float>(LocalRandom( size[ value_limit::min ], size[ value_limit::max ] ));
|
||||
Particle.opacity = static_cast<float>(LocalRandom( opacity[ value_limit::min ], opacity[ value_limit::max ] ) / Global.SmokeFidelity);
|
||||
Particle.age = 0;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ smoke_source::deserialize( cParser &Input ) {
|
||||
if( false == Input.ok() ) { return false; }
|
||||
|
||||
while( true == deserialize_mapping( Input ) ) {
|
||||
; // all work done by while()
|
||||
// all work done by while()
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -166,8 +166,8 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
||||
( ( false == Global.Smoke ) || ( true == Onlydespawn ) ) ?
|
||||
0.f :
|
||||
std::min<float>(
|
||||
m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
|
||||
m_max_particles ) );
|
||||
static_cast<float>(m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity )),
|
||||
static_cast<float>(m_max_particles) ) );
|
||||
// consider special spawn rate cases
|
||||
if( m_ownertype == owner_type::vehicle ) {
|
||||
|
||||
@@ -183,7 +183,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
||||
0.f :
|
||||
std::min<float>(
|
||||
// m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
|
||||
m_spawncount +(m_spawnrate * Timedelta * Global.SmokeFidelity * (((m_owner.vehicle->MoverParameters->enrot) / 4 ) * 0.01)), m_max_particles);
|
||||
static_cast<float>(m_spawncount +(m_spawnrate * Timedelta * Global.SmokeFidelity * (((m_owner.vehicle->MoverParameters->enrot) / 4 ) * 0.01))), static_cast<float>(m_max_particles));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -195,7 +195,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
||||
0.f :
|
||||
std::min<float>(
|
||||
// m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
|
||||
m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) *0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005))), m_max_particles);
|
||||
static_cast<float>(m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) *0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005)))), static_cast<float>(m_max_particles));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -205,7 +205,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
||||
0.f :
|
||||
std::min<float>(
|
||||
// m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
|
||||
m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) * (sqrt(m_owner.vehicle->MoverParameters->Im) * 0.01) * 0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005))), m_max_particles);
|
||||
static_cast<float>(m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) * (sqrt(m_owner.vehicle->MoverParameters->Im) * 0.01) * 0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005)))), static_cast<float>(m_max_particles));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -254,10 +254,8 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
||||
// if we still have pending requests after filling entire container replace older particles
|
||||
if( m_spawncount >= 1.f ) {
|
||||
// sort all particles from most to least transparent, oldest to youngest if it's a tie
|
||||
std::sort(
|
||||
std::begin( m_particles ),
|
||||
std::end( m_particles ),
|
||||
[]( smoke_particle const &Left, smoke_particle const &Right ) {
|
||||
std::ranges::sort(
|
||||
m_particles, []( smoke_particle const &Left, smoke_particle const &Right ) {
|
||||
return ( Left.opacity != Right.opacity ?
|
||||
Left.opacity < Right.opacity :
|
||||
Left.age > Right.age ); } );
|
||||
@@ -283,7 +281,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
|
||||
// determine bounding area from calculated bounding box
|
||||
if( false == m_particles.empty() ) {
|
||||
m_area.center = glm::mix(boundingbox[value_limit::min], boundingbox[value_limit::max], 0.5);
|
||||
m_area.radius = 0.5 * ( glm::length( boundingbox[ value_limit::max ] - boundingbox[ value_limit::min ] ) );
|
||||
m_area.radius = static_cast<float>(0.5 * ( glm::length( boundingbox[ value_limit::max ] - boundingbox[ value_limit::min ] ) ));
|
||||
}
|
||||
else {
|
||||
m_area.center = location();
|
||||
@@ -331,10 +329,9 @@ smoke_source::initialize( smoke_particle &Particle ) {
|
||||
Particle.position = location();
|
||||
|
||||
if( m_ownertype == owner_type::vehicle ) {
|
||||
Particle.opacity *= m_owner.vehicle->MoverParameters->dizel_fill;
|
||||
auto const enginerevolutionsfactor { 1.5f }; // high engine revolutions increase initial particle velocity
|
||||
switch( m_owner.vehicle->MoverParameters->EngineType ) {
|
||||
case TEngineType::DieselElectric: {
|
||||
Particle.opacity *= static_cast<float>(m_owner.vehicle->MoverParameters->dizel_fill);
|
||||
if (m_owner.vehicle->MoverParameters->EngineType == TEngineType::DieselElectric)
|
||||
{
|
||||
if (m_owner.vehicle->MoverParameters->dizel_spinup == true)
|
||||
{
|
||||
Particle.velocity *= 0.38*(((m_owner.vehicle->MoverParameters->enrot)/2)*0.5); // / m_owner.vehicle->MoverParameters->dizel_fill *0.01)) ;
|
||||
@@ -347,11 +344,6 @@ smoke_source::initialize( smoke_particle &Particle ) {
|
||||
//Particle.velocity *= m_owner.vehicle->GetVelocity(); // / m_owner.vehicle->MoverParameters->dizel_fill *0.01)) ;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -368,28 +360,23 @@ smoke_source::update( smoke_particle &Particle, bounding_box &Boundingbox, doubl
|
||||
|
||||
// crude smoke dispersion simulation
|
||||
// http://www.auburn.edu/academic/forestry_wildlife/fire/smoke_guide/smoke_dispersion.htm
|
||||
switch (m_ownertype)
|
||||
if (m_ownertype == owner_type::vehicle)
|
||||
{
|
||||
case owner_type::vehicle:
|
||||
Particle.velocity.y += static_cast<float>(( 0.025 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 90 ) * Timedelta); // decelerate faster in cold weather
|
||||
Particle.velocity.y -= static_cast<float>(( (0.05 * (pow(m_owner.vehicle->GetVelocity()*1,0.4))) * Particle.velocity.y ) * Global.Overcast * Timedelta); // decelerate faster with high air humidity and/or precipitation
|
||||
}
|
||||
else
|
||||
{
|
||||
Particle.velocity.y += ( 0.025 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 90 ) * Timedelta; // decelerate faster in cold weather
|
||||
Particle.velocity.y -= ( (0.05 * (pow(m_owner.vehicle->GetVelocity()*1,0.4))) * Particle.velocity.y ) * Global.Overcast * Timedelta; // decelerate faster with high air humidity and/or precipitation
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Particle.velocity.y += ( 0.005 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 10 ) * Timedelta; // decelerate faster in cold weather
|
||||
Particle.velocity.y -= ( 0.050 * Particle.velocity.y ) * Global.Overcast * Timedelta; // decelerate faster with high air humidity and/or precipitation
|
||||
Particle.velocity.y = std::max<float>( 0.25 * ( 2.f - Global.Overcast ), Particle.velocity.y ); // put a cap on deceleration
|
||||
break;
|
||||
}
|
||||
}
|
||||
Particle.velocity.y += static_cast<float>(( 0.005 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 10 ) * Timedelta); // decelerate faster in cold weather
|
||||
Particle.velocity.y -= static_cast<float>(( 0.050 * Particle.velocity.y ) * Global.Overcast * Timedelta); // decelerate faster with high air humidity and/or precipitation
|
||||
Particle.velocity.y = std::max<float>( static_cast<float>(0.25 * ( 2.f - Global.Overcast )), Particle.velocity.y ); // put a cap on deceleration
|
||||
}
|
||||
|
||||
Particle.position += Particle.velocity * static_cast<float>( Timedelta );
|
||||
Particle.position += 0.1f * Particle.age * simulation::Environment.wind() * static_cast<float>( Timedelta );
|
||||
// m_velocitymodifier.update( Particle.velocity, Timedelta );
|
||||
|
||||
Particle.age += Timedelta;
|
||||
Particle.age += static_cast<float>(Timedelta);
|
||||
|
||||
// update bounding box
|
||||
Boundingbox[ value_limit::min ] = glm::min( Boundingbox[ value_limit::min ], Particle.position - glm::dvec3{ Particle.size } );
|
||||
@@ -467,21 +454,19 @@ particle_manager::find( std::string const &Template ) {
|
||||
auto const templatename { ToLower( Template ) };
|
||||
|
||||
// try to locate specified rail profile...
|
||||
auto const lookup { m_sourcetemplates.find( templatename ) };
|
||||
if( lookup != m_sourcetemplates.end() ) {
|
||||
if( auto const lookup { m_sourcetemplates.find( templatename ) }; lookup != m_sourcetemplates.end() ) {
|
||||
// ...if it works, we're done...
|
||||
return &(lookup->second);
|
||||
}
|
||||
// ... and if it fails try to add the template to the database from a data file
|
||||
smoke_source source;
|
||||
cParser parser(templatepath + templatename + ".txt", cParser::buffer_FILE);
|
||||
|
||||
if (source.deserialize(parser))
|
||||
if (cParser parser(templatepath + templatename + ".txt", cParser::buffer_FILE); source.deserialize(parser))
|
||||
{
|
||||
// if deserialization didn't fail finish source setup...
|
||||
source.m_opacitymodifier.bind( &Global.SmokeFidelity );
|
||||
// ...then cache the source as template for future instances
|
||||
m_sourcetemplates.emplace( templatename, source );
|
||||
m_sourcetemplates.try_emplace( templatename, source );
|
||||
// should be 'safe enough' to return lookup result directly afterwards
|
||||
return &( m_sourcetemplates.find( templatename )->second );
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
return (
|
||||
m_valuechangemodifier == nullptr ?
|
||||
m_valuechange :
|
||||
m_valuechange / *( m_valuechangemodifier ) ); }
|
||||
m_valuechange / *m_valuechangemodifier ); }
|
||||
|
||||
private:
|
||||
//types
|
||||
@@ -122,7 +122,7 @@ private:
|
||||
glm::vec3 color { 16.f / 255.f };
|
||||
|
||||
void deserialize( cParser &Input );
|
||||
void initialize( smoke_particle &Particle );
|
||||
void initialize( smoke_particle &Particle ) const;
|
||||
};
|
||||
|
||||
using bounding_box = glm::dvec3[ 2 ]; // bounding box of owned particles
|
||||
@@ -212,7 +212,7 @@ fixedstep_modifier<Type_>::update( Type_ &Variable, double const Timedelta ) con
|
||||
auto const valuechange { (
|
||||
m_valuechangemodifier == nullptr ?
|
||||
m_valuechange :
|
||||
m_valuechange / *( m_valuechangemodifier ) ) };
|
||||
m_valuechange / *m_valuechangemodifier ) };
|
||||
Variable += ( valuechange * static_cast<float>( Timedelta ) );
|
||||
// clamp down to allowed value range
|
||||
Variable = glm::max( Variable, m_valuelimits[ value_limit::min ] );
|
||||
|
||||
@@ -29,9 +29,9 @@ void screenshot_manager::screenshot_save_thread( char *img, int w, int h )
|
||||
stride = -w * 3;
|
||||
}
|
||||
|
||||
char datetime[64];
|
||||
std::array<char, 64> datetime{};
|
||||
std::tm const tm_info = local_tm(std::time(nullptr));
|
||||
strftime(datetime, 64, "%Y-%m-%d_%H-%M-%S", &tm_info);
|
||||
strftime(datetime.data(), datetime.size(), "%Y-%m-%d_%H-%M-%S", &tm_info);
|
||||
|
||||
uint64_t perf;
|
||||
#ifdef _WIN32
|
||||
@@ -42,7 +42,7 @@ void screenshot_manager::screenshot_save_thread( char *img, int w, int h )
|
||||
perf = ts.tv_nsec;
|
||||
#endif
|
||||
|
||||
std::string filename = Global.screenshot_dir + "/" + std::string(datetime) +
|
||||
std::string filename = Global.screenshot_dir + "/" + std::string(datetime.data()) +
|
||||
"_" + std::to_string(perf) + ".png";
|
||||
|
||||
if (png_image_write_to_file(&png, filename.c_str(), 0, img, stride, nullptr) == 1)
|
||||
@@ -55,7 +55,7 @@ void screenshot_manager::screenshot_save_thread( char *img, int w, int h )
|
||||
|
||||
void screenshot_manager::make_screenshot()
|
||||
{
|
||||
char *img = new char[Global.fb_size.x * Global.fb_size.y * 4];
|
||||
auto img = new char[Global.fb_size.x * Global.fb_size.y * 4];
|
||||
glReadPixels(0, 0, Global.fb_size.x, Global.fb_size.y, Global.gfx_usegles ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);
|
||||
//m7t: use pbo
|
||||
|
||||
|
||||
@@ -50,9 +50,8 @@ basic_editor::translate( scene::basic_node *Node, glm::dvec3 const &Location, bo
|
||||
// TODO: contextual switch between group and item translation
|
||||
// TODO: translation of affected/relevant events
|
||||
auto &nodegroup { scene::Groups.group( Node->group() ).nodes };
|
||||
std::for_each(
|
||||
std::begin( nodegroup ), std::end( nodegroup ),
|
||||
[&]( auto *node ) {
|
||||
std::ranges::for_each(
|
||||
nodegroup, [&]( auto *node ) {
|
||||
translate_node( node, node->location() + translation ); } );
|
||||
}
|
||||
}
|
||||
@@ -72,9 +71,8 @@ basic_editor::translate( scene::basic_node *Node, float const Offset ) {
|
||||
// TODO: contextual switch between group and item translation
|
||||
// TODO: translation of affected/relevant events
|
||||
auto &nodegroup { scene::Groups.group( Node->group() ).nodes };
|
||||
std::for_each(
|
||||
std::begin( nodegroup ), std::end( nodegroup ),
|
||||
[&]( auto *node ) {
|
||||
std::ranges::for_each(
|
||||
nodegroup, [&]( auto *node ) {
|
||||
translate_node( node, offset ); } );
|
||||
}
|
||||
}
|
||||
@@ -102,7 +100,7 @@ basic_editor::translate_node( scene::basic_node *Node, float const Offset ) {
|
||||
}
|
||||
|
||||
void
|
||||
basic_editor::translate_instance( TAnimModel *Instance, glm::dvec3 const &Location ) {
|
||||
basic_editor::translate_instance( TAnimModel *Instance, glm::dvec3 const &Location ) const {
|
||||
|
||||
simulation::Region->erase( Instance );
|
||||
Instance->location( Location );
|
||||
@@ -110,7 +108,7 @@ basic_editor::translate_instance( TAnimModel *Instance, glm::dvec3 const &Locati
|
||||
}
|
||||
|
||||
void
|
||||
basic_editor::translate_instance( TAnimModel *Instance, float const Offset ) {
|
||||
basic_editor::translate_instance( TAnimModel *Instance, float const Offset ) const {
|
||||
|
||||
auto location { Instance->location() };
|
||||
location.y += Offset;
|
||||
@@ -118,7 +116,7 @@ basic_editor::translate_instance( TAnimModel *Instance, float const Offset ) {
|
||||
}
|
||||
|
||||
void
|
||||
basic_editor::translate_memorycell( TMemCell *Memorycell, glm::dvec3 const &Location ) {
|
||||
basic_editor::translate_memorycell( TMemCell *Memorycell, glm::dvec3 const &Location ) const {
|
||||
|
||||
simulation::Region->erase( Memorycell );
|
||||
Memorycell->location( Location );
|
||||
@@ -126,7 +124,7 @@ basic_editor::translate_memorycell( TMemCell *Memorycell, glm::dvec3 const &Loca
|
||||
}
|
||||
|
||||
void
|
||||
basic_editor::translate_memorycell( TMemCell *Memorycell, float const Offset ) {
|
||||
basic_editor::translate_memorycell( TMemCell *Memorycell, float const Offset ) const {
|
||||
|
||||
auto location { Memorycell->location() };
|
||||
location.y += Offset;
|
||||
@@ -161,9 +159,8 @@ basic_editor::rotate( scene::basic_node *Node, glm::vec3 const &Angle, float con
|
||||
// TODO: translation of affected/relevant events
|
||||
auto const &rotationcenter { Node->location() };
|
||||
auto const &nodegroup { scene::Groups.group( Node->group() ).nodes };
|
||||
std::for_each(
|
||||
std::begin( nodegroup ), std::end( nodegroup ),
|
||||
[&]( auto *node ) {
|
||||
std::ranges::for_each(
|
||||
nodegroup, [&]( auto *node ) {
|
||||
rotate_node( node, rotation );
|
||||
if( node != Node ) {
|
||||
translate_node(
|
||||
@@ -184,7 +181,7 @@ basic_editor::rotate_node( scene::basic_node *Node, glm::vec3 const &Angle ) {
|
||||
}
|
||||
|
||||
void
|
||||
basic_editor::rotate_instance( TAnimModel *Instance, glm::vec3 const &Angle ) {
|
||||
basic_editor::rotate_instance( TAnimModel *Instance, glm::vec3 const &Angle ) const {
|
||||
|
||||
auto targetangle { Instance->Angles() + Angle };
|
||||
|
||||
|
||||
@@ -19,14 +19,13 @@ struct node_snapshot {
|
||||
scene::basic_node *node;
|
||||
std::string data;
|
||||
|
||||
node_snapshot( scene::basic_node *Node ) :
|
||||
explicit node_snapshot( scene::basic_node *Node ) :
|
||||
node( Node ) {
|
||||
if( Node != nullptr ) {
|
||||
Node->export_as_text( data ); } };
|
||||
};
|
||||
|
||||
inline bool operator==( node_snapshot const &Left, node_snapshot const &Right ) { return Left.node == Right.node && Left.data == Right.data; }
|
||||
inline bool operator!=( node_snapshot const &Left, node_snapshot const &Right ) { return !(Left == Right); }
|
||||
|
||||
class basic_editor {
|
||||
|
||||
@@ -46,17 +45,17 @@ private:
|
||||
void
|
||||
translate_node( scene::basic_node *Node, float const Offset );
|
||||
void
|
||||
translate_instance( TAnimModel *Instance, glm::dvec3 const &Location );
|
||||
translate_instance( TAnimModel *Instance, glm::dvec3 const &Location ) const;
|
||||
void
|
||||
translate_instance( TAnimModel *Instance, float const Offset );
|
||||
translate_instance( TAnimModel *Instance, float const Offset ) const;
|
||||
void
|
||||
translate_memorycell( TMemCell *Memorycell, glm::dvec3 const &Location );
|
||||
translate_memorycell( TMemCell *Memorycell, glm::dvec3 const &Location ) const;
|
||||
void
|
||||
translate_memorycell( TMemCell *Memorycell, float const Offset );
|
||||
translate_memorycell( TMemCell *Memorycell, float const Offset ) const;
|
||||
void
|
||||
rotate_node( scene::basic_node *Node, glm::vec3 const &Angle );
|
||||
void
|
||||
rotate_instance( TAnimModel *Instance, glm::vec3 const &Angle );
|
||||
rotate_instance( TAnimModel *Instance, glm::vec3 const &Angle ) const;
|
||||
};
|
||||
|
||||
} // scene
|
||||
|
||||
@@ -16,17 +16,17 @@ static_assert(-1 == ~0, "Two's complement required");
|
||||
// deserialize little endian uint16
|
||||
uint16_t sn_utils::ld_uint16(std::istream &s)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
s.read((char*)buf, 2);
|
||||
uint16_t v = buf[1] << 8 | buf[0];
|
||||
std::array<uint8_t, 2> buf{};
|
||||
s.read(reinterpret_cast<char *>(buf.data()), buf.size());
|
||||
auto v = static_cast<uint16_t>(buf[1] << 8 | buf[0]);
|
||||
return v;
|
||||
}
|
||||
|
||||
// deserialize little endian uint32
|
||||
uint32_t sn_utils::ld_uint32(std::istream &s)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
s.read((char*)buf, 4);
|
||||
std::array<uint8_t, 4> buf{};
|
||||
s.read(reinterpret_cast<char *>(buf.data()), buf.size());
|
||||
uint32_t v = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
|
||||
return v;
|
||||
}
|
||||
@@ -34,8 +34,8 @@ uint32_t sn_utils::ld_uint32(std::istream &s)
|
||||
// deserialize little endian int32
|
||||
int32_t sn_utils::ld_int32(std::istream &s)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
s.read((char*)buf, 4);
|
||||
std::array<uint8_t, 4> buf{};
|
||||
s.read(reinterpret_cast<char *>(buf.data()), buf.size());
|
||||
uint32_t v = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
|
||||
return static_cast<int32_t>(v);
|
||||
}
|
||||
@@ -43,8 +43,8 @@ int32_t sn_utils::ld_int32(std::istream &s)
|
||||
// deserialize little endian uint64
|
||||
uint64_t sn_utils::ld_uint64(std::istream &s)
|
||||
{
|
||||
uint8_t buf[8];
|
||||
s.read((char*)buf, 8);
|
||||
std::array<uint8_t, 8> buf{};
|
||||
s.read(reinterpret_cast<char *>(buf.data()), buf.size());
|
||||
uint64_t v = (uint64_t)buf[7] << 56 | (uint64_t)buf[6] << 48 |
|
||||
(uint64_t)buf[5] << 40 | (uint64_t)buf[4] << 32 |
|
||||
(uint64_t)buf[3] << 24 | (uint64_t)buf[2] << 16 |
|
||||
@@ -55,8 +55,8 @@ uint64_t sn_utils::ld_uint64(std::istream &s)
|
||||
// deserialize little endian int64
|
||||
int64_t sn_utils::ld_int64(std::istream &s)
|
||||
{
|
||||
uint8_t buf[8];
|
||||
s.read((char*)buf, 8);
|
||||
std::array<uint8_t, 8> buf{};
|
||||
s.read(reinterpret_cast<char *>(buf.data()), buf.size());
|
||||
uint64_t v = (uint64_t)buf[7] << 56 | (uint64_t)buf[6] << 48 |
|
||||
(uint64_t)buf[5] << 40 | (uint64_t)buf[4] << 32 |
|
||||
(uint64_t)buf[3] << 24 | (uint64_t)buf[2] << 16 |
|
||||
@@ -67,8 +67,8 @@ int64_t sn_utils::ld_int64(std::istream &s)
|
||||
// deserialize little endian ieee754 float32
|
||||
float sn_utils::ld_float32(std::istream &s)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
s.read((char*)buf, 4);
|
||||
std::array<uint8_t, 4> buf{};
|
||||
s.read(reinterpret_cast<char *>(buf.data()), buf.size());
|
||||
uint32_t v = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
|
||||
return std::bit_cast<float>(v);
|
||||
}
|
||||
@@ -76,8 +76,8 @@ float sn_utils::ld_float32(std::istream &s)
|
||||
// deserialize little endian ieee754 float64
|
||||
double sn_utils::ld_float64(std::istream &s)
|
||||
{
|
||||
uint8_t buf[8];
|
||||
s.read((char*)buf, 8);
|
||||
std::array<uint8_t, 8> buf{};
|
||||
s.read(reinterpret_cast<char *>(buf.data()), buf.size());
|
||||
uint64_t v = (uint64_t)buf[7] << 56 | (uint64_t)buf[6] << 48 |
|
||||
(uint64_t)buf[5] << 40 | (uint64_t)buf[4] << 32 |
|
||||
(uint64_t)buf[3] << 24 | (uint64_t)buf[2] << 16 |
|
||||
@@ -90,13 +90,13 @@ std::string sn_utils::d_str(std::istream &s)
|
||||
{
|
||||
std::string r;
|
||||
r.reserve(32);
|
||||
char buf[1];
|
||||
char c{};
|
||||
while (true)
|
||||
{
|
||||
s.read(buf, 1);
|
||||
if (buf[0] == 0)
|
||||
s.read(&c, 1);
|
||||
if (c == 0)
|
||||
break;
|
||||
r.push_back(buf[0]);
|
||||
r.push_back(c);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -141,84 +141,84 @@ uint8_t sn_utils::d_uint8( std::istream& s ) {
|
||||
|
||||
void sn_utils::ls_uint16(std::ostream &s, uint16_t v)
|
||||
{
|
||||
uint8_t buf[2];
|
||||
buf[0] = v;
|
||||
std::array<uint8_t, 2> buf{};
|
||||
buf[0] = static_cast<uint8_t>(v);
|
||||
buf[1] = v >> 8;
|
||||
s.write((char*)buf, 2);
|
||||
s.write(reinterpret_cast<char const *>(buf.data()), buf.size());
|
||||
}
|
||||
|
||||
void sn_utils::ls_uint32(std::ostream &s, uint32_t v)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
buf[0] = v;
|
||||
buf[1] = v >> 8;
|
||||
buf[2] = v >> 16;
|
||||
std::array<uint8_t, 4> buf{};
|
||||
buf[0] = static_cast<uint8_t>(v);
|
||||
buf[1] = static_cast<uint8_t>(v >> 8);
|
||||
buf[2] = static_cast<uint8_t>(v >> 16);
|
||||
buf[3] = v >> 24;
|
||||
s.write((char*)buf, 4);
|
||||
s.write(reinterpret_cast<char const *>(buf.data()), buf.size());
|
||||
}
|
||||
|
||||
void sn_utils::ls_int32(std::ostream &s, int32_t v)
|
||||
{
|
||||
uint8_t buf[4];
|
||||
buf[0] = v;
|
||||
buf[1] = v >> 8;
|
||||
buf[2] = v >> 16;
|
||||
std::array<uint8_t, 4> buf{};
|
||||
buf[0] = static_cast<uint8_t>(v);
|
||||
buf[1] = static_cast<uint8_t>(v >> 8);
|
||||
buf[2] = static_cast<uint8_t>(v >> 16);
|
||||
buf[3] = v >> 24;
|
||||
s.write((char*)buf, 4);
|
||||
s.write(reinterpret_cast<char const *>(buf.data()), buf.size());
|
||||
}
|
||||
|
||||
void sn_utils::ls_uint64(std::ostream &s, uint64_t v)
|
||||
{
|
||||
uint8_t buf[8];
|
||||
buf[0] = v;
|
||||
buf[1] = v >> 8;
|
||||
buf[2] = v >> 16;
|
||||
buf[3] = v >> 24;
|
||||
buf[4] = v >> 32;
|
||||
buf[5] = v >> 40;
|
||||
buf[6] = v >> 48;
|
||||
std::array<uint8_t, 8> buf{};
|
||||
buf[0] = static_cast<uint8_t>(v);
|
||||
buf[1] = static_cast<uint8_t>(v >> 8);
|
||||
buf[2] = static_cast<uint8_t>(v >> 16);
|
||||
buf[3] = static_cast<uint8_t>(v >> 24);
|
||||
buf[4] = static_cast<uint8_t>(v >> 32);
|
||||
buf[5] = static_cast<uint8_t>(v >> 40);
|
||||
buf[6] = static_cast<uint8_t>(v >> 48);
|
||||
buf[7] = v >> 56;
|
||||
s.write((char*)buf, 8);
|
||||
s.write(reinterpret_cast<char const *>(buf.data()), buf.size());
|
||||
}
|
||||
|
||||
void sn_utils::ls_int64(std::ostream &s, int64_t v)
|
||||
{
|
||||
uint8_t buf[8];
|
||||
buf[0] = v;
|
||||
buf[1] = v >> 8;
|
||||
buf[2] = v >> 16;
|
||||
buf[3] = v >> 24;
|
||||
buf[4] = v >> 32;
|
||||
buf[5] = v >> 40;
|
||||
buf[6] = v >> 48;
|
||||
std::array<uint8_t, 8> buf{};
|
||||
buf[0] = static_cast<uint8_t>(v);
|
||||
buf[1] = static_cast<uint8_t>(v >> 8);
|
||||
buf[2] = static_cast<uint8_t>(v >> 16);
|
||||
buf[3] = static_cast<uint8_t>(v >> 24);
|
||||
buf[4] = static_cast<uint8_t>(v >> 32);
|
||||
buf[5] = static_cast<uint8_t>(v >> 40);
|
||||
buf[6] = static_cast<uint8_t>(v >> 48);
|
||||
buf[7] = v >> 56;
|
||||
s.write((char*)buf, 8);
|
||||
s.write(reinterpret_cast<char const *>(buf.data()), buf.size());
|
||||
}
|
||||
|
||||
void sn_utils::ls_float32(std::ostream &s, float t)
|
||||
{
|
||||
uint32_t v = std::bit_cast<uint32_t>(t);
|
||||
uint8_t buf[4];
|
||||
buf[0] = v;
|
||||
buf[1] = v >> 8;
|
||||
buf[2] = v >> 16;
|
||||
auto v = std::bit_cast<uint32_t>(t);
|
||||
std::array<uint8_t, 4> buf{};
|
||||
buf[0] = static_cast<uint8_t>(v);
|
||||
buf[1] = static_cast<uint8_t>(v >> 8);
|
||||
buf[2] = static_cast<uint8_t>(v >> 16);
|
||||
buf[3] = v >> 24;
|
||||
s.write((char*)buf, 4);
|
||||
s.write(reinterpret_cast<char const *>(buf.data()), buf.size());
|
||||
}
|
||||
|
||||
void sn_utils::ls_float64(std::ostream &s, double t)
|
||||
{
|
||||
uint64_t v = std::bit_cast<uint64_t>(t);
|
||||
uint8_t buf[8];
|
||||
buf[0] = v;
|
||||
buf[1] = v >> 8;
|
||||
buf[2] = v >> 16;
|
||||
buf[3] = v >> 24;
|
||||
buf[4] = v >> 32;
|
||||
buf[5] = v >> 40;
|
||||
buf[6] = v >> 48;
|
||||
auto v = std::bit_cast<uint64_t>(t);
|
||||
std::array<uint8_t, 8> buf{};
|
||||
buf[0] = static_cast<uint8_t>(v);
|
||||
buf[1] = static_cast<uint8_t>(v >> 8);
|
||||
buf[2] = static_cast<uint8_t>(v >> 16);
|
||||
buf[3] = static_cast<uint8_t>(v >> 24);
|
||||
buf[4] = static_cast<uint8_t>(v >> 32);
|
||||
buf[5] = static_cast<uint8_t>(v >> 40);
|
||||
buf[6] = static_cast<uint8_t>(v >> 48);
|
||||
buf[7] = v >> 56;
|
||||
s.write((char*)buf, 8);
|
||||
s.write(reinterpret_cast<char const *>(buf.data()), buf.size());
|
||||
}
|
||||
|
||||
void sn_utils::s_uint8(std::ostream &s, uint8_t v)
|
||||
@@ -226,7 +226,7 @@ void sn_utils::s_uint8(std::ostream &s, uint8_t v)
|
||||
s.write((char*)&v, 1);
|
||||
}
|
||||
|
||||
void sn_utils::s_str(std::ostream &s, std::string v)
|
||||
void sn_utils::s_str(std::ostream &s, std::string const &v)
|
||||
{
|
||||
const char* buf = v.c_str();
|
||||
s.write(buf, v.size() + 1);
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
static void ls_float32(std::ostream&, float);
|
||||
static void ls_float64(std::ostream&, double);
|
||||
static void s_uint8(std::ostream&, uint8_t);
|
||||
static void s_str(std::ostream&, std::string);
|
||||
static void s_str(std::ostream&, std::string const &);
|
||||
static void s_bool(std::ostream&, bool);
|
||||
static void s_dvec3(std::ostream&, glm::dvec3 const &);
|
||||
static void s_vec3(std::ostream&, glm::vec3 const &);
|
||||
|
||||
@@ -30,36 +30,36 @@ void render_task::run()
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
for (auto const &datapair : m_input->floats)
|
||||
for (auto const &[dataname, datavalue] : m_input->floats)
|
||||
{
|
||||
auto *value{PyGetFloat(datapair.second)};
|
||||
auto *value{PyGetFloat(datavalue)};
|
||||
if (value == nullptr)
|
||||
{
|
||||
PyErr_Clear();
|
||||
continue;
|
||||
}
|
||||
PyDict_SetItemString(input, datapair.first.c_str(), value);
|
||||
PyDict_SetItemString(input, dataname.c_str(), value);
|
||||
Py_DECREF(value);
|
||||
}
|
||||
for (auto const &datapair : m_input->integers)
|
||||
for (auto const &[dataname, datavalue] : m_input->integers)
|
||||
{
|
||||
auto *value{PyLong_FromLong(datapair.second)};
|
||||
auto *value{PyLong_FromLong(datavalue)};
|
||||
if (value == nullptr)
|
||||
{
|
||||
PyErr_Clear();
|
||||
continue;
|
||||
}
|
||||
PyDict_SetItemString(input, datapair.first.c_str(), value);
|
||||
PyDict_SetItemString(input, dataname.c_str(), value);
|
||||
Py_DECREF(value);
|
||||
}
|
||||
for (auto const &datapair : m_input->bools)
|
||||
for (auto const &[dataname, datavalue] : m_input->bools)
|
||||
{
|
||||
// Py_True / Py_False sa niesmiertelne, ale PyDict_SetItemString i tak
|
||||
// pobiera wlasna referencje - nie zwalniamy
|
||||
auto *value{PyGetBool(datapair.second)};
|
||||
PyDict_SetItemString(input, datapair.first.c_str(), value);
|
||||
auto *value{PyGetBool(datavalue)};
|
||||
PyDict_SetItemString(input, dataname.c_str(), value);
|
||||
}
|
||||
for (auto const &datapair : m_input->strings)
|
||||
for (auto const &[dataname, datavalue] : m_input->strings)
|
||||
{
|
||||
// Nazwy scenerii/wagonow (asName, SceneryFile, asCarName, cCode...) moga
|
||||
// byc albo w UTF-8, albo w starym kodowaniu Windows-1250. PyUnicode_FromString
|
||||
@@ -68,8 +68,8 @@ void render_task::run()
|
||||
//
|
||||
// Strategia: najpierw probujemy UTF-8 (strict). Jesli sie nie uda - probujemy
|
||||
// cp1250. Jesli oba zawioda - pomijamy klucz, ale nie wywracamy symulatora.
|
||||
char const *const str{datapair.second.c_str()};
|
||||
Py_ssize_t const len{static_cast<Py_ssize_t>(datapair.second.size())};
|
||||
char const *const str{datavalue.c_str()};
|
||||
Py_ssize_t const len{static_cast<Py_ssize_t>(datavalue.size())};
|
||||
|
||||
auto *value{PyUnicode_DecodeUTF8(str, len, "strict")};
|
||||
if (value == nullptr)
|
||||
@@ -82,16 +82,16 @@ void render_task::run()
|
||||
PyErr_Clear();
|
||||
continue;
|
||||
}
|
||||
PyDict_SetItemString(input, datapair.first.c_str(), value);
|
||||
PyDict_SetItemString(input, dataname.c_str(), value);
|
||||
Py_DECREF(value);
|
||||
}
|
||||
for (auto const &datapair : m_input->vec2_lists)
|
||||
for (auto const &[dataname, datavalue] : m_input->vec2_lists)
|
||||
{
|
||||
PyObject *list = PyList_New(datapair.second.size());
|
||||
PyObject *list = PyList_New(datavalue.size());
|
||||
|
||||
for (size_t i = 0; i < datapair.second.size(); i++)
|
||||
for (size_t i = 0; i < datavalue.size(); i++)
|
||||
{
|
||||
auto const &vec = datapair.second[i];
|
||||
auto const &vec = datavalue[i];
|
||||
WriteLog("passing " + glm::to_string(vec));
|
||||
|
||||
PyObject *tuple = PyTuple_New(2);
|
||||
@@ -101,24 +101,24 @@ void render_task::run()
|
||||
PyList_SetItem(list, i, tuple); // steals ref
|
||||
}
|
||||
|
||||
PyDict_SetItemString(input, datapair.first.c_str(), list);
|
||||
PyDict_SetItemString(input, dataname.c_str(), list);
|
||||
Py_DECREF(list);
|
||||
}
|
||||
m_input = nullptr;
|
||||
|
||||
// call the renderer
|
||||
auto *output{PyObject_CallMethod(m_renderer, const_cast<char *>("render"), const_cast<char *>("O"), input)};
|
||||
auto *output{PyObject_CallMethod(m_renderer, "render", "O", input)};
|
||||
Py_DECREF(input);
|
||||
|
||||
if (output != nullptr)
|
||||
{
|
||||
auto *outputWidth = PyObject_CallMethod(m_renderer, const_cast<char *>("get_width"), nullptr);
|
||||
auto *outputHeight = PyObject_CallMethod(m_renderer, const_cast<char *>("get_height"), nullptr);
|
||||
auto *outputWidth = PyObject_CallMethod(m_renderer, "get_width", nullptr);
|
||||
auto *outputHeight = PyObject_CallMethod(m_renderer, "get_height", nullptr);
|
||||
|
||||
if (outputWidth != nullptr && outputHeight != nullptr && m_target != nullptr)
|
||||
{
|
||||
const int screenWidth = static_cast<int>(PyLong_AsLong(outputWidth));
|
||||
const int screenHeight = static_cast<int>(PyLong_AsLong(outputHeight));
|
||||
const auto screenWidth = static_cast<int>(PyLong_AsLong(outputWidth));
|
||||
const auto screenHeight = static_cast<int>(PyLong_AsLong(outputHeight));
|
||||
|
||||
const bool useRgb = false && !Global.gfx_usegles;
|
||||
|
||||
@@ -166,7 +166,7 @@ void render_task::run()
|
||||
}
|
||||
|
||||
// get commands from renderer
|
||||
auto *commandsPO = PyObject_CallMethod(m_renderer, const_cast<char *>("getCommands"), nullptr);
|
||||
auto *commandsPO = PyObject_CallMethod(m_renderer, "getCommands", nullptr);
|
||||
if (commandsPO != nullptr)
|
||||
{
|
||||
std::vector<std::string> commands = python_external_utils::PyObjectToStringArray(commandsPO);
|
||||
@@ -178,10 +178,10 @@ void render_task::run()
|
||||
for (const auto &cmd : commands)
|
||||
{
|
||||
std::string baseCmd;
|
||||
int p1 = 0, p2 = 0;
|
||||
int p1 = 0;
|
||||
int p2 = 0;
|
||||
|
||||
size_t pos1 = cmd.find(';');
|
||||
if (pos1 == std::string::npos)
|
||||
if (size_t pos1 = cmd.find(';'); pos1 == std::string::npos)
|
||||
{
|
||||
baseCmd = cmd;
|
||||
}
|
||||
@@ -224,7 +224,7 @@ void render_task::run()
|
||||
}
|
||||
}
|
||||
|
||||
void render_task::upload()
|
||||
void render_task::upload() const
|
||||
{
|
||||
if (Global.python_uploadmain && m_target && m_target->shared_tex)
|
||||
{
|
||||
@@ -232,7 +232,7 @@ void render_task::upload()
|
||||
}
|
||||
}
|
||||
|
||||
void render_task::cancel() {}
|
||||
void render_task::cancel() const { /* nothing to do */ }
|
||||
|
||||
// initializes the module. returns true on success
|
||||
auto python_taskqueue::init() -> bool
|
||||
@@ -310,7 +310,7 @@ auto python_taskqueue::init() -> bool
|
||||
stringiomodule = PyImport_ImportModule("io");
|
||||
stringioclassname = stringiomodule != nullptr ? PyObject_GetAttrString(stringiomodule, "StringIO") : nullptr;
|
||||
stringioobject = stringioclassname != nullptr ? PyObject_CallObject(stringioclassname, nullptr) : nullptr;
|
||||
m_stderr = {(stringioobject == nullptr ? nullptr : PySys_SetObject(const_cast<char *>("stderr"), stringioobject) != 0 ? nullptr : stringioobject)};
|
||||
m_stderr = {(stringioobject == nullptr ? nullptr : PySys_SetObject("stderr", stringioobject) != 0 ? nullptr : stringioobject)};
|
||||
|
||||
if (false == run_file("abstractscreenrenderer"))
|
||||
{
|
||||
@@ -362,23 +362,23 @@ void python_taskqueue::exit()
|
||||
// document intent. clearing the deque also actually releases the tasks,
|
||||
// which the previous code did not do (cancel() is a no-op stub).
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_tasks.mutex);
|
||||
for (auto &task : m_tasks.data)
|
||||
std::scoped_lock lock(m_tasks.mutex);
|
||||
for (auto const &task : m_tasks.data)
|
||||
{
|
||||
task->cancel();
|
||||
}
|
||||
m_tasks.data.clear();
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_uploadtasks.mutex);
|
||||
std::scoped_lock lock(m_uploadtasks.mutex);
|
||||
m_uploadtasks.data.clear();
|
||||
}
|
||||
// reclaim cached python objects while the interpreter is still alive,
|
||||
// so no Py_DECREF lands on a finalized interpreter during later teardown
|
||||
acquire_lock();
|
||||
for (auto &entry : m_renderers)
|
||||
for (auto const &[renderername, rendererobject] : m_renderers)
|
||||
{
|
||||
Py_XDECREF(entry.second);
|
||||
Py_XDECREF(rendererobject);
|
||||
}
|
||||
m_renderers.clear();
|
||||
Py_XDECREF(m_stderr);
|
||||
@@ -394,7 +394,7 @@ void python_taskqueue::exit()
|
||||
auto python_taskqueue::insert(task_request const &Task) -> bool
|
||||
{
|
||||
|
||||
if (!m_initialized || false == Global.python_enabled || Task.renderer.empty() || Task.input == nullptr || Task.target == 0)
|
||||
if (!m_initialized || false == Global.python_enabled || Task.renderer.empty() || Task.input == nullptr || Task.target == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -409,7 +409,7 @@ auto python_taskqueue::insert(task_request const &Task) -> bool
|
||||
bool newtaskinserted{false};
|
||||
// acquire a lock on the task queue and add the new task
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_tasks.mutex);
|
||||
std::scoped_lock lock(m_tasks.mutex);
|
||||
// check the task list for a pending request with the same target
|
||||
for (auto &task : m_tasks.data)
|
||||
{
|
||||
@@ -437,13 +437,13 @@ auto python_taskqueue::insert(task_request const &Task) -> bool
|
||||
auto python_taskqueue::run_file(std::string const &File, std::string const &Path) -> bool
|
||||
{
|
||||
|
||||
auto const lookup{FileExists({Path + File, "python/local/" + File}, {".py"})};
|
||||
if (lookup.first.empty())
|
||||
auto const [filepath, fileextension]{FileExists({Path + File, "python/local/" + File}, {".py"})};
|
||||
if (filepath.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ifstream inputfile{lookup.first + lookup.second};
|
||||
std::ifstream inputfile{filepath + fileextension};
|
||||
std::string input;
|
||||
input.assign(std::istreambuf_iterator<char>(inputfile), std::istreambuf_iterator<char>());
|
||||
|
||||
@@ -464,17 +464,16 @@ void python_taskqueue::acquire_lock()
|
||||
}
|
||||
|
||||
// releases the python gil and swaps the main thread out
|
||||
void python_taskqueue::release_lock()
|
||||
void python_taskqueue::release_lock() const
|
||||
{
|
||||
|
||||
PyEval_SaveThread();
|
||||
}
|
||||
|
||||
auto python_taskqueue::fetch_renderer(std::string const Renderer) -> PyObject *
|
||||
auto python_taskqueue::fetch_renderer(std::string const &Renderer) -> PyObject *
|
||||
{
|
||||
|
||||
auto const lookup{m_renderers.find(Renderer)};
|
||||
if (lookup != std::end(m_renderers))
|
||||
if (auto const lookup{m_renderers.find(Renderer)}; lookup != std::end(m_renderers))
|
||||
{
|
||||
return lookup->second;
|
||||
}
|
||||
@@ -510,7 +509,7 @@ auto python_taskqueue::fetch_renderer(std::string const Renderer) -> PyObject *
|
||||
}
|
||||
renderer = PyObject_CallObject(renderername, rendererarguments);
|
||||
|
||||
PyObject_CallMethod(renderer, const_cast<char *>("manul_set_format"), const_cast<char *>("(s)"), "RGBA");
|
||||
PyObject_CallMethod(renderer, "manul_set_format", "(s)", "RGBA");
|
||||
|
||||
if (PyErr_Occurred() != nullptr)
|
||||
{
|
||||
@@ -527,11 +526,11 @@ auto python_taskqueue::fetch_renderer(std::string const Renderer) -> PyObject *
|
||||
}
|
||||
release_lock();
|
||||
// cache the failures as well so we don't try again on subsequent requests
|
||||
m_renderers.emplace(Renderer, renderer);
|
||||
m_renderers.try_emplace(Renderer, renderer);
|
||||
return renderer;
|
||||
}
|
||||
|
||||
void python_taskqueue::run(GLFWwindow *Context, rendertask_sequence &Tasks, uploadtask_sequence &Upload_Tasks, threading::condition_variable &Condition, std::atomic<bool> &Exit)
|
||||
void python_taskqueue::run(GLFWwindow *Context, rendertask_sequence &Tasks, uploadtask_sequence &Upload_Tasks, threading::condition_variable &Condition, std::atomic<bool> const &Exit)
|
||||
{
|
||||
|
||||
if (Context)
|
||||
@@ -554,7 +553,7 @@ void python_taskqueue::run(GLFWwindow *Context, rendertask_sequence &Tasks, uplo
|
||||
task = nullptr;
|
||||
// acquire a lock on the task queue and potentially grab a task from it
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Tasks.mutex);
|
||||
std::scoped_lock lock(Tasks.mutex);
|
||||
if (false == Tasks.data.empty())
|
||||
{
|
||||
// fifo
|
||||
@@ -573,7 +572,7 @@ void python_taskqueue::run(GLFWwindow *Context, rendertask_sequence &Tasks, uplo
|
||||
task->upload();
|
||||
else
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(Upload_Tasks.mutex);
|
||||
std::scoped_lock lock(Upload_Tasks.mutex);
|
||||
Upload_Tasks.data.push_back(task);
|
||||
}
|
||||
if (PyErr_Occurred() != nullptr)
|
||||
@@ -608,9 +607,9 @@ void python_taskqueue::run(GLFWwindow *Context, rendertask_sequence &Tasks, uplo
|
||||
|
||||
void python_taskqueue::update()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_uploadtasks.mutex);
|
||||
std::scoped_lock lock(m_uploadtasks.mutex);
|
||||
|
||||
for (auto &task : m_uploadtasks.data)
|
||||
for (auto const &task : m_uploadtasks.data)
|
||||
task->upload();
|
||||
|
||||
m_uploadtasks.data.clear();
|
||||
@@ -622,21 +621,21 @@ void python_taskqueue::error()
|
||||
{
|
||||
// std err pythona jest buforowane
|
||||
PyErr_Print();
|
||||
auto *errortext{PyObject_CallMethod(m_stderr, const_cast<char *>("getvalue"), nullptr)};
|
||||
if (errortext != nullptr)
|
||||
if (auto *errortext{PyObject_CallMethod(m_stderr, "getvalue", nullptr)}; errortext != nullptr)
|
||||
{
|
||||
const char *errstr = PyUnicode_AsUTF8(errortext);
|
||||
if (errstr != nullptr)
|
||||
if (const char *errstr = PyUnicode_AsUTF8(errortext); errstr != nullptr)
|
||||
ErrorLog(errstr);
|
||||
Py_DECREF(errortext);
|
||||
}
|
||||
PyObject_CallMethod(m_stderr, const_cast<char *>("truncate"), const_cast<char *>("L"), (long long)0);
|
||||
PyObject_CallMethod(m_stderr, const_cast<char *>("seek"), const_cast<char *>("L"), (long long)0);
|
||||
PyObject_CallMethod(m_stderr, "truncate", "L", (long long)0);
|
||||
PyObject_CallMethod(m_stderr, "seek", "L", (long long)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// nie dziala buffor pythona
|
||||
PyObject *type, *value, *traceback;
|
||||
PyObject *type;
|
||||
PyObject *value;
|
||||
PyObject *traceback;
|
||||
PyErr_Fetch(&type, &value, &traceback);
|
||||
if (type == nullptr)
|
||||
{
|
||||
@@ -647,11 +646,9 @@ void python_taskqueue::error()
|
||||
{
|
||||
ErrorLog("Python Interpreter: don't know how to handle null exception");
|
||||
}
|
||||
auto *typetext{PyObject_Str(type)};
|
||||
if (typetext != nullptr)
|
||||
if (auto *typetext{PyObject_Str(type)}; typetext != nullptr)
|
||||
{
|
||||
const char *s = PyUnicode_AsUTF8(typetext);
|
||||
if (s)
|
||||
if (const char *s = PyUnicode_AsUTF8(typetext); s)
|
||||
ErrorLog(s);
|
||||
Py_DECREF(typetext);
|
||||
}
|
||||
@@ -660,8 +657,7 @@ void python_taskqueue::error()
|
||||
auto *valuetext{PyObject_Str(value)};
|
||||
if (valuetext != nullptr)
|
||||
{
|
||||
const char *s = PyUnicode_AsUTF8(valuetext);
|
||||
if (s)
|
||||
if (const char *s = PyUnicode_AsUTF8(valuetext); s)
|
||||
ErrorLog(s);
|
||||
Py_DECREF(valuetext);
|
||||
}
|
||||
@@ -669,8 +665,7 @@ void python_taskqueue::error()
|
||||
auto *tracebacktext{PyObject_Str(traceback)};
|
||||
if (tracebacktext != nullptr)
|
||||
{
|
||||
const char *s = PyUnicode_AsUTF8(tracebacktext);
|
||||
if (s)
|
||||
if (const char *s = PyUnicode_AsUTF8(tracebacktext); s)
|
||||
ErrorLog(s);
|
||||
Py_DECREF(tracebacktext);
|
||||
}
|
||||
@@ -709,7 +704,7 @@ std::vector<std::string> python_external_utils::PyObjectToStringArray(PyObject *
|
||||
return emptyIfError;
|
||||
}
|
||||
|
||||
result.push_back(std::string(str));
|
||||
result.emplace_back(str);
|
||||
Py_DECREF(item); // Decrease reference count for the item
|
||||
}
|
||||
|
||||
|
||||
@@ -80,8 +80,8 @@ class render_task
|
||||
render_task(PyObject *Renderer, std::shared_ptr<dictionary_source> Input, std::shared_ptr<python_rt> Target) : m_renderer(Renderer), m_input(Input), m_target(Target) {}
|
||||
// methods
|
||||
void run();
|
||||
void upload();
|
||||
void cancel();
|
||||
void upload() const;
|
||||
void cancel() const;
|
||||
auto target() const -> std::shared_ptr<python_rt>
|
||||
{
|
||||
return m_target;
|
||||
@@ -120,7 +120,7 @@ class python_taskqueue
|
||||
// acquires the python gil and sets the main thread as current
|
||||
void acquire_lock();
|
||||
// releases the python gil and swaps the main thread out
|
||||
void release_lock();
|
||||
void release_lock() const;
|
||||
|
||||
void update();
|
||||
|
||||
@@ -131,8 +131,8 @@ class python_taskqueue
|
||||
using rendertask_sequence = threading::lockable<std::deque<std::shared_ptr<render_task>>>;
|
||||
using uploadtask_sequence = threading::lockable<std::deque<std::shared_ptr<render_task>>>;
|
||||
// methods
|
||||
auto fetch_renderer(std::string const Renderer) -> PyObject *;
|
||||
void run(GLFWwindow *Context, rendertask_sequence &Tasks, uploadtask_sequence &Upload_Tasks, threading::condition_variable &Condition, std::atomic<bool> &Exit);
|
||||
auto fetch_renderer(std::string const &Renderer) -> PyObject *;
|
||||
void run(GLFWwindow *Context, rendertask_sequence &Tasks, uploadtask_sequence &Upload_Tasks, threading::condition_variable &Condition, std::atomic<bool> const &Exit);
|
||||
void error();
|
||||
|
||||
// members
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user