mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 18:39:18 +02:00
vehicle params window, aware system rewrite, sifa
This commit is contained in:
@@ -128,6 +128,7 @@ set(SOURCES
|
||||
"widgets/map_objects.cpp"
|
||||
"widgets/popup.cpp"
|
||||
"widgets/time.cpp"
|
||||
"widgets/vehicleparams.cpp"
|
||||
|
||||
"ref/glad/src/glad.c"
|
||||
|
||||
|
||||
14
Driver.cpp
14
Driver.cpp
@@ -3759,7 +3759,7 @@ void TController::PhysicsLog()
|
||||
<< ( mvOccupied->CommandIn.Command.empty() ? "none" : mvOccupied->CommandIn.Command.c_str() ) << " "
|
||||
<< mvOccupied->CommandIn.Value1 << " "
|
||||
<< mvOccupied->CommandIn.Value2 << " "
|
||||
<< int(mvControlling->SecuritySystem.Status) << " "
|
||||
<< int(mvControlling->SecuritySystem.is_blinking()) << " "
|
||||
<< int(mvControlling->SlippingWheels) << " "
|
||||
<< mvControlling->dizel_heat.Ts << " "
|
||||
<< mvControlling->dizel_heat.To << " "
|
||||
@@ -4231,17 +4231,9 @@ TController::UpdateSituation(double dt) {
|
||||
// rozpoznaj komende bo lokomotywa jej nie rozpoznaje
|
||||
RecognizeCommand(); // samo czyta komendę wstawioną do pojazdu?
|
||||
}
|
||||
if( mvOccupied->SecuritySystem.Status > 1 ) {
|
||||
if( mvOccupied->SecuritySystem.is_blinking() ) {
|
||||
// jak zadziałało CA/SHP
|
||||
if( !mvOccupied->SecuritySystemReset() ) { // to skasuj
|
||||
if( ( mvOccupied->BrakeCtrlPos == 0 )
|
||||
&& ( AccDesired > 0.0 )
|
||||
&& ( ( TestFlag( mvOccupied->SecuritySystem.Status, s_SHPebrake ) )
|
||||
|| ( TestFlag( mvOccupied->SecuritySystem.Status, s_CAebrake ) ) ) ) {
|
||||
//!!! hm, może po prostu normalnie sterować hamulcem?
|
||||
mvOccupied->BrakeLevelSet( 0 );
|
||||
}
|
||||
}
|
||||
mvOccupied->SecuritySystemReset(); // to skasuj
|
||||
}
|
||||
// basic emergency stop handling, while at it
|
||||
if( ( true == mvOccupied->RadioStopFlag ) // radio-stop
|
||||
|
||||
@@ -5957,7 +5957,7 @@ void TDynamicObject::RadioStop()
|
||||
{ // zatrzymanie pojazdu
|
||||
if( Mechanik ) {
|
||||
// o ile ktoś go prowadzi
|
||||
if( ( MoverParameters->SecuritySystem.RadioStop )
|
||||
if( ( MoverParameters->SecuritySystem.radiostop_available() )
|
||||
&& ( MoverParameters->Radio ) ) {
|
||||
// jeśli pojazd ma RadioStop i jest on aktywny
|
||||
// HACK cast until math types unification
|
||||
|
||||
@@ -78,6 +78,7 @@ zwiekszenie nacisku przy duzych predkosciach w hamulcach Oerlikona
|
||||
*/
|
||||
|
||||
#include "dumb3d.h"
|
||||
#include "utilities.h"
|
||||
|
||||
extern int ConversionError;
|
||||
|
||||
@@ -201,17 +202,6 @@ static int const dbrake_switch = 2;
|
||||
static int const dbrake_reversal = 4;
|
||||
static int const dbrake_automatic = 8;
|
||||
|
||||
/*status czuwaka/SHP*/
|
||||
//hunter-091012: rozdzielenie alarmow, dodanie testu czuwaka
|
||||
static int const s_waiting = 1; //działa
|
||||
static int const s_aware = 2; //czuwak miga
|
||||
static int const s_active = 4; //SHP świeci
|
||||
static int const s_CAalarm = 8; //buczy
|
||||
static int const s_SHPalarm = 16; //buczy
|
||||
static int const s_CAebrake = 32; //hamuje
|
||||
static int const s_SHPebrake = 64; //hamuje
|
||||
static int const s_CAtest = 128;
|
||||
|
||||
/*dzwieki*/
|
||||
enum sound {
|
||||
none,
|
||||
@@ -572,23 +562,43 @@ struct TMotorParameters
|
||||
}
|
||||
};
|
||||
|
||||
struct TSecuritySystem
|
||||
class TSecuritySystem
|
||||
{
|
||||
int SystemType { 0 }; /*0: brak, 1: czuwak aktywny, 2: SHP/sygnalizacja kabinowa*/
|
||||
double AwareDelay { -1.0 }; // czas powtarzania czuwaka
|
||||
double AwareMinSpeed; // minimalna prędkość załączenia czuwaka, normalnie 10% Vmax
|
||||
double SoundSignalDelay { -1.0 };
|
||||
double EmergencyBrakeDelay { -1.0 };
|
||||
int Status { 0 }; /*0: wylaczony, 1: wlaczony, 2: czuwak, 4: shp, 8: alarm, 16: hamowanie awaryjne*/
|
||||
double SystemTimer { 0.0 };
|
||||
double SystemSoundCATimer { 0.0 };
|
||||
double SystemSoundSHPTimer { 0.0 };
|
||||
double SystemBrakeCATimer { 0.0 };
|
||||
double SystemBrakeSHPTimer { 0.0 };
|
||||
double SystemBrakeCATestTimer { 0.0 }; // hunter-091012
|
||||
int VelocityAllowed;
|
||||
int NextVelocityAllowed; /*predkosc pokazywana przez sygnalizacje kabinowa*/
|
||||
bool RadioStop; // czy jest RadioStop
|
||||
bool vigilance_enabled = false;
|
||||
bool cabsignal_enabled = false;
|
||||
bool radiostop_enabled = false;
|
||||
|
||||
bool cabsignal_active = false;
|
||||
bool pressed = false;
|
||||
bool enabled = false;
|
||||
bool is_sifa = false; // Sifa-like pedal device, with inverted input for convenient keyboard usage
|
||||
|
||||
double vigilance_timer = 0.0;
|
||||
double alert_timer = 0.0;
|
||||
double press_timer = 0.0;
|
||||
|
||||
double velocity = 0.0;
|
||||
|
||||
double AwareDelay = 30.0;
|
||||
double AwareMinSpeed = 0.0;
|
||||
double SoundSignalDelay = 5.0;
|
||||
double EmergencyBrakeDelay = 5.0;
|
||||
double MaxHoldTime = 5.0;
|
||||
|
||||
public:
|
||||
void set_enabled(bool e);
|
||||
void acknowledge_press();
|
||||
void acknowledge_release();
|
||||
void update(double dt, double Vel);
|
||||
void set_cabsignal();
|
||||
bool is_blinking() const;
|
||||
bool is_vigilance_blinking() const;
|
||||
bool is_cabsignal_blinking() const;
|
||||
bool is_beeping() const;
|
||||
bool is_braking() const;
|
||||
bool is_engine_blocked() const;
|
||||
bool radiostop_available() const;
|
||||
void load(std::string const &line, double Vmax);
|
||||
};
|
||||
|
||||
struct TTransmision
|
||||
@@ -1372,8 +1382,7 @@ public:
|
||||
bool Sandbox( bool const State, range_t const Notify = range_t::consist );/*wlacza/wylacza sypanie piasku*/
|
||||
|
||||
/*! zbijanie czuwaka/SHP*/
|
||||
void SSReset(void);
|
||||
bool SecuritySystemReset(void);
|
||||
void SecuritySystemReset(void);
|
||||
void SecuritySystemCheck(double dt);
|
||||
|
||||
bool BatterySwitch(bool State);
|
||||
@@ -1516,7 +1525,6 @@ private:
|
||||
void LoadFIZ_Cntrl( std::string const &line );
|
||||
void LoadFIZ_Blending(std::string const &line);
|
||||
void LoadFIZ_Light( std::string const &line );
|
||||
void LoadFIZ_Security( std::string const &line );
|
||||
void LoadFIZ_Clima( std::string const &line );
|
||||
void LoadFIZ_Power( std::string const &Line );
|
||||
void LoadFIZ_Engine( std::string const &Input );
|
||||
|
||||
@@ -78,6 +78,113 @@ int DirF(int CouplerN)
|
||||
}
|
||||
}
|
||||
|
||||
void TSecuritySystem::set_enabled(bool e) {
|
||||
if (vigilance_enabled || cabsignal_enabled)
|
||||
enabled = e;
|
||||
if (enabled && cabsignal_enabled && !is_sifa) {
|
||||
cabsignal_active = true;
|
||||
alert_timer = SoundSignalDelay;
|
||||
}
|
||||
}
|
||||
|
||||
void TSecuritySystem::acknowledge_press() {
|
||||
pressed = true;
|
||||
|
||||
if (cabsignal_active) {
|
||||
cabsignal_active = false;
|
||||
alert_timer = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
vigilance_timer = 0.0;
|
||||
alert_timer = 0.0;
|
||||
}
|
||||
|
||||
void TSecuritySystem::acknowledge_release() {
|
||||
pressed = false;
|
||||
|
||||
press_timer = 0.0;
|
||||
alert_timer = 0.0;
|
||||
}
|
||||
|
||||
void TSecuritySystem::update(double dt, double vel) {
|
||||
if (!enabled) {
|
||||
cabsignal_active = false;
|
||||
vigilance_timer = 0.0;
|
||||
alert_timer = 0.0;
|
||||
press_timer = 0.0;
|
||||
return;
|
||||
}
|
||||
|
||||
velocity = vel;
|
||||
|
||||
if (vigilance_enabled && velocity > AwareMinSpeed)
|
||||
vigilance_timer += dt;
|
||||
|
||||
if (pressed && (!is_sifa || velocity > AwareMinSpeed))
|
||||
press_timer += dt;
|
||||
|
||||
if (vigilance_timer > AwareDelay
|
||||
|| press_timer > MaxHoldTime
|
||||
|| cabsignal_active)
|
||||
alert_timer += dt;
|
||||
}
|
||||
|
||||
void TSecuritySystem::set_cabsignal() {
|
||||
if (cabsignal_enabled)
|
||||
cabsignal_active = true;
|
||||
}
|
||||
|
||||
bool TSecuritySystem::is_blinking() const {
|
||||
return alert_timer > 0.0;
|
||||
}
|
||||
|
||||
bool TSecuritySystem::is_vigilance_blinking() const {
|
||||
return press_timer > MaxHoldTime || vigilance_timer > AwareDelay;
|
||||
}
|
||||
|
||||
bool TSecuritySystem::is_cabsignal_blinking() const {
|
||||
return cabsignal_active;
|
||||
}
|
||||
|
||||
bool TSecuritySystem::is_beeping() const {
|
||||
return alert_timer > SoundSignalDelay;
|
||||
}
|
||||
|
||||
bool TSecuritySystem::is_braking() const {
|
||||
return alert_timer > SoundSignalDelay + EmergencyBrakeDelay
|
||||
&& velocity > AwareMinSpeed;
|
||||
}
|
||||
|
||||
bool TSecuritySystem::radiostop_available() const {
|
||||
return radiostop_enabled;
|
||||
}
|
||||
|
||||
bool TSecuritySystem::is_engine_blocked() const {
|
||||
if (!is_sifa)
|
||||
return false;
|
||||
|
||||
return velocity < AwareMinSpeed && pressed;
|
||||
}
|
||||
|
||||
void TSecuritySystem::load(std::string const &line, double Vmax) {
|
||||
std::string awaresystem = extract_value( "AwareSystem", line );
|
||||
if( awaresystem.find( "Active" ) != std::string::npos )
|
||||
vigilance_enabled = true;
|
||||
if( awaresystem.find( "CabSignal" ) != std::string::npos )
|
||||
cabsignal_enabled = true;
|
||||
if( awaresystem.find( "Sifa" ) != std::string::npos )
|
||||
is_sifa = true;
|
||||
|
||||
extract_value( AwareDelay, "AwareDelay", line, "" );
|
||||
AwareMinSpeed = 0.1 * Vmax; //domyślnie 10% Vmax
|
||||
extract_value( AwareMinSpeed, "AwareMinSpeed", line, "" );
|
||||
extract_value( SoundSignalDelay, "SoundSignalDelay", line, "" );
|
||||
extract_value( EmergencyBrakeDelay, "EmergencyBrakeDelay", line, "" );
|
||||
extract_value( MaxHoldTime, "MaxHoldTime", line, "" );
|
||||
extract_value( radiostop_enabled, "RadioStop", line, "" );
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// Q: 20160716
|
||||
// Obliczanie natężenie prądu w silnikach
|
||||
@@ -362,20 +469,6 @@ ActiveCab( Cab )
|
||||
RunningTraction.TractionFreq = 0.0;
|
||||
RunningTraction.TractionMaxCurrent = 0.0;
|
||||
RunningTraction.TractionResistivity = 1.0;
|
||||
|
||||
SecuritySystem.SystemType = 0;
|
||||
SecuritySystem.AwareDelay = -1.0;
|
||||
SecuritySystem.SoundSignalDelay = -1.0;
|
||||
SecuritySystem.EmergencyBrakeDelay = -1.0;
|
||||
SecuritySystem.Status = 0;
|
||||
SecuritySystem.SystemTimer = 0.0;
|
||||
SecuritySystem.SystemBrakeCATimer = 0.0;
|
||||
SecuritySystem.SystemBrakeSHPTimer = 0.0; // hunter-091012
|
||||
SecuritySystem.VelocityAllowed = -1;
|
||||
SecuritySystem.NextVelocityAllowed = -1;
|
||||
SecuritySystem.RadioStop = false; // domyślnie nie ma
|
||||
SecuritySystem.AwareMinSpeed = 0.1 * Vmax;
|
||||
s_CAtestebrake = false;
|
||||
};
|
||||
|
||||
double TMoverParameters::Distance(const TLocation &Loc1, const TLocation &Loc2,
|
||||
@@ -2083,7 +2176,7 @@ bool TMoverParameters::CabActivisation(void)
|
||||
{
|
||||
CabNo = ActiveCab; // sterowanie jest z kabiny z obsadą
|
||||
DirAbsolute = ActiveDir * CabNo;
|
||||
SecuritySystem.Status |= s_waiting; // activate the alerter TODO: make it part of control based cab selection
|
||||
SecuritySystem.set_enabled(true);
|
||||
SendCtrlToNext("CabActivisation", 1, CabNo);
|
||||
}
|
||||
return OK;
|
||||
@@ -2103,7 +2196,7 @@ bool TMoverParameters::CabDeactivisation(void)
|
||||
CabNo = 0;
|
||||
DirAbsolute = ActiveDir * CabNo;
|
||||
DepartureSignal = false; // nie buczeć z nieaktywnej kabiny
|
||||
SecuritySystem.Status = 0; // deactivate alerter TODO: make it part of control based cab selection
|
||||
SecuritySystem.set_enabled(false);
|
||||
|
||||
SendCtrlToNext("CabActivisation", 0, ActiveCab); // CabNo==0!
|
||||
}
|
||||
@@ -2181,58 +2274,18 @@ bool TMoverParameters::Sandbox( bool const State, range_t const Notify )
|
||||
return result;
|
||||
}
|
||||
|
||||
void TMoverParameters::SSReset(void)
|
||||
{ // funkcja pomocnicza dla SecuritySystemReset - w Delphi Reset()
|
||||
SecuritySystem.SystemTimer = 0;
|
||||
|
||||
if (TestFlag(SecuritySystem.Status, s_aware))
|
||||
{
|
||||
SecuritySystem.SystemBrakeCATimer = 0;
|
||||
SecuritySystem.SystemSoundCATimer = 0;
|
||||
SetFlag(SecuritySystem.Status, -s_aware);
|
||||
SetFlag(SecuritySystem.Status, -s_CAalarm);
|
||||
SetFlag(SecuritySystem.Status, -s_CAebrake);
|
||||
// EmergencyBrakeFlag = false; //YB-HN
|
||||
SecuritySystem.VelocityAllowed = -1;
|
||||
}
|
||||
else if (TestFlag(SecuritySystem.Status, s_active))
|
||||
{
|
||||
SecuritySystem.SystemBrakeSHPTimer = 0;
|
||||
SecuritySystem.SystemSoundSHPTimer = 0;
|
||||
SetFlag(SecuritySystem.Status, -s_active);
|
||||
SetFlag(SecuritySystem.Status, -s_SHPalarm);
|
||||
SetFlag(SecuritySystem.Status, -s_SHPebrake);
|
||||
// EmergencyBrakeFlag = false; //YB-HN
|
||||
SecuritySystem.VelocityAllowed = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************************************
|
||||
// Q: 20160710
|
||||
// zbicie czuwaka / SHP
|
||||
// *****************************************************************************
|
||||
// hunter-091012: rozbicie alarmow, dodanie testu czuwaka
|
||||
bool TMoverParameters::SecuritySystemReset(void) // zbijanie czuwaka/SHP
|
||||
void TMoverParameters::SecuritySystemReset(void) // zbijanie czuwaka/SHP
|
||||
{
|
||||
// zbijanie czuwaka/SHP
|
||||
bool SSR = false;
|
||||
// with SecuritySystem do
|
||||
if ((SecuritySystem.SystemType > 0) && (SecuritySystem.Status > 0))
|
||||
{
|
||||
SSR = true;
|
||||
if ((TrainType == dt_EZT) ||
|
||||
(ActiveDir != 0)) // Ra 2014-03: w EZT nie trzeba ustawiać kierunku
|
||||
if (!TestFlag(SecuritySystem.Status, s_CAebrake) ||
|
||||
!TestFlag(SecuritySystem.Status, s_SHPebrake))
|
||||
SSReset();
|
||||
// else
|
||||
// if EmergencyBrakeSwitch(false) then
|
||||
// Reset;
|
||||
}
|
||||
else
|
||||
SSR = false;
|
||||
// SendCtrlToNext('SecurityReset',0,CabNo);
|
||||
return SSR;
|
||||
if (TrainType != dt_EZT && ActiveDir == 0)
|
||||
return; // Ra 2014-03: w EZT nie trzeba ustawiać kierunku
|
||||
|
||||
SecuritySystem.acknowledge_press();
|
||||
SecuritySystem.acknowledge_release();
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
@@ -2241,83 +2294,12 @@ bool TMoverParameters::SecuritySystemReset(void) // zbijanie czuwaka/SHP
|
||||
// *************************************************************************************************
|
||||
void TMoverParameters::SecuritySystemCheck(double dt)
|
||||
{
|
||||
// Ra: z CA/SHP w EZT jest ten problem, że w rozrządczym nie ma kierunku, a w silnikowym nie ma
|
||||
// obsady
|
||||
// poza tym jest zdefiniowany we wszystkich 3 członach EN57
|
||||
if ((!Radio))
|
||||
RadiostopSwitch(false);
|
||||
|
||||
if ((SecuritySystem.SystemType > 0) && (SecuritySystem.Status > 0) &&
|
||||
(Battery)) // Ra: EZT ma teraz czuwak w rozrządczym
|
||||
{
|
||||
// CA
|
||||
if( ( SecuritySystem.AwareMinSpeed > 0.0 ?
|
||||
( Vel >= SecuritySystem.AwareMinSpeed ) :
|
||||
( ActiveDir != 0 ) ) ) {
|
||||
// domyślnie predkość większa od 10% Vmax, albo podanej jawnie w FIZ
|
||||
// with defined minspeed of 0 the alerter will activate with reverser out of neutral position
|
||||
// this emulates behaviour of engines like SM42
|
||||
SecuritySystem.SystemTimer += dt;
|
||||
if (TestFlag(SecuritySystem.SystemType, 1) &&
|
||||
TestFlag(SecuritySystem.Status, s_aware)) // jeśli świeci albo miga
|
||||
SecuritySystem.SystemSoundCATimer += dt;
|
||||
if (TestFlag(SecuritySystem.SystemType, 1) &&
|
||||
TestFlag(SecuritySystem.Status, s_CAalarm)) // jeśli buczy
|
||||
SecuritySystem.SystemBrakeCATimer += dt;
|
||||
if (TestFlag(SecuritySystem.SystemType, 1))
|
||||
if ((SecuritySystem.SystemTimer > SecuritySystem.AwareDelay) &&
|
||||
(SecuritySystem.AwareDelay >= 0)) //-1 blokuje
|
||||
if (!SetFlag(SecuritySystem.Status, s_aware)) // juz wlaczony sygnal swietlny
|
||||
if ((SecuritySystem.SystemSoundCATimer > SecuritySystem.SoundSignalDelay) &&
|
||||
(SecuritySystem.SoundSignalDelay >= 0))
|
||||
if (!SetFlag(SecuritySystem.Status,
|
||||
s_CAalarm)) // juz wlaczony sygnal dzwiekowy
|
||||
if ((SecuritySystem.SystemBrakeCATimer >
|
||||
SecuritySystem.EmergencyBrakeDelay) &&
|
||||
(SecuritySystem.EmergencyBrakeDelay >= 0))
|
||||
SetFlag(SecuritySystem.Status, s_CAebrake);
|
||||
|
||||
// SHP
|
||||
if (TestFlag(SecuritySystem.SystemType, 2) &&
|
||||
TestFlag(SecuritySystem.Status, s_active)) // jeśli świeci albo miga
|
||||
SecuritySystem.SystemSoundSHPTimer += dt;
|
||||
if (TestFlag(SecuritySystem.SystemType, 2) &&
|
||||
TestFlag(SecuritySystem.Status, s_SHPalarm)) // jeśli buczy
|
||||
SecuritySystem.SystemBrakeSHPTimer += dt;
|
||||
if (TestFlag(SecuritySystem.SystemType, 2) && TestFlag(SecuritySystem.Status, s_active))
|
||||
if ((Vel > SecuritySystem.VelocityAllowed) && (SecuritySystem.VelocityAllowed >= 0))
|
||||
SetFlag(SecuritySystem.Status, s_SHPebrake);
|
||||
else if (((SecuritySystem.SystemSoundSHPTimer > SecuritySystem.SoundSignalDelay) &&
|
||||
(SecuritySystem.SoundSignalDelay >= 0)) ||
|
||||
((Vel > SecuritySystem.NextVelocityAllowed) &&
|
||||
(SecuritySystem.NextVelocityAllowed >= 0)))
|
||||
if (!SetFlag(SecuritySystem.Status,
|
||||
s_SHPalarm)) // juz wlaczony sygnal dzwiekowy}
|
||||
if ((SecuritySystem.SystemBrakeSHPTimer >
|
||||
SecuritySystem.EmergencyBrakeDelay) &&
|
||||
(SecuritySystem.EmergencyBrakeDelay >= 0))
|
||||
SetFlag(SecuritySystem.Status, s_SHPebrake);
|
||||
|
||||
} // else SystemTimer:=0;
|
||||
|
||||
// TEST CA
|
||||
if (TestFlag(SecuritySystem.Status, s_CAtest)) // jeśli świeci albo miga
|
||||
SecuritySystem.SystemBrakeCATestTimer += dt;
|
||||
if (TestFlag(SecuritySystem.SystemType, 1))
|
||||
if (TestFlag(SecuritySystem.Status, s_CAtest)) // juz wlaczony sygnal swietlny
|
||||
if ((SecuritySystem.SystemBrakeCATestTimer > SecuritySystem.EmergencyBrakeDelay) &&
|
||||
(SecuritySystem.EmergencyBrakeDelay >= 0))
|
||||
s_CAtestebrake = true;
|
||||
|
||||
// wdrazanie hamowania naglego
|
||||
// if TestFlag(Status,s_SHPebrake) or TestFlag(Status,s_CAebrake) or
|
||||
// (s_CAtestebrake=true) then
|
||||
// EmergencyBrakeFlag:=true; //YB-HN
|
||||
if (Battery) {
|
||||
SecuritySystem.update(dt, Vel);
|
||||
}
|
||||
else if (!Battery)
|
||||
else
|
||||
{ // wyłączenie baterii deaktywuje sprzęt
|
||||
RadiostopSwitch(false);
|
||||
// SecuritySystem.Status = 0; //deaktywacja czuwaka
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2339,10 +2321,7 @@ bool TMoverParameters::BatterySwitch(bool State)
|
||||
SendCtrlToNext("BatterySwitch", 0, CabNo);
|
||||
BS = true;
|
||||
|
||||
if ((Battery) && (ActiveCab != 0)) /*|| (TrainType==dt_EZT)*/
|
||||
SecuritySystem.Status = (SecuritySystem.Status | s_waiting); // aktywacja czuwaka
|
||||
else
|
||||
SecuritySystem.Status = 0; // wyłączenie czuwaka
|
||||
SecuritySystem.set_enabled((Battery) && (ActiveCab != 0));
|
||||
|
||||
return BS;
|
||||
}
|
||||
@@ -3569,19 +3548,12 @@ void TMoverParameters::UpdatePipePressure(double dt)
|
||||
Pipe2->Flow(dpMainValve);
|
||||
}
|
||||
|
||||
// ulepszony hamulec bezp.
|
||||
if( ( true == RadioStopFlag )
|
||||
|| ( true == AlarmChainFlag )
|
||||
|| ( true == TestFlag( SecuritySystem.Status, s_SHPebrake ) )
|
||||
|| ( true == TestFlag( SecuritySystem.Status, s_CAebrake ) )
|
||||
/*
|
||||
// NOTE: disabled because 32 is 'load destroyed' flag, what does this have to do with emergency brake?
|
||||
// (if it's supposed to be broken coupler, such event sets alarmchainflag instead when appropriate)
|
||||
|| ( true == TestFlag( EngDmgFlag, 32 ) )
|
||||
*/
|
||||
|| ( true == s_CAtestebrake ) ) {
|
||||
|| SecuritySystem.is_braking() ) {
|
||||
dpMainValve = dpMainValve + PF( 0, PipePress, 0.15 ) * dt;
|
||||
}
|
||||
|
||||
// 0.2*Spg
|
||||
Pipe->Flow(-dpMainValve);
|
||||
Pipe->Flow(-(PipePress)*0.001 * dt);
|
||||
@@ -5047,7 +5019,7 @@ double TMoverParameters::TractionForce( double dt ) {
|
||||
|
||||
case TEngineType::ElectricInductionMotor:
|
||||
{
|
||||
if( true == Mains ) {
|
||||
if( true == Mains && !SecuritySystem.is_engine_blocked() ) {
|
||||
//tempomat
|
||||
if (ScndCtrlPosNo > 1)
|
||||
{
|
||||
@@ -7747,7 +7719,7 @@ bool TMoverParameters::LoadFIZ(std::string chkpath)
|
||||
{
|
||||
startBPT = false;
|
||||
fizlines.emplace( "Security", inputline );
|
||||
LoadFIZ_Security( inputline );
|
||||
SecuritySystem.load(inputline, Vmax);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -8568,24 +8540,6 @@ void TMoverParameters::LoadFIZ_Light( std::string const &line ) {
|
||||
NominalBatteryVoltage = BatteryVoltage;
|
||||
}
|
||||
|
||||
void TMoverParameters::LoadFIZ_Security( std::string const &line ) {
|
||||
|
||||
std::string awaresystem = extract_value( "AwareSystem", line );
|
||||
if( awaresystem.find( "Active" ) != std::string::npos ) {
|
||||
SetFlag( SecuritySystem.SystemType, 1 );
|
||||
}
|
||||
if( awaresystem.find( "CabSignal" ) != std::string::npos ) {
|
||||
SetFlag( SecuritySystem.SystemType, 2 );
|
||||
}
|
||||
|
||||
extract_value( SecuritySystem.AwareDelay, "AwareDelay", line, "" );
|
||||
SecuritySystem.AwareMinSpeed = 0.1 * Vmax; //domyślnie 10% Vmax
|
||||
extract_value( SecuritySystem.AwareMinSpeed, "AwareMinSpeed", line, "" );
|
||||
extract_value( SecuritySystem.SoundSignalDelay, "SoundSignalDelay", line, "" );
|
||||
extract_value( SecuritySystem.EmergencyBrakeDelay, "EmergencyBrakeDelay", line, "" );
|
||||
extract_value( SecuritySystem.RadioStop, "RadioStop", line, "" );
|
||||
}
|
||||
|
||||
void TMoverParameters::LoadFIZ_Clima( std::string const &line ) {
|
||||
|
||||
HeatingPowerSource.SourceType = LoadFIZ_SourceDecode( extract_value( "Heating", line ) );
|
||||
@@ -9677,10 +9631,7 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
||||
Battery = true;
|
||||
else if ((CValue1 == 0))
|
||||
Battery = false;
|
||||
if ((Battery) && (ActiveCab != 0) /*or (TrainType=dt_EZT)*/)
|
||||
SecuritySystem.Status = SecuritySystem.Status || s_waiting; // aktywacja czuwaka
|
||||
else
|
||||
SecuritySystem.Status = 0; // wyłączenie czuwaka
|
||||
SecuritySystem.set_enabled(((Battery) && (ActiveCab != 0)));
|
||||
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
|
||||
}
|
||||
// else if command='EpFuseSwitch' then {NBMX}
|
||||
@@ -9903,16 +9854,7 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
||||
}
|
||||
else if (Command == "CabSignal") /*SHP,Indusi*/
|
||||
{ // Ra: to powinno działać tylko w członie obsadzonym
|
||||
if (/*(TrainType=dt_EZT)or*/ (ActiveCab != 0) && (Battery) &&
|
||||
TestFlag(SecuritySystem.SystemType,
|
||||
2)) // jeśli kabina jest obsadzona (silnikowy w EZT?)
|
||||
/*?*/ /* WITH SecuritySystem */
|
||||
{
|
||||
SecuritySystem.VelocityAllowed = static_cast<int>(floor(CValue1));
|
||||
SecuritySystem.NextVelocityAllowed = static_cast<int>(floor(CValue2));
|
||||
SecuritySystem.SystemSoundSHPTimer = 0; // hunter-091012
|
||||
SetFlag(SecuritySystem.Status, s_active);
|
||||
}
|
||||
SecuritySystem.set_cabsignal();
|
||||
// else OK:=false;
|
||||
OK = true; // true, gdy można usunąć komendę
|
||||
}
|
||||
|
||||
109
Train.cpp
109
Train.cpp
@@ -486,8 +486,8 @@ dictionary_source *TTrain::GetTrainState() {
|
||||
dict->insert( "brake_delay_flag", mvOccupied->BrakeDelayFlag );
|
||||
dict->insert( "brake_op_mode_flag", mvOccupied->BrakeOpModeFlag );
|
||||
// other controls
|
||||
dict->insert( "ca", TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) );
|
||||
dict->insert( "shp", TestFlag( mvOccupied->SecuritySystem.Status, s_active ) );
|
||||
dict->insert( "ca", mvOccupied->SecuritySystem.is_vigilance_blinking() );
|
||||
dict->insert( "shp", mvOccupied->SecuritySystem.is_cabsignal_blinking() );
|
||||
dict->insert( "pantpress", std::abs( mvControlled->PantPress ) );
|
||||
dict->insert( "universal3", InstrumentLightActive );
|
||||
dict->insert( "radio_channel", iRadioChannel );
|
||||
@@ -612,7 +612,7 @@ TTrain::get_state() const {
|
||||
btLampkaOgrzewanieSkladu.GetValue(),
|
||||
btHaslerBrakes.GetValue(),
|
||||
btHaslerCurrent.GetValue(),
|
||||
( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm ) || TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ),
|
||||
mvOccupied->SecuritySystem.is_blinking(),
|
||||
btLampkaHVoltageB.GetValue(),
|
||||
fTachoVelocity,
|
||||
static_cast<float>( mvOccupied->Compressor ),
|
||||
@@ -1612,26 +1612,20 @@ void TTrain::OnCommand_reverserbackward( TTrain *Train, command_data const &Comm
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_alerteracknowledge( TTrain *Train, command_data const &Command ) {
|
||||
if (Train->mvOccupied->TrainType != dt_EZT && Train->mvOccupied->ActiveDir == 0)
|
||||
return; // Ra 2014-03: w EZT nie trzeba ustawiać kierunku
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// visual feedback
|
||||
Train->ggSecurityResetButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
if( Train->CAflag == false ) {
|
||||
Train->CAflag = true;
|
||||
Train->mvOccupied->SecuritySystemReset();
|
||||
}
|
||||
|
||||
Train->mvOccupied->SecuritySystem.acknowledge_press();
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
// visual feedback
|
||||
Train->ggSecurityResetButton.UpdateValue( 0.0 );
|
||||
|
||||
Train->fCzuwakTestTimer = 0.0f;
|
||||
if( TestFlag( Train->mvOccupied->SecuritySystem.Status, s_CAtest ) ) {
|
||||
SetFlag( Train->mvOccupied->SecuritySystem.Status, -s_CAtest );
|
||||
Train->mvOccupied->s_CAtestebrake = false;
|
||||
Train->mvOccupied->SecuritySystem.SystemBrakeCATestTimer = 0.0;
|
||||
}
|
||||
Train->CAflag = false;
|
||||
Train->mvOccupied->SecuritySystem.acknowledge_release();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1666,11 +1660,7 @@ void TTrain::OnCommand_batteryenable( TTrain *Train, command_data const &Command
|
||||
if( Train->mvOccupied->LightsPosNo > 0 ) {
|
||||
Train->SetLights();
|
||||
}
|
||||
if( TestFlag( Train->mvOccupied->SecuritySystem.SystemType, 2 ) ) {
|
||||
// Ra: znowu w kabinie jest coś, co być nie powinno!
|
||||
SetFlag( Train->mvOccupied->SecuritySystem.Status, s_active );
|
||||
SetFlag( Train->mvOccupied->SecuritySystem.Status, s_SHPalarm );
|
||||
}
|
||||
Train->mvOccupied->SecuritySystem.set_enabled(true); // Ra: znowu w kabinie jest coś, co być nie powinno!
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5449,36 +5439,23 @@ bool TTrain::Update( double const Deltatime )
|
||||
}
|
||||
|
||||
if (mvControlled->Battery || mvControlled->ConverterFlag) {
|
||||
// alerter test
|
||||
if( true == CAflag ) {
|
||||
if( ggSecurityResetButton.GetDesiredValue() > 0.95 ) {
|
||||
fCzuwakTestTimer += Deltatime;
|
||||
}
|
||||
if( fCzuwakTestTimer > 1.0 ) {
|
||||
SetFlag( mvOccupied->SecuritySystem.Status, s_CAtest );
|
||||
}
|
||||
}
|
||||
// McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa
|
||||
if( mvOccupied->SecuritySystem.Status > 0 ) {
|
||||
if( mvOccupied->SecuritySystem.is_vigilance_blinking() ) {
|
||||
if( fBlinkTimer > fCzuwakBlink )
|
||||
fBlinkTimer = -fCzuwakBlink;
|
||||
else
|
||||
fBlinkTimer += Deltatime;
|
||||
// hunter-091012: dodanie testu czuwaka
|
||||
if( ( TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) )
|
||||
|| ( TestFlag( mvOccupied->SecuritySystem.Status, s_CAtest ) ) ) {
|
||||
|
||||
btLampkaCzuwaka.Turn( fBlinkTimer > 0 );
|
||||
}
|
||||
else
|
||||
else {
|
||||
btLampkaCzuwaka.Turn( false );
|
||||
}
|
||||
|
||||
btLampkaSHP.Turn( TestFlag( mvOccupied->SecuritySystem.Status, s_active ) );
|
||||
}
|
||||
else // wylaczone
|
||||
{
|
||||
btLampkaCzuwaka.Turn( false );
|
||||
if (mvOccupied->SecuritySystem.is_cabsignal_blinking())
|
||||
btLampkaSHP.Turn( true );
|
||||
else
|
||||
btLampkaSHP.Turn( false );
|
||||
}
|
||||
|
||||
btLampkaWylSzybki.Turn(
|
||||
( ( (m_linebreakerstate == 2)
|
||||
@@ -6098,13 +6075,9 @@ bool TTrain::Update( double const Deltatime )
|
||||
*/
|
||||
// screens
|
||||
fScreenTimer += Deltatime;
|
||||
if( ( fScreenTimer > Global.PythonScreenUpdateRate * 0.001f )
|
||||
&& !FreeFlyModeFlag && simulation::Train == this ) { // don't bother if we're outside
|
||||
fScreenTimer = 0.f;
|
||||
for( auto const &screen : m_screens ) {
|
||||
Application.request( { std::get<0>(screen), GetTrainState(), std::get<1>(screen) } );
|
||||
}
|
||||
}
|
||||
if (!FreeFlyModeFlag && simulation::Train == this) // don't bother if we're outside
|
||||
update_screens();
|
||||
|
||||
// sounds
|
||||
update_sounds( Deltatime );
|
||||
|
||||
@@ -6299,10 +6272,8 @@ TTrain::update_sounds( double const Deltatime ) {
|
||||
}
|
||||
|
||||
// McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa
|
||||
if (mvOccupied->SecuritySystem.Status > 0) {
|
||||
if (mvOccupied->SecuritySystem.is_beeping()) {
|
||||
// hunter-091012: rozdzielenie alarmow
|
||||
if( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm )
|
||||
|| TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ) {
|
||||
|
||||
if( false == dsbBuzzer.is_playing() ) {
|
||||
dsbBuzzer
|
||||
@@ -6319,16 +6290,6 @@ TTrain::update_sounds( double const Deltatime ) {
|
||||
dsbBuzzer.stop();
|
||||
#ifdef _WIN32
|
||||
Console::BitsClear( 1 << 14 ); // ustawienie bitu 16 na PoKeys
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// wylaczone
|
||||
if( true == dsbBuzzer.is_playing() ) {
|
||||
dsbBuzzer.stop();
|
||||
#ifdef _WIN32
|
||||
Console::BitsClear( 1 << 14 ); // ustawienie bitu 16 na PoKeys
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -6435,6 +6396,14 @@ void TTrain::update_sounds_radio() {
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::update_screens() {
|
||||
if (fScreenTimer > Global.PythonScreenUpdateRate * 0.001f) {
|
||||
fScreenTimer = 0.f;
|
||||
for (auto const &screen : m_screens)
|
||||
Application.request( { std::get<0>(screen), GetTrainState(), std::get<1>(screen) } );
|
||||
}
|
||||
}
|
||||
|
||||
bool TTrain::CabChange(int iDirection)
|
||||
{ // McZapkie-090902: zmiana kabiny 1->0->2 i z powrotem
|
||||
if( ( DynamicObject->Mechanik == nullptr )
|
||||
@@ -6893,16 +6862,16 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
||||
|
||||
tex->create();
|
||||
|
||||
// record renderer and material binding for future update requests
|
||||
m_screens.emplace_back(
|
||||
( substr_path(renderername).empty() ? // supply vehicle folder as path if none is provided
|
||||
const std::string rendererpath {
|
||||
substr_path(renderername).empty() ? // supply vehicle folder as path if none is provided
|
||||
DynamicObject->asBaseDir + renderername :
|
||||
renderername ),
|
||||
tex->id,
|
||||
nullptr);
|
||||
renderername };
|
||||
|
||||
// record renderer and material binding for future update requests
|
||||
m_screens.emplace_back(rendererpath, tex->id, nullptr);
|
||||
|
||||
if (Global.python_displaywindows)
|
||||
std::get<2>(m_screens.back()) = std::make_unique<python_screen_viewer>(tex->id, submodelname);
|
||||
std::get<2>(m_screens.back()) = std::make_unique<python_screen_viewer>(tex->id, rendererpath);
|
||||
}
|
||||
// btLampkaUnknown.Init("unknown",mdKabina,false);
|
||||
} while (token != "");
|
||||
@@ -7170,6 +7139,11 @@ TTrain::clamp_inside( Math3D::vector3 const &Point ) const {
|
||||
clamp( Point.z, Cabine[ iCabn ].CabPos1.z, Cabine[ iCabn ].CabPos2.z ) };
|
||||
}
|
||||
|
||||
const TTrain::screen_map& TTrain::get_screens() {
|
||||
update_screens();
|
||||
return m_screens;
|
||||
}
|
||||
|
||||
void
|
||||
TTrain::radio_message( sound_source *Message, int const Channel ) {
|
||||
|
||||
@@ -8295,8 +8269,7 @@ std::array<float, 3> TTrain::get_current()
|
||||
|
||||
bool TTrain::get_alarm()
|
||||
{
|
||||
return (TestFlag(mvOccupied->SecuritySystem.Status, s_CAalarm) ||
|
||||
TestFlag(mvOccupied->SecuritySystem.Status, s_SHPalarm));
|
||||
return mvOccupied->SecuritySystem.is_beeping();
|
||||
}
|
||||
|
||||
void TTrain::set_mainctrl(int pos)
|
||||
|
||||
9
Train.h
9
Train.h
@@ -98,6 +98,8 @@ class TTrain
|
||||
float hv_voltage;
|
||||
std::array<float, 3> hv_current;
|
||||
};
|
||||
typedef std::tuple<std::string, GLuint, std::unique_ptr<python_screen_viewer>> screen_entry;
|
||||
typedef std::vector<screen_entry> screen_map;
|
||||
|
||||
// methods
|
||||
bool CabChange(int iDirection);
|
||||
@@ -151,6 +153,7 @@ class TTrain
|
||||
void update_sounds( double const Deltatime );
|
||||
void update_sounds_runningnoise( sound_source &Sound );
|
||||
void update_sounds_radio();
|
||||
void update_screens();
|
||||
|
||||
// command handlers
|
||||
// NOTE: we're currently using universal handlers and static handler map but it may be beneficial to have these implemented on individual class instance basis
|
||||
@@ -632,11 +635,8 @@ private:
|
||||
float fHaslerTimer;
|
||||
float fConverterTimer; // hunter-261211: dla przekaznika
|
||||
float fMainRelayTimer; // hunter-141211: zalaczanie WSa z opoznieniem
|
||||
float fCzuwakTestTimer; // hunter-091012: do testu czuwaka
|
||||
float fScreenTimer { 0.f };
|
||||
|
||||
bool CAflag { false }; // hunter-131211: dla osobnego zbijania CA i SHP
|
||||
|
||||
// McZapkie-240302 - przyda sie do tachometru
|
||||
float fTachoVelocity{ 0.0f };
|
||||
float fTachoVelocityJump{ 0.0f }; // ze skakaniem
|
||||
@@ -665,7 +665,7 @@ private:
|
||||
bool m_mastercontrollerinuse { false };
|
||||
float m_mastercontrollerreturndelay { 0.f };
|
||||
int iRadioChannel { 1 }; // numer aktualnego kana?u radiowego
|
||||
std::vector<std::tuple<std::string, GLuint, std::unique_ptr<python_screen_viewer>>> m_screens;
|
||||
screen_map m_screens;
|
||||
uint16_t vid { 0 };
|
||||
|
||||
public:
|
||||
@@ -686,6 +686,7 @@ private:
|
||||
// checks whether specified point is within boundaries of the active cab
|
||||
bool point_inside( Math3D::vector3 const Point ) const;
|
||||
Math3D::vector3 clamp_inside( Math3D::vector3 const &Point ) const;
|
||||
const screen_map & get_screens();
|
||||
|
||||
float get_tacho();
|
||||
float get_tank_pressure();
|
||||
|
||||
@@ -28,6 +28,7 @@ driver_ui::driver_ui() {
|
||||
push_back( &m_transcriptspanel );
|
||||
|
||||
//push_back( &m_vehiclelist );
|
||||
push_back( &m_vehicleparams );
|
||||
push_back( &m_timepanel );
|
||||
push_back( &m_mappanel );
|
||||
push_back( &m_logpanel );
|
||||
@@ -57,6 +58,8 @@ void driver_ui::render_menu_contents() {
|
||||
if (ImGui::MenuItem(m_timepanel.get_name().c_str()))
|
||||
m_timepanel.open();
|
||||
|
||||
ImGui::MenuItem(m_vehicleparams.get_name().c_str(), nullptr, &m_vehicleparams.is_open);
|
||||
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "command.h"
|
||||
|
||||
#include "widgets/vehiclelist.h"
|
||||
#include "widgets/vehicleparams.h"
|
||||
#include "widgets/map.h"
|
||||
#include "widgets/time.h"
|
||||
|
||||
@@ -58,6 +59,7 @@ private:
|
||||
|
||||
command_relay m_relay;
|
||||
ui::vehiclelist_panel m_vehiclelist;
|
||||
ui::vehicleparams_panel m_vehicleparams;
|
||||
ui::map_panel m_mappanel;
|
||||
ui::time_panel m_timepanel;
|
||||
};
|
||||
|
||||
@@ -137,11 +137,11 @@ drivingaid_panel::update() {
|
||||
}
|
||||
}
|
||||
std::string textline =
|
||||
( true == TestFlag( mover->SecuritySystem.Status, s_aware ) ?
|
||||
( mover->SecuritySystem.is_vigilance_blinking() ?
|
||||
locale::strings[ locale::string::driver_aid_alerter ] :
|
||||
" " );
|
||||
textline +=
|
||||
( true == TestFlag( mover->SecuritySystem.Status, s_active ) ?
|
||||
( mover->SecuritySystem.is_cabsignal_blinking() ?
|
||||
locale::strings[ locale::string::driver_aid_shp ] :
|
||||
" " );
|
||||
|
||||
|
||||
@@ -91,6 +91,8 @@ init() {
|
||||
"Divert /",
|
||||
"Insert obstacle:",
|
||||
|
||||
"Vehicle parameters",
|
||||
|
||||
"master controller",
|
||||
"second controller",
|
||||
"shunt mode power",
|
||||
@@ -263,6 +265,8 @@ init() {
|
||||
u8"W bok /",
|
||||
u8"Wstaw przeszkodę:",
|
||||
|
||||
u8"Parametry pojazdu",
|
||||
|
||||
u8"nastawnik jazdy",
|
||||
u8"nastawnik dodatkowy",
|
||||
u8"sterowanie analogowe",
|
||||
|
||||
@@ -80,6 +80,8 @@ enum string {
|
||||
map_divert,
|
||||
map_obstacle_insert,
|
||||
|
||||
vehicleparams_window,
|
||||
|
||||
cab_mainctrl,
|
||||
cab_scndctrl,
|
||||
cab_shuntmodepower,
|
||||
|
||||
112
widgets/map.cpp
112
widgets/map.cpp
@@ -63,7 +63,8 @@ float ui::map_panel::get_vehicle_rotation()
|
||||
return glm::atan(front.z, front.x) - glm::atan(north_ptr.y, north_ptr.x);
|
||||
}
|
||||
|
||||
void ui::map_panel::render_map_texture(glm::mat4 transform, glm::vec2 surface_size) {
|
||||
void ui::map_panel::render_map_texture(glm::mat4 transform, glm::vec2 surface_size)
|
||||
{
|
||||
cFrustum frustum;
|
||||
frustum.calculate(transform, glm::mat4());
|
||||
|
||||
@@ -78,7 +79,8 @@ void ui::map_panel::render_map_texture(glm::mat4 transform, glm::vec2 surface_si
|
||||
if (section && frustum.sphere_inside(section->area().center, section->area().radius) > 0.f)
|
||||
{
|
||||
const gfx::geometrybank_handle handle = section->get_map_geometry();
|
||||
if (handle != null_handle) {
|
||||
if (handle != null_handle)
|
||||
{
|
||||
m_section_handles.push_back(handle);
|
||||
section->get_map_active_switches(m_switch_handles);
|
||||
}
|
||||
@@ -130,7 +132,8 @@ void ui::map_panel::render_map_texture(glm::mat4 transform, glm::vec2 surface_si
|
||||
void ui::map_panel::render_labels(glm::mat4 transform, ImVec2 origin, glm::vec2 surface_size)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.7f, 1.0f, 0.7f, 1.0f));
|
||||
for (TDynamicObject *vehicle : simulation::Vehicles.sequence()) {
|
||||
for (TDynamicObject *vehicle : simulation::Vehicles.sequence())
|
||||
{
|
||||
if (vehicle->Prev() || !vehicle->Mechanik)
|
||||
continue;
|
||||
|
||||
@@ -147,14 +150,13 @@ void ui::map_panel::render_labels(glm::mat4 transform, ImVec2 origin, glm::vec2
|
||||
TDynamicObject *veh = vehicle;
|
||||
|
||||
ImVec2 textsize = ImGui::CalcTextSize(label.c_str());
|
||||
ImGui::SetCursorPos(ImVec2(origin.x + gui_pos.x - textsize.x / 2.0f,
|
||||
origin.y + gui_pos.y - textsize.y / 2.0f));
|
||||
ImGui::SetCursorPos(ImVec2(origin.x + gui_pos.x - textsize.x / 2.0f, origin.y + gui_pos.y - textsize.y / 2.0f));
|
||||
ImGui::TextUnformatted(label.c_str());
|
||||
}
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
if (zoom > 0.005f) {
|
||||
|
||||
if (zoom > 0.005f)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,14 +181,12 @@ void ui::map_panel::render_contents()
|
||||
glm::mat4 transform;
|
||||
transform[0][0] = -1.0f;
|
||||
|
||||
static enum {
|
||||
MODE_MANUAL = 0,
|
||||
MODE_CAMERA,
|
||||
MODE_VEHICLE
|
||||
} mode = MODE_MANUAL;
|
||||
static enum { MODE_MANUAL = 0, MODE_CAMERA, MODE_VEHICLE } mode = MODE_MANUAL;
|
||||
|
||||
ImGui::RadioButton("manual", (int*)&mode, 0); ImGui::SameLine();
|
||||
ImGui::RadioButton("cam", (int*)&mode, 1); ImGui::SameLine();
|
||||
ImGui::RadioButton("manual", (int *)&mode, 0);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("cam", (int *)&mode, 1);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("vehicle", (int *)&mode, 2);
|
||||
|
||||
ImVec2 surface_size_im = ImGui::GetContentRegionAvail();
|
||||
@@ -235,7 +235,8 @@ void ui::map_panel::render_contents()
|
||||
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
if (mode == 0 && ImGui::IsMouseDragging(0)) {
|
||||
if (mode == 0 && ImGui::IsMouseDragging(0))
|
||||
{
|
||||
ImVec2 delta_im = ImGui::GetMouseDragDelta();
|
||||
ImGui::ResetMouseDragDelta();
|
||||
|
||||
@@ -245,27 +246,30 @@ void ui::map_panel::render_contents()
|
||||
|
||||
translate -= delta * 2.0f;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
ImVec2 screen_pos = ImGui::GetMousePos();
|
||||
glm::vec2 surface_pos(screen_pos.x - screen_origin.x, screen_pos.y - screen_origin.y);
|
||||
glm::vec2 ndc_pos = surface_pos / surface_size * 2.0f - 1.0f;
|
||||
glm::vec3 world_pos = glm::inverse(transform) * glm::vec4(ndc_pos.x, 0.0f, -ndc_pos.y, 1.0f);
|
||||
|
||||
map::sorted_object_list objects =
|
||||
map::Objects.find_in_range(glm::vec3(world_pos.x, NAN, world_pos.z), 0.03f / zoom);
|
||||
map::sorted_object_list objects = map::Objects.find_in_range(glm::vec3(world_pos.x, NAN, world_pos.z), 0.03f / zoom);
|
||||
|
||||
if (ImGui::IsMouseClicked(1)) {
|
||||
if (ImGui::IsMouseClicked(1))
|
||||
{
|
||||
if (objects.size() > 1)
|
||||
register_popup(std::make_unique<ui::disambiguation_popup>(*this, std::move(objects)));
|
||||
else if (objects.size() == 1)
|
||||
handle_map_object_click(*this, objects.begin()->second);
|
||||
else {
|
||||
else
|
||||
{
|
||||
glm::vec3 nearest = simulation::Region->find_nearest_track_point(world_pos);
|
||||
if (!glm::isnan(nearest.x) && glm::distance(world_pos, nearest) < (0.03f / zoom))
|
||||
register_popup(std::make_unique<obstacle_window>(*this, std::move(nearest)));
|
||||
}
|
||||
}
|
||||
else if (!objects.empty()) {
|
||||
else if (!objects.empty())
|
||||
{
|
||||
handle_map_object_hover(objects.begin()->second);
|
||||
}
|
||||
}
|
||||
@@ -276,10 +280,12 @@ void ui::map_panel::render_contents()
|
||||
|
||||
void ui::handle_map_object_click(ui_panel &parent, std::shared_ptr<map::map_object> &obj)
|
||||
{
|
||||
if (auto sem = std::dynamic_pointer_cast<map::semaphore>(obj)) {
|
||||
if (auto sem = std::dynamic_pointer_cast<map::semaphore>(obj))
|
||||
{
|
||||
parent.register_popup(std::make_unique<semaphore_window>(parent, std::move(sem)));
|
||||
}
|
||||
else if (auto track = std::dynamic_pointer_cast<map::track_switch>(obj)) {
|
||||
else if (auto track = std::dynamic_pointer_cast<map::track_switch>(obj))
|
||||
{
|
||||
parent.register_popup(std::make_unique<switch_window>(parent, std::move(track)));
|
||||
}
|
||||
}
|
||||
@@ -288,12 +294,15 @@ void ui::handle_map_object_hover(std::shared_ptr<map::map_object> &obj)
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
|
||||
if (auto sem = std::dynamic_pointer_cast<map::semaphore>(obj)) {
|
||||
for (auto &model : sem->models) {
|
||||
if (auto sem = std::dynamic_pointer_cast<map::semaphore>(obj))
|
||||
{
|
||||
for (auto &model : sem->models)
|
||||
{
|
||||
ImGui::PushID(model);
|
||||
ImGui::TextUnformatted(model->name().c_str());
|
||||
|
||||
for (int i = 0; i < iMaxNumLights; i++) {
|
||||
for (int i = 0; i < iMaxNumLights; i++)
|
||||
{
|
||||
GfxRenderer.Update_AnimModel(model); // update lamp opacities
|
||||
auto state = model->LightGet(i);
|
||||
if (!state)
|
||||
@@ -314,20 +323,22 @@ void ui::handle_map_object_hover(std::shared_ptr<map::map_object> &obj)
|
||||
ImGui::PopID();
|
||||
}
|
||||
}
|
||||
else if (auto sw = std::dynamic_pointer_cast<map::track_switch>(obj)) {
|
||||
else if (auto sw = std::dynamic_pointer_cast<map::track_switch>(obj))
|
||||
{
|
||||
ImGui::TextUnformatted(sw->name.c_str());
|
||||
}
|
||||
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
|
||||
ui::disambiguation_popup::disambiguation_popup(ui_panel &panel, map::sorted_object_list &&list)
|
||||
: popup(panel), m_list(list) { }
|
||||
ui::disambiguation_popup::disambiguation_popup(ui_panel &panel, map::sorted_object_list &&list) : popup(panel), m_list(list) {}
|
||||
|
||||
void ui::disambiguation_popup::render_content()
|
||||
{
|
||||
for (auto &item : m_list) {
|
||||
if (ImGui::Button(item.second->name.c_str())) {
|
||||
for (auto &item : m_list)
|
||||
{
|
||||
if (ImGui::Button(item.second->name.c_str()))
|
||||
{
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
handle_map_object_click(m_parent, item.second);
|
||||
@@ -335,16 +346,17 @@ void ui::disambiguation_popup::render_content()
|
||||
}
|
||||
}
|
||||
|
||||
ui::semaphore_window::semaphore_window(ui_panel &panel, std::shared_ptr<map::semaphore> &&sem)
|
||||
: popup(panel), m_sem(sem) { }
|
||||
ui::semaphore_window::semaphore_window(ui_panel &panel, std::shared_ptr<map::semaphore> &&sem) : popup(panel), m_sem(sem) {}
|
||||
|
||||
void ui::semaphore_window::render_content()
|
||||
{
|
||||
for (auto &model : m_sem->models) {
|
||||
for (auto &model : m_sem->models)
|
||||
{
|
||||
ImGui::PushID(model);
|
||||
ImGui::TextUnformatted(model->name().c_str());
|
||||
|
||||
for (int i = 0; i < iMaxNumLights; i++) {
|
||||
for (int i = 0; i < iMaxNumLights; i++)
|
||||
{
|
||||
GfxRenderer.Update_AnimModel(model); // update lamp opacities
|
||||
auto state = model->LightGet(i);
|
||||
if (!state)
|
||||
@@ -361,7 +373,8 @@ void ui::semaphore_window::render_content()
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(current_color.x, current_color.y, current_color.z, 1.0f));
|
||||
|
||||
std::string res = " ##" + std::to_string(i);
|
||||
if (ImGui::Button(res.c_str())) {
|
||||
if (ImGui::Button(res.c_str()))
|
||||
{
|
||||
level += 1.0f;
|
||||
if (level >= 3.0f)
|
||||
level = 0.0f;
|
||||
@@ -378,7 +391,8 @@ void ui::semaphore_window::render_content()
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
for (auto &item : m_sem->events) {
|
||||
for (auto &item : m_sem->events)
|
||||
{
|
||||
std::string displayname = item->name().substr(m_sem->name.size());
|
||||
|
||||
if (displayname.size() < 2)
|
||||
@@ -386,38 +400,40 @@ void ui::semaphore_window::render_content()
|
||||
|
||||
displayname[1] = std::toupper(displayname[1]);
|
||||
|
||||
if (ImGui::Button(displayname.c_str())) {
|
||||
if (ImGui::Button(displayname.c_str()))
|
||||
{
|
||||
m_relay.post(user_command::queueevent, (double)simulation::Events.GetEventId(item), 0.0, GLFW_PRESS, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui::switch_window::switch_window(ui_panel &panel, std::shared_ptr<map::track_switch> &&sw)
|
||||
: popup(panel), m_switch(sw) { }
|
||||
ui::switch_window::switch_window(ui_panel &panel, std::shared_ptr<map::track_switch> &&sw) : popup(panel), m_switch(sw) {}
|
||||
|
||||
void ui::switch_window::render_content()
|
||||
{
|
||||
ImGui::TextUnformatted(m_switch->name.c_str());
|
||||
|
||||
if (ImGui::Button(LOC_STR(map_straight))) {
|
||||
if (ImGui::Button(LOC_STR(map_straight)))
|
||||
{
|
||||
m_relay.post(user_command::queueevent, (double)simulation::Events.GetEventId(m_switch->straight_event), 0.0, GLFW_PRESS, 0);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if (ImGui::Button(LOC_STR(map_divert))) {
|
||||
if (ImGui::Button(LOC_STR(map_divert)))
|
||||
{
|
||||
m_relay.post(user_command::queueevent, (double)simulation::Events.GetEventId(m_switch->divert_event), 0.0, GLFW_PRESS, 0);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
|
||||
ui::obstacle_window::obstacle_window(ui_panel &panel, glm::dvec3 const &pos)
|
||||
: popup(panel), m_position(pos)
|
||||
ui::obstacle_window::obstacle_window(ui_panel &panel, glm::dvec3 const &pos) : popup(panel), m_position(pos)
|
||||
{
|
||||
std::ifstream file;
|
||||
file.open("obstaclebank.txt", std::ios_base::in | std::ios_base::binary);
|
||||
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
std::istringstream entry(line);
|
||||
|
||||
std::string name;
|
||||
@@ -432,8 +448,10 @@ ui::obstacle_window::obstacle_window(ui_panel &panel, glm::dvec3 const &pos)
|
||||
void ui::obstacle_window::render_content()
|
||||
{
|
||||
ImGui::TextUnformatted(LOC_STR(map_obstacle_insert));
|
||||
for (auto const &entry : m_obstacles) {
|
||||
if (ImGui::Button(entry.first.c_str())) {
|
||||
for (auto const &entry : m_obstacles)
|
||||
{
|
||||
if (ImGui::Button(entry.first.c_str()))
|
||||
{
|
||||
std::string name("obstacle_" + std::to_string(LocalRandom(0.0, 100000.0)));
|
||||
TAnimModel *cloned = simulation::State.create_model(entry.second, name, m_position);
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
#include "widgets/map_objects.h"
|
||||
#include "widgets/popup.h"
|
||||
|
||||
namespace ui {
|
||||
namespace ui
|
||||
{
|
||||
|
||||
class disambiguation_popup : public popup {
|
||||
class disambiguation_popup : public popup
|
||||
{
|
||||
map::sorted_object_list m_list;
|
||||
|
||||
public:
|
||||
@@ -18,7 +20,8 @@ public:
|
||||
virtual void render_content() override;
|
||||
};
|
||||
|
||||
class semaphore_window : public popup {
|
||||
class semaphore_window : public popup
|
||||
{
|
||||
std::shared_ptr<map::semaphore> m_sem;
|
||||
command_relay m_relay;
|
||||
|
||||
@@ -28,7 +31,8 @@ public:
|
||||
virtual void render_content() override;
|
||||
};
|
||||
|
||||
class switch_window : public popup {
|
||||
class switch_window : public popup
|
||||
{
|
||||
std::shared_ptr<map::track_switch> m_switch;
|
||||
command_relay m_relay;
|
||||
|
||||
@@ -38,7 +42,8 @@ public:
|
||||
virtual void render_content() override;
|
||||
};
|
||||
|
||||
class obstacle_window : public popup {
|
||||
class obstacle_window : public popup
|
||||
{
|
||||
glm::dvec3 m_position;
|
||||
std::vector<std::pair<std::string, std::string>> m_obstacles;
|
||||
|
||||
@@ -48,7 +53,8 @@ public:
|
||||
virtual void render_content() override;
|
||||
};
|
||||
|
||||
class map_panel : public ui_panel {
|
||||
class map_panel : public ui_panel
|
||||
{
|
||||
std::unique_ptr<gl::program> m_shader;
|
||||
std::unique_ptr<gl::framebuffer> m_msaa_fb;
|
||||
std::unique_ptr<gl::renderbuffer> m_msaa_rb;
|
||||
@@ -81,4 +87,4 @@ public:
|
||||
|
||||
void handle_map_object_click(ui_panel &parent, std::shared_ptr<map::map_object> &obj);
|
||||
void handle_map_object_hover(std::shared_ptr<map::map_object> &obj);
|
||||
}
|
||||
} // namespace ui
|
||||
|
||||
@@ -8,17 +8,20 @@ map::sorted_object_list map::objects::find_in_range(glm::vec3 from, float distan
|
||||
|
||||
float max_distance2 = distance * distance;
|
||||
|
||||
for (auto const entry : entries) {
|
||||
for (auto const entry : entries)
|
||||
{
|
||||
glm::vec3 entry_location = entry->location;
|
||||
glm::vec3 search_point = from;
|
||||
|
||||
if (glm::isnan(from.y)) {
|
||||
if (glm::isnan(from.y))
|
||||
{
|
||||
entry_location.y = 0.0f;
|
||||
search_point.y = 0.0f;
|
||||
}
|
||||
|
||||
float dist = glm::distance2(entry_location, search_point);
|
||||
if (dist < max_distance2) {
|
||||
if (dist < max_distance2)
|
||||
{
|
||||
items.emplace(dist, std::move(entry));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
#include "Event.h"
|
||||
#include "scene.h"
|
||||
|
||||
namespace map {
|
||||
namespace map
|
||||
{
|
||||
|
||||
struct map_object {
|
||||
struct map_object
|
||||
{
|
||||
std::string name;
|
||||
glm::vec3 location;
|
||||
|
||||
@@ -17,19 +19,22 @@ namespace map {
|
||||
using sorted_object_list = std::map<float, std::shared_ptr<map::map_object>>;
|
||||
|
||||
// semaphore description (only for minimap purposes)
|
||||
struct semaphore : public map_object {
|
||||
struct semaphore : public map_object
|
||||
{
|
||||
std::vector<TAnimModel *> models;
|
||||
|
||||
std::vector<basic_event *> events;
|
||||
};
|
||||
|
||||
// switch description (only for minimap purposes)
|
||||
struct track_switch : public map_object {
|
||||
struct track_switch : public map_object
|
||||
{
|
||||
basic_event *straight_event = nullptr;
|
||||
basic_event *divert_event = nullptr;
|
||||
};
|
||||
|
||||
struct objects {
|
||||
struct objects
|
||||
{
|
||||
std::vector<std::shared_ptr<map_object>> entries;
|
||||
|
||||
// returns objects in range from vec3, NaN in Y ignores it
|
||||
@@ -37,4 +42,4 @@ namespace map {
|
||||
};
|
||||
|
||||
extern objects Objects;
|
||||
}
|
||||
} // namespace map
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
#include "widgets/popup.h"
|
||||
|
||||
ui::popup::popup(ui_panel &panel)
|
||||
: m_parent(panel)
|
||||
{
|
||||
}
|
||||
ui::popup::popup(ui_panel &panel) : m_parent(panel) {}
|
||||
|
||||
ui::popup::~popup()
|
||||
{
|
||||
}
|
||||
ui::popup::~popup() {}
|
||||
|
||||
bool ui::popup::render()
|
||||
{
|
||||
if (!m_id.size()) {
|
||||
if (!m_id.size())
|
||||
{
|
||||
m_id = "popup:" + std::to_string(id++);
|
||||
ImGui::OpenPopup(m_id.c_str());
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
class ui_panel;
|
||||
|
||||
namespace ui {
|
||||
namespace ui
|
||||
{
|
||||
|
||||
class popup {
|
||||
class popup
|
||||
{
|
||||
std::string m_id;
|
||||
static int id;
|
||||
|
||||
@@ -19,4 +21,4 @@ protected:
|
||||
virtual void render_content() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace ui
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
#include "simulationtime.h"
|
||||
#include "Globals.h"
|
||||
|
||||
ui::time_panel::time_panel()
|
||||
: ui_panel(LOC_STR(time_window), false)
|
||||
ui::time_panel::time_panel() : ui_panel(LOC_STR(time_window), false)
|
||||
{
|
||||
size.x = 450;
|
||||
}
|
||||
@@ -17,7 +16,8 @@ void ui::time_panel::render_contents()
|
||||
ImGui::SliderFloat(LOC_STR(time_weather), &overcast, 0.0f, 2.0f, "%.1f");
|
||||
ImGui::SliderFloat(LOC_STR(time_temperature), &temperature, -20.0f, 40.0f, "%.0f");
|
||||
|
||||
if (ImGui::Button(LOC_STR(time_apply))) {
|
||||
if (ImGui::Button(LOC_STR(time_apply)))
|
||||
{
|
||||
m_relay.post(user_command::setdatetime, (double)yearday, time, 1, 0);
|
||||
m_relay.post(user_command::setweather, fog, overcast, 1, 0);
|
||||
m_relay.post(user_command::settemperature, temperature, 0.0, 1, 0);
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#include "translation.h"
|
||||
#include "command.h"
|
||||
|
||||
namespace ui {
|
||||
class time_panel : public ui_panel {
|
||||
namespace ui
|
||||
{
|
||||
class time_panel : public ui_panel
|
||||
{
|
||||
command_relay m_relay;
|
||||
|
||||
float time;
|
||||
@@ -18,4 +20,4 @@ namespace ui {
|
||||
void render_contents() override;
|
||||
void open();
|
||||
};
|
||||
}
|
||||
} // namespace ui
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
#include "simulation.h"
|
||||
#include "Driver.h"
|
||||
|
||||
void ui::vehiclelist_panel::render_contents() {
|
||||
for (TDynamicObject* vehicle : simulation::Vehicles.sequence()) {
|
||||
void ui::vehiclelist_panel::render_contents()
|
||||
{
|
||||
for (TDynamicObject *vehicle : simulation::Vehicles.sequence())
|
||||
{
|
||||
if (vehicle->Prev())
|
||||
continue;
|
||||
|
||||
@@ -17,9 +19,11 @@ void ui::vehiclelist_panel::render_contents() {
|
||||
std::string label = std::string(name + ", " + timetable + std::to_string(speed) + " km/h");
|
||||
if (!vehicle->Next())
|
||||
ImGui::TextUnformatted(label.c_str());
|
||||
else if (ImGui::TreeNode(vehicle, label.c_str())) {
|
||||
else if (ImGui::TreeNode(vehicle, label.c_str()))
|
||||
{
|
||||
vehicle = vehicle->Next();
|
||||
while (vehicle) {
|
||||
while (vehicle)
|
||||
{
|
||||
ImGui::TextUnformatted(vehicle->name().c_str());
|
||||
vehicle = vehicle->Next();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "uilayer.h"
|
||||
|
||||
namespace ui {
|
||||
class vehiclelist_panel : public ui_panel {
|
||||
namespace ui
|
||||
{
|
||||
class vehiclelist_panel : public ui_panel
|
||||
{
|
||||
public:
|
||||
vehiclelist_panel() : ui_panel("Vehicle list", true) {}
|
||||
|
||||
void render_contents() override;
|
||||
};
|
||||
}
|
||||
} // namespace ui
|
||||
|
||||
189
widgets/vehicleparams.cpp
Normal file
189
widgets/vehicleparams.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
#include "stdafx.h"
|
||||
#include "widgets/vehicleparams.h"
|
||||
#include "simulation.h"
|
||||
#include "driveruipanels.h"
|
||||
#include "Driver.h"
|
||||
#include "Train.h"
|
||||
|
||||
ui::vehicleparams_panel::vehicleparams_panel()
|
||||
: ui_panel(LOC_STR(vehicleparams_window), false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ui::vehicleparams_panel::render_contents()
|
||||
{
|
||||
if (m_vehicle_name.empty())
|
||||
m_vehicle_name = simulation::Vehicles.sequence()[0]->name();
|
||||
|
||||
TDynamicObject *vehicle_ptr = simulation::Vehicles.find(m_vehicle_name);
|
||||
if (!vehicle_ptr) {
|
||||
is_open = false;
|
||||
return;
|
||||
}
|
||||
|
||||
TTrain *train_ptr = simulation::Trains.find(m_vehicle_name);
|
||||
if (train_ptr) {
|
||||
const TTrain::screen_map &screens = train_ptr->get_screens();
|
||||
|
||||
for (const auto &viewport : Global.python_viewports) {
|
||||
for (auto const &entry : screens) {
|
||||
if (std::get<std::string>(entry) != viewport.surface)
|
||||
continue;
|
||||
|
||||
float aspect = (float)viewport.size.y / viewport.size.x;
|
||||
|
||||
glm::mat3 proj = glm::translate(glm::scale(glm::mat3(), 1.0f / viewport.scale), viewport.offset);
|
||||
|
||||
glm::vec2 uv0 = glm::vec2(proj * glm::vec3(0.0f, 1.0f, 1.0f));
|
||||
glm::vec2 uv1 = glm::vec2(proj * glm::vec3(1.0f, 0.0f, 1.0f));
|
||||
|
||||
ImGui::Image(reinterpret_cast<void*>(std::get<GLuint>(entry)), ImVec2(500, 500 * aspect), ImVec2(uv0.x, uv0.y), ImVec2(uv1.x, uv1.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TDynamicObject &vehicle = *vehicle_ptr;
|
||||
TMoverParameters &mover = *vehicle.MoverParameters;
|
||||
|
||||
std::vector<text_line> lines;
|
||||
std::array<char, 1024> buffer;
|
||||
|
||||
auto const isdieselenginepowered { ( mover.EngineType == TEngineType::DieselElectric ) || ( mover.EngineType == TEngineType::DieselEngine ) };
|
||||
auto const isdieselinshuntmode { mover.ShuntMode && mover.EngineType == TEngineType::DieselElectric };
|
||||
|
||||
std::snprintf(
|
||||
buffer.data(), buffer.size(),
|
||||
locale::strings[ locale::string::debug_vehicle_devicespower ].c_str(),
|
||||
// devices
|
||||
( mover.Battery ? 'B' : '.' ),
|
||||
( mover.Mains ? 'M' : '.' ),
|
||||
( mover.FuseFlag ? '!' : '.' ),
|
||||
( mover.PantRearUp ? ( mover.PantRearVolt > 0.0 ? 'O' : 'o' ) : '.' ),
|
||||
( mover.PantFrontUp ? ( mover.PantFrontVolt > 0.0 ? 'P' : 'p' ) : '.' ),
|
||||
( mover.PantPressLockActive ? '!' : ( mover.PantPressSwitchActive ? '*' : '.' ) ),
|
||||
( mover.WaterPump.is_active ? 'W' : ( false == mover.WaterPump.breaker ? '-' : ( mover.WaterPump.is_enabled ? 'w' : '.' ) ) ),
|
||||
( true == mover.WaterHeater.is_damaged ? '!' : ( mover.WaterHeater.is_active ? 'H' : ( false == mover.WaterHeater.breaker ? '-' : ( mover.WaterHeater.is_enabled ? 'h' : '.' ) ) ) ),
|
||||
( mover.FuelPump.is_active ? 'F' : ( mover.FuelPump.is_enabled ? 'f' : '.' ) ),
|
||||
( mover.OilPump.is_active ? 'O' : ( mover.OilPump.is_enabled ? 'o' : '.' ) ),
|
||||
( false == mover.ConverterAllowLocal ? '-' : ( mover.ConverterAllow ? ( mover.ConverterFlag ? 'X' : 'x' ) : '.' ) ),
|
||||
( mover.ConvOvldFlag ? '!' : '.' ),
|
||||
( mover.CompressorFlag ? 'C' : ( false == mover.CompressorAllowLocal ? '-' : ( ( mover.CompressorAllow || mover.CompressorStart == start_t::automatic ) ? 'c' : '.' ) ) ),
|
||||
( mover.CompressorGovernorLock ? '!' : '.' ),
|
||||
"",
|
||||
std::string( isdieselenginepowered ? locale::strings[ locale::string::debug_vehicle_oilpressure ] + to_string( mover.OilPump.pressure, 2 ) : "" ).c_str(),
|
||||
// power transfers
|
||||
mover.Couplers[ end::front ].power_high.voltage,
|
||||
mover.Couplers[ end::front ].power_high.current,
|
||||
std::string( mover.Couplers[ end::front ].power_high.local ? "" : "-" ).c_str(),
|
||||
std::string( vehicle.DirectionGet() ? ":<<:" : ":>>:" ).c_str(),
|
||||
std::string( mover.Couplers[ end::rear ].power_high.local ? "" : "-" ).c_str(),
|
||||
mover.Couplers[ end::rear ].power_high.voltage,
|
||||
mover.Couplers[ end::rear ].power_high.current );
|
||||
|
||||
ImGui::TextUnformatted(buffer.data());
|
||||
|
||||
std::snprintf(
|
||||
buffer.data(), buffer.size(),
|
||||
locale::strings[ locale::string::debug_vehicle_controllersenginerevolutions ].c_str(),
|
||||
// controllers
|
||||
mover.MainCtrlPos,
|
||||
mover.MainCtrlActualPos,
|
||||
std::string( isdieselinshuntmode ? to_string( mover.AnPos, 2 ) + locale::strings[ locale::string::debug_vehicle_shuntmode ] : std::to_string( mover.ScndCtrlPos ) + "(" + std::to_string( mover.ScndCtrlActualPos ) + ")" ).c_str(),
|
||||
// engine
|
||||
mover.EnginePower,
|
||||
std::abs( mover.TrainType == dt_EZT ? mover.ShowCurrent( 0 ) : mover.Im ),
|
||||
// revolutions
|
||||
std::abs( mover.enrot ) * 60,
|
||||
std::abs( mover.nrot ) * mover.Transmision.Ratio * 60,
|
||||
mover.RventRot * 60,
|
||||
std::abs( mover.MotorBlowers[end::front].revolutions ),
|
||||
std::abs( mover.MotorBlowers[end::rear].revolutions ),
|
||||
mover.dizel_heat.rpmw,
|
||||
mover.dizel_heat.rpmw2 );
|
||||
|
||||
ImGui::TextUnformatted(buffer.data());
|
||||
|
||||
if( isdieselenginepowered ) {
|
||||
std::snprintf(
|
||||
buffer.data(), buffer.size(),
|
||||
locale::strings[ locale::string::debug_vehicle_temperatures ].c_str(),
|
||||
mover.dizel_heat.Ts,
|
||||
mover.dizel_heat.To,
|
||||
mover.dizel_heat.temperatura1,
|
||||
( mover.WaterCircuitsLink ? '-' : '|' ),
|
||||
mover.dizel_heat.temperatura2 );
|
||||
ImGui::TextUnformatted(buffer.data());
|
||||
}
|
||||
|
||||
std::string brakedelay;
|
||||
{
|
||||
std::vector<std::pair<int, std::string>> delays {
|
||||
{ bdelay_G, "G" },
|
||||
{ bdelay_P, "P" },
|
||||
{ bdelay_R, "R" },
|
||||
{ bdelay_M, "+Mg" } };
|
||||
|
||||
for( auto const &delay : delays ) {
|
||||
if( ( mover.BrakeDelayFlag & delay.first ) == delay.first ) {
|
||||
brakedelay += delay.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::snprintf(
|
||||
buffer.data(), buffer.size(),
|
||||
locale::strings[ locale::string::debug_vehicle_brakespressures ].c_str(),
|
||||
// brakes
|
||||
mover.fBrakeCtrlPos,
|
||||
mover.LocalBrakePosA,
|
||||
mover.BrakeOpModeFlag,
|
||||
brakedelay.c_str(),
|
||||
mover.LoadFlag,
|
||||
// cylinders
|
||||
mover.BrakePress,
|
||||
mover.LocBrakePress,
|
||||
mover.Hamulec->GetBrakeStatus(),
|
||||
// pipes
|
||||
mover.PipePress,
|
||||
mover.BrakeCtrlPos2,
|
||||
mover.ScndPipePress,
|
||||
mover.CntrlPipePress,
|
||||
// tanks
|
||||
mover.Hamulec->GetBRP(),
|
||||
mover.Compressor,
|
||||
mover.Hamulec->GetCRP() );
|
||||
|
||||
ImGui::TextUnformatted(buffer.data());
|
||||
|
||||
if( mover.EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) {
|
||||
std::snprintf(
|
||||
buffer.data(), buffer.size(),
|
||||
locale::strings[ locale::string::debug_vehicle_pantograph ].c_str(),
|
||||
mover.PantPress,
|
||||
( mover.bPantKurek3 ? '-' : '|' ) );
|
||||
ImGui::TextUnformatted(buffer.data());
|
||||
}
|
||||
|
||||
std::snprintf(
|
||||
buffer.data(), buffer.size(),
|
||||
locale::strings[ locale::string::debug_vehicle_forcesaccelerationvelocityposition ].c_str(),
|
||||
// forces
|
||||
mover.Ft * 0.001f * ( mover.ActiveCab ? mover.ActiveCab : vehicle.ctOwner ? vehicle.ctOwner->Controlling()->ActiveCab : 1 ) + 0.001f,
|
||||
mover.Fb * 0.001f,
|
||||
mover.Adhesive( mover.RunningTrack.friction ),
|
||||
( mover.SlippingWheels ? " (!)" : "" ),
|
||||
// acceleration
|
||||
mover.AccSVBased,
|
||||
mover.AccN + 0.001f,
|
||||
std::string( std::abs( mover.RunningShape.R ) > 10000.0 ? "~0" : to_string( mover.RunningShape.R, 0 ) ).c_str(),
|
||||
// velocity
|
||||
vehicle.GetVelocity(),
|
||||
mover.DistCounter,
|
||||
// position
|
||||
vehicle.GetPosition().x,
|
||||
vehicle.GetPosition().y,
|
||||
vehicle.GetPosition().z );
|
||||
|
||||
ImGui::TextUnformatted(buffer.data());
|
||||
}
|
||||
16
widgets/vehicleparams.h
Normal file
16
widgets/vehicleparams.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "uilayer.h"
|
||||
#include "translation.h"
|
||||
#include "command.h"
|
||||
|
||||
namespace ui
|
||||
{
|
||||
class vehicleparams_panel : public ui_panel
|
||||
{
|
||||
std::string m_vehicle_name;
|
||||
|
||||
public:
|
||||
vehicleparams_panel();
|
||||
|
||||
void render_contents() override;
|
||||
};
|
||||
} // namespace ui
|
||||
Reference in New Issue
Block a user