mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 20:19:19 +02:00
build 210324. event queue text filter enhancement, contextual uncoupling sounds, parameter support for python screens, radio and odometer state exposed to python scripts, configurable audio volume when paused, skydome color calculation tweak, fog color calculation tweak, doorstep cab control enhancement, tempomat cab control enhancement, pantograph selector preset list support, minor bug fixes
This commit is contained in:
102
Driver.cpp
102
Driver.cpp
@@ -964,7 +964,9 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
VelLimitLastDist.second = d + point.trTrack->Length() + fLength;
|
VelLimitLastDist.second = d + point.trTrack->Length() + fLength;
|
||||||
}
|
}
|
||||||
else if( VelLimitLastDist.second > 0 ) { // the speed limit can potentially start afterwards, so don't mark it as broken too soon
|
else if( VelLimitLastDist.second > 0 ) { // the speed limit can potentially start afterwards, so don't mark it as broken too soon
|
||||||
speedlimitiscontinuous = false;
|
if( ( point.iFlags & ( spSwitch | spPassengerStopPoint ) ) == 0 ) {
|
||||||
|
speedlimitiscontinuous = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( false == railwaytrackend ) {
|
if( false == railwaytrackend ) {
|
||||||
continue; // i tyle wystarczy
|
continue; // i tyle wystarczy
|
||||||
@@ -1213,7 +1215,7 @@ TController::TableUpdateStopPoint( TCommandType &Command, TSpeedPos &Point, doub
|
|||||||
//jeśli nie widzi następnego sygnału ustawia dotychczasową
|
//jeśli nie widzi następnego sygnału ustawia dotychczasową
|
||||||
eSignNext = Point.evEvent;
|
eSignNext = Point.evEvent;
|
||||||
}
|
}
|
||||||
if( mvOccupied->Vel > 0.3 ) {
|
if( mvOccupied->Vel > EU07_AI_MOVEMENT ) {
|
||||||
// jeśli jedzie (nie trzeba czekać, aż się drgania wytłumią - drzwi zamykane od 1.0) to będzie zatrzymanie
|
// jeśli jedzie (nie trzeba czekać, aż się drgania wytłumią - drzwi zamykane od 1.0) to będzie zatrzymanie
|
||||||
Point.fVelNext = 0;
|
Point.fVelNext = 0;
|
||||||
// potentially announce pending stop
|
// potentially announce pending stop
|
||||||
@@ -1540,7 +1542,7 @@ TController::TableUpdateEvent( double &Velocity, TCommandType &Command, TSpeedPo
|
|||||||
Velocity = 0.0;
|
Velocity = 0.0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VelSignalNext - Point.fVelNext;
|
VelSignalNext = Point.fVelNext;
|
||||||
if( Velocity < 0 ) {
|
if( Velocity < 0 ) {
|
||||||
Velocity = fVelMax;
|
Velocity = fVelMax;
|
||||||
VelSignal = fVelMax;
|
VelSignal = fVelMax;
|
||||||
@@ -2510,10 +2512,8 @@ bool TController::CheckVehicles(TOrders user)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ra 2014-09: tymczasowo prymitywne ustawienie warunku pod kątem SN61
|
// detect push-pull train configurations and mark them accordingly
|
||||||
if( ( is_emu() )
|
if( pVehicles[ end::front ]->is_connected( pVehicles[ end::rear ], coupling::control ) ) {
|
||||||
|| ( is_dmu() )
|
|
||||||
|| ( iVehicles == 1 ) ) {
|
|
||||||
// zmiana czoła przez zmianę kabiny
|
// zmiana czoła przez zmianę kabiny
|
||||||
iDrivigFlags |= movePushPull;
|
iDrivigFlags |= movePushPull;
|
||||||
}
|
}
|
||||||
@@ -2540,7 +2540,7 @@ void TController::Lights(int head, int rear)
|
|||||||
void TController::DirectionInitial()
|
void TController::DirectionInitial()
|
||||||
{ // ustawienie kierunku po wczytaniu trainset (może jechać na wstecznym
|
{ // ustawienie kierunku po wczytaniu trainset (może jechać na wstecznym
|
||||||
mvOccupied->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
|
mvOccupied->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
|
||||||
if (mvOccupied->Vel > 0.0)
|
if (mvOccupied->Vel > EU07_AI_NOMOVEMENT)
|
||||||
{ // jeśli na starcie jedzie
|
{ // jeśli na starcie jedzie
|
||||||
iDirection = iDirectionOrder =
|
iDirection = iDirectionOrder =
|
||||||
(mvOccupied->V > 0 ? 1 : -1); // początkowa prędkość wymusza kierunek jazdy
|
(mvOccupied->V > 0 ? 1 : -1); // początkowa prędkość wymusza kierunek jazdy
|
||||||
@@ -2825,7 +2825,7 @@ bool TController::ReleaseEngine() {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// don't bother with the rest until we're standing still
|
// don't bother with the rest until we're standing still
|
||||||
if( mvOccupied->Vel > 0.01 ) { return false; }
|
if( mvOccupied->Vel > EU07_AI_NOMOVEMENT ) { return false; }
|
||||||
|
|
||||||
LastReactionTime = 0.0;
|
LastReactionTime = 0.0;
|
||||||
ReactionTime = PrepareTime;
|
ReactionTime = PrepareTime;
|
||||||
@@ -3248,7 +3248,7 @@ bool TController::DecBrakeEIM()
|
|||||||
{
|
{
|
||||||
case 0: {
|
case 0: {
|
||||||
if( mvOccupied->MED_amax != 9.81 ) {
|
if( mvOccupied->MED_amax != 9.81 ) {
|
||||||
auto const desiredacceleration { ( mvOccupied->Vel > 0.01 ? AccDesired : std::max( 0.0, AccDesired ) ) };
|
auto const desiredacceleration { ( mvOccupied->Vel > EU07_AI_NOMOVEMENT ? AccDesired : std::max( 0.0, AccDesired ) ) };
|
||||||
auto const brakeposition { clamp( -1.0 * mvOccupied->AIHintLocalBrakeAccFactor * desiredacceleration / mvOccupied->MED_amax, 0.0, 1.0 ) };
|
auto const brakeposition { clamp( -1.0 * mvOccupied->AIHintLocalBrakeAccFactor * desiredacceleration / mvOccupied->MED_amax, 0.0, 1.0 ) };
|
||||||
OK = ( brakeposition != mvOccupied->LocalBrakePosA );
|
OK = ( brakeposition != mvOccupied->LocalBrakePosA );
|
||||||
mvOccupied->LocalBrakePosA = brakeposition;
|
mvOccupied->LocalBrakePosA = brakeposition;
|
||||||
@@ -3684,7 +3684,7 @@ void TController::SpeedSet() {
|
|||||||
else {
|
else {
|
||||||
// jak ma jechać
|
// jak ma jechać
|
||||||
if( fActionTime < 0.0 ) { break; }
|
if( fActionTime < 0.0 ) { break; }
|
||||||
if( fReady > ( mvOccupied->Vel > 5.0 ? 0.5 : 0.4 ) ) { break; }
|
if( false == Ready ) { break; }
|
||||||
|
|
||||||
if( mvOccupied->DirActive > 0 ) {
|
if( mvOccupied->DirActive > 0 ) {
|
||||||
mvOccupied->DirectionForward(); //żeby EN57 jechały na drugiej nastawie
|
mvOccupied->DirectionForward(); //żeby EN57 jechały na drugiej nastawie
|
||||||
@@ -4210,7 +4210,7 @@ void TController::Doors( bool const Open, int const Side ) {
|
|||||||
|
|
||||||
if( ( true == ismanualdoor )
|
if( ( true == ismanualdoor )
|
||||||
&& ( ( vehicle->LoadExchangeTime() == 0.f )
|
&& ( ( vehicle->LoadExchangeTime() == 0.f )
|
||||||
|| ( vehicle->MoverParameters->Vel > 0.1 ) ) ) {
|
|| ( vehicle->MoverParameters->Vel > EU07_AI_MOVEMENT ) ) ) {
|
||||||
vehicle->MoverParameters->OperateDoors( side::right, false, range_t::local );
|
vehicle->MoverParameters->OperateDoors( side::right, false, range_t::local );
|
||||||
vehicle->MoverParameters->OperateDoors( side::left, false, range_t::local );
|
vehicle->MoverParameters->OperateDoors( side::left, false, range_t::local );
|
||||||
}
|
}
|
||||||
@@ -4535,7 +4535,7 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
|||||||
OrderNext(o); // to samo robić po zmianie
|
OrderNext(o); // to samo robić po zmianie
|
||||||
else if (!o) // jeśli wcześniej było czekanie
|
else if (!o) // jeśli wcześniej było czekanie
|
||||||
OrderNext(Shunt); // to dalej jazda manewrowa
|
OrderNext(Shunt); // to dalej jazda manewrowa
|
||||||
if (mvOccupied->Vel >= 1.0) // jeśli jedzie
|
if (mvOccupied->Vel >= EU07_AI_MOVEMENT) // jeśli jedzie
|
||||||
iDrivigFlags &= ~moveStartHorn; // to bez trąbienia po ruszeniu z zatrzymania
|
iDrivigFlags &= ~moveStartHorn; // to bez trąbienia po ruszeniu z zatrzymania
|
||||||
// Change_direction wykona się samo i następnie przejdzie do kolejnej komendy
|
// Change_direction wykona się samo i następnie przejdzie do kolejnej komendy
|
||||||
return true;
|
return true;
|
||||||
@@ -4795,7 +4795,7 @@ TController::Update( double const Timedelta ) {
|
|||||||
auto const awarenessrange {
|
auto const awarenessrange {
|
||||||
std::max(
|
std::max(
|
||||||
750.0,
|
750.0,
|
||||||
mvOccupied->Vel > 5.0 ?
|
mvOccupied->Vel > EU07_AI_MOVEMENT ?
|
||||||
400 + fBrakeDist :
|
400 + fBrakeDist :
|
||||||
30.0 * fDriverDist ) }; // 1500m dla stojących pociągów;
|
30.0 * fDriverDist ) }; // 1500m dla stojących pociągów;
|
||||||
if( is_active() ) {
|
if( is_active() ) {
|
||||||
@@ -4893,8 +4893,9 @@ TController::PrepareDirection() {
|
|||||||
|
|
||||||
if( iDirection == 0 ) {
|
if( iDirection == 0 ) {
|
||||||
// jeśli nie ma ustalonego kierunku
|
// jeśli nie ma ustalonego kierunku
|
||||||
if( mvOccupied->Vel < 0.01 ) { // ustalenie kierunku, gdy stoi
|
if( mvOccupied->Vel < EU07_AI_NOMOVEMENT ) { // ustalenie kierunku, gdy stoi
|
||||||
iDirection = mvOccupied->CabActive; // wg wybranej kabiny
|
iDirection = mvOccupied->CabActive; // wg wybranej kabiny
|
||||||
|
/*
|
||||||
if( iDirection == 0 ) {
|
if( iDirection == 0 ) {
|
||||||
// jeśli nie ma ustalonego kierunku
|
// jeśli nie ma ustalonego kierunku
|
||||||
if( mvOccupied->Couplers[ end::rear ].Connected == nullptr ) {
|
if( mvOccupied->Couplers[ end::rear ].Connected == nullptr ) {
|
||||||
@@ -4906,6 +4907,7 @@ TController::PrepareDirection() {
|
|||||||
iDirection = 1; // jazda w kierunku sprzęgu 0
|
iDirection = 1; // jazda w kierunku sprzęgu 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// ustalenie kierunku, gdy jedzie
|
// ustalenie kierunku, gdy jedzie
|
||||||
@@ -5354,7 +5356,7 @@ TCommandType TController::BackwardScan( double const Range )
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if( ( scandist > fMinProximityDist )
|
if( ( scandist > fMinProximityDist )
|
||||||
&& ( ( mvOccupied->Vel > 0.0 )
|
&& ( ( mvOccupied->Vel > EU07_AI_NOMOVEMENT )
|
||||||
&& ( ( OrderCurrentGet() & ( Shunt | Loose_shunt ) ) == 0 ) ) ) {
|
&& ( ( OrderCurrentGet() & ( Shunt | Loose_shunt ) ) == 0 ) ) ) {
|
||||||
// jeśli semafor jest daleko, a pojazd jedzie, to informujemy o zmianie prędkości
|
// jeśli semafor jest daleko, a pojazd jedzie, to informujemy o zmianie prędkości
|
||||||
// jeśli jedzie manewrowo, musi dostać SetVelocity, żeby sie na pociągowy przełączył
|
// jeśli jedzie manewrowo, musi dostać SetVelocity, żeby sie na pociągowy przełączył
|
||||||
@@ -5393,12 +5395,12 @@ TCommandType TController::BackwardScan( double const Range )
|
|||||||
if (move ? true : e->input_command() == TCommandType::cm_ShuntVelocity)
|
if (move ? true : e->input_command() == TCommandType::cm_ShuntVelocity)
|
||||||
{ // jeśli powyżej było SetVelocity 0 0, to dociągamy pod S1
|
{ // jeśli powyżej było SetVelocity 0 0, to dociągamy pod S1
|
||||||
if ((scandist > fMinProximityDist) &&
|
if ((scandist > fMinProximityDist) &&
|
||||||
(mvOccupied->Vel > 0.0) || (vmechmax == 0.0) )
|
(mvOccupied->Vel > EU07_AI_NOMOVEMENT) || (vmechmax == 0.0) )
|
||||||
{ // jeśli tarcza jest daleko, to:
|
{ // jeśli tarcza jest daleko, to:
|
||||||
//- jesli pojazd jedzie, to informujemy o zmianie prędkości
|
//- jesli pojazd jedzie, to informujemy o zmianie prędkości
|
||||||
//- jeśli stoi, to z własnej inicjatywy może podjechać pod zamkniętą
|
//- jeśli stoi, to z własnej inicjatywy może podjechać pod zamkniętą
|
||||||
// tarczę
|
// tarczę
|
||||||
if (mvOccupied->Vel > 0.0) // tylko jeśli jedzie
|
if (mvOccupied->Vel > EU07_AI_NOMOVEMENT) // tylko jeśli jedzie
|
||||||
{ // Mechanik->PutCommand("SetProximityVelocity",scandist,vmechmax,sl);
|
{ // Mechanik->PutCommand("SetProximityVelocity",scandist,vmechmax,sl);
|
||||||
#if LOGBACKSCAN
|
#if LOGBACKSCAN
|
||||||
// WriteLog(edir+"SetProximityVelocity "+AnsiString(scandist)+"
|
// WriteLog(edir+"SetProximityVelocity "+AnsiString(scandist)+"
|
||||||
@@ -5907,7 +5909,7 @@ TController::determine_consist_state() {
|
|||||||
fAccGravity /= fMass;
|
fAccGravity /= fMass;
|
||||||
{
|
{
|
||||||
auto absaccs { fAccGravity }; // Ra 2014-03: jesli skład stoi, to działa na niego składowa styczna grawitacji
|
auto absaccs { fAccGravity }; // Ra 2014-03: jesli skład stoi, to działa na niego składowa styczna grawitacji
|
||||||
if( mvOccupied->Vel > 0.01 ) {
|
if( mvOccupied->Vel > EU07_AI_NOMOVEMENT ) {
|
||||||
absaccs = 0;
|
absaccs = 0;
|
||||||
auto *d = pVehicles[ end::front ]; // pojazd na czele składu
|
auto *d = pVehicles[ end::front ]; // pojazd na czele składu
|
||||||
while( d ) {
|
while( d ) {
|
||||||
@@ -5939,7 +5941,7 @@ TController::determine_consist_state() {
|
|||||||
if( has_diesel_engine() ) {
|
if( has_diesel_engine() ) {
|
||||||
|
|
||||||
Ready = (
|
Ready = (
|
||||||
( vehicle->Vel > 0.5 ) // already moving
|
( vehicle->Vel > EU07_AI_MOVEMENT ) // already moving
|
||||||
|| ( false == vehicle->Mains ) // deadweight vehicle
|
|| ( false == vehicle->Mains ) // deadweight vehicle
|
||||||
|| ( vehicle->enrot > 0.8 * (
|
|| ( vehicle->enrot > 0.8 * (
|
||||||
vehicle->EngineType == TEngineType::DieselEngine ?
|
vehicle->EngineType == TEngineType::DieselEngine ?
|
||||||
@@ -6001,7 +6003,7 @@ TController::control_pantographs() {
|
|||||||
|| ( is_emu() ) // special case
|
|| ( is_emu() ) // special case
|
||||||
|| ( mvControlling->TrainType == dt_ET41 ) }; // special case
|
|| ( mvControlling->TrainType == dt_ET41 ) }; // special case
|
||||||
|
|
||||||
if( mvOccupied->Vel > 0.05 ) {
|
if( mvOccupied->Vel > EU07_AI_NOMOVEMENT ) {
|
||||||
|
|
||||||
if( ( fOverhead2 >= 0.0 ) || iOverheadZero ) {
|
if( ( fOverhead2 >= 0.0 ) || iOverheadZero ) {
|
||||||
// jeśli jazda bezprądowa albo z opuszczonym pantografem
|
// jeśli jazda bezprądowa albo z opuszczonym pantografem
|
||||||
@@ -6116,7 +6118,7 @@ TController::control_horns( double const Timedelta ) {
|
|||||||
cue_action( locale::string::driver_hint_hornoff ); // a tu się kończy
|
cue_action( locale::string::driver_hint_hornoff ); // a tu się kończy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( mvOccupied->Vel >= 5.0 ) {
|
if( mvOccupied->Vel > EU07_AI_MOVEMENT ) {
|
||||||
// jesli jedzie, można odblokować trąbienie, bo się wtedy nie włączy
|
// jesli jedzie, można odblokować trąbienie, bo się wtedy nie włączy
|
||||||
iDrivigFlags &= ~moveStartHornDone; // zatrąbi dopiero jak następnym razem stanie
|
iDrivigFlags &= ~moveStartHornDone; // zatrąbi dopiero jak następnym razem stanie
|
||||||
iDrivigFlags |= moveStartHorn; // i trąbić przed następnym ruszeniem
|
iDrivigFlags |= moveStartHorn; // i trąbić przed następnym ruszeniem
|
||||||
@@ -6292,7 +6294,7 @@ TController::control_doors() {
|
|||||||
if( false == doors_open() ) { return; }
|
if( false == doors_open() ) { return; }
|
||||||
// jeżeli jedzie
|
// jeżeli jedzie
|
||||||
// nie zamykać drzwi przy drganiach, bo zatrzymanie na W4 akceptuje niewielkie prędkości
|
// nie zamykać drzwi przy drganiach, bo zatrzymanie na W4 akceptuje niewielkie prędkości
|
||||||
if( mvOccupied->Vel > 1.0 ) {
|
if( mvOccupied->Vel > EU07_AI_MOVEMENT ) {
|
||||||
Doors( false );
|
Doors( false );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -6600,25 +6602,30 @@ TController::check_departure() {
|
|||||||
void
|
void
|
||||||
TController::UpdateChangeDirection() {
|
TController::UpdateChangeDirection() {
|
||||||
// TODO: rework into driver mode independent routine
|
// TODO: rework into driver mode independent routine
|
||||||
if( ( true == AIControllFlag)
|
if( false == TestFlag( OrderCurrentGet(), Change_direction ) ) { return; }
|
||||||
&& ( true == TestFlag( OrderCurrentGet(), Change_direction ) ) ) {
|
|
||||||
|
if( true == AIControllFlag ) {
|
||||||
// sprobuj zmienic kierunek (może być zmieszane z jeszcze jakąś komendą)
|
// sprobuj zmienic kierunek (może być zmieszane z jeszcze jakąś komendą)
|
||||||
if( mvOccupied->Vel < 0.1 ) {
|
if( mvOccupied->Vel < EU07_AI_NOMOVEMENT ) {
|
||||||
// jeśli się zatrzymał, to zmieniamy kierunek jazdy, a nawet kabinę/człon
|
// jeśli się zatrzymał, to zmieniamy kierunek jazdy, a nawet kabinę/człon
|
||||||
Activation(); // ustawienie zadanego wcześniej kierunku i ewentualne przemieszczenie AI
|
Activation(); // ustawienie zadanego wcześniej kierunku i ewentualne przemieszczenie AI
|
||||||
PrepareEngine();
|
} // Change_direction (tylko dla AI)
|
||||||
JumpToNextOrder(); // następnie robimy, co jest do zrobienia (Shunt albo Obey_train)
|
}
|
||||||
if( OrderCurrentGet() & ( Shunt | Loose_shunt | Connect ) ) {
|
// shared part of the routine, implement if direction matches what was requested
|
||||||
// jeśli dalej mamy manewry
|
if( ( mvOccupied->Vel < EU07_AI_NOMOVEMENT )
|
||||||
if( false == TestFlag( iDrivigFlags, moveStopHere ) ) {
|
&& ( iDirection == iDirectionOrder ) ) {
|
||||||
// o ile nie ma stać w miejscu,
|
PrepareEngine();
|
||||||
// jechać od razu w przeciwną stronę i nie trąbić z tego tytułu:
|
JumpToNextOrder(); // następnie robimy, co jest do zrobienia (Shunt albo Obey_train)
|
||||||
iDrivigFlags &= ~moveStartHorn;
|
if( OrderCurrentGet() & ( Shunt | Loose_shunt | Connect ) ) {
|
||||||
SetVelocity( fShuntVelocity, fShuntVelocity );
|
// jeśli dalej mamy manewry
|
||||||
}
|
if( false == TestFlag( iDrivigFlags, moveStopHere ) ) {
|
||||||
|
// o ile nie ma stać w miejscu,
|
||||||
|
// jechać od razu w przeciwną stronę i nie trąbić z tego tytułu:
|
||||||
|
iDrivigFlags &= ~moveStartHorn;
|
||||||
|
SetVelocity( fShuntVelocity, fShuntVelocity );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // Change_direction (tylko dla AI)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -7116,7 +7123,7 @@ TController::adjust_desired_speed_for_obstacles() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ReactionTime = (
|
ReactionTime = (
|
||||||
mvOccupied->Vel > 0.01 ?
|
mvOccupied->Vel > EU07_AI_NOMOVEMENT ?
|
||||||
0.1 : // orientuj się, bo jest goraco
|
0.1 : // orientuj się, bo jest goraco
|
||||||
2.0 ); // we're already standing still, so take it easy
|
2.0 ); // we're already standing still, so take it easy
|
||||||
}
|
}
|
||||||
@@ -7225,7 +7232,7 @@ TController::adjust_desired_speed_for_target_speed( double const Range ) {
|
|||||||
&& ( ActualProximityDist <= Range )
|
&& ( ActualProximityDist <= Range )
|
||||||
&& ( vel >= VelNext ) ) {
|
&& ( vel >= VelNext ) ) {
|
||||||
// gdy zbliża się i jest za szybki do nowej prędkości, albo stoi na zatrzymaniu
|
// gdy zbliża się i jest za szybki do nowej prędkości, albo stoi na zatrzymaniu
|
||||||
if (vel > 0.0) {
|
if (vel > EU07_AI_NOMOVEMENT) {
|
||||||
// jeśli jedzie
|
// jeśli jedzie
|
||||||
if( ( vel < VelNext )
|
if( ( vel < VelNext )
|
||||||
&& ( ActualProximityDist > fMaxProximityDist * ( 1.0 + 0.1 * vel ) ) ) {
|
&& ( ActualProximityDist > fMaxProximityDist * ( 1.0 + 0.1 * vel ) ) ) {
|
||||||
@@ -7402,7 +7409,7 @@ TController::adjust_desired_speed_for_current_speed() {
|
|||||||
clamp( VelDesired - speedestimate, 0.0, fVelMinus ) / fVelMinus ) );
|
clamp( VelDesired - speedestimate, 0.0, fVelMinus ) / fVelMinus ) );
|
||||||
}
|
}
|
||||||
// final tweaks
|
// final tweaks
|
||||||
if( vel > 0.1 ) {
|
if( vel > EU07_AI_NOMOVEMENT ) {
|
||||||
// going downhill also take into account impact of gravity
|
// going downhill also take into account impact of gravity
|
||||||
AccDesired -= fAccGravity;
|
AccDesired -= fAccGravity;
|
||||||
// HACK: if the max allowed speed was exceeded something went wrong; brake harder
|
// HACK: if the max allowed speed was exceeded something went wrong; brake harder
|
||||||
@@ -7450,7 +7457,7 @@ TController::adjust_desired_speed_for_current_speed() {
|
|||||||
if( vel < VelDesired ) {
|
if( vel < VelDesired ) {
|
||||||
// don't adjust acceleration when going above current target speed
|
// don't adjust acceleration when going above current target speed
|
||||||
if( -AccDesired * BrakeAccFactor() < (
|
if( -AccDesired * BrakeAccFactor() < (
|
||||||
( ( fReady > ( IsHeavyCargoTrain ? 0.4 : ( mvOccupied->Vel > 5.0 ) ? 0.45 : 0.4 ) )
|
( ( false == Ready )
|
||||||
|| ( VelNext > vel - 40.0 ) ) ?
|
|| ( VelNext > vel - 40.0 ) ) ?
|
||||||
fBrake_a0[ 0 ] * 0.8 :
|
fBrake_a0[ 0 ] * 0.8 :
|
||||||
-fAccThreshold )
|
-fAccThreshold )
|
||||||
@@ -7483,7 +7490,7 @@ TController::control_tractive_and_braking_force() {
|
|||||||
|
|
||||||
// if the radio-stop was issued don't waste effort trying to fight it
|
// if the radio-stop was issued don't waste effort trying to fight it
|
||||||
if( ( true == mvOccupied->RadioStopFlag ) // radio-stop
|
if( ( true == mvOccupied->RadioStopFlag ) // radio-stop
|
||||||
&& ( mvOccupied->Vel > 0.0 ) ) { // and still moving
|
&& ( mvOccupied->Vel > EU07_AI_NOMOVEMENT ) ) { // and still moving
|
||||||
cue_action( locale::string::driver_hint_mastercontrollersetzerospeed ); // just throttle down...
|
cue_action( locale::string::driver_hint_mastercontrollersetzerospeed ); // just throttle down...
|
||||||
return; // ...and don't touch any other controls
|
return; // ...and don't touch any other controls
|
||||||
}
|
}
|
||||||
@@ -7702,15 +7709,18 @@ void TController::control_braking_force() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// odhamowywanie składu po zatrzymaniu i zabezpieczanie lokomotywy
|
// odhamowywanie składu po zatrzymaniu i zabezpieczanie lokomotywy
|
||||||
if( ( mvOccupied->Vel < 0.01 )
|
if( ( mvOccupied->Vel < EU07_AI_NOMOVEMENT )
|
||||||
&& ( ( VelDesired == 0.0 )
|
&& ( ( VelDesired == 0.0 )
|
||||||
|| ( AccDesired <= EU07_AI_NOACCELERATION ) ) ) {
|
|| ( AccDesired <= EU07_AI_NOACCELERATION ) ) ) {
|
||||||
|
|
||||||
if( ( ( OrderCurrentGet() & ( Disconnect | Connect ) ) == 0 ) // przy (p)odłączaniu nie zwalniamy tu hamulca
|
if( ( ( OrderCurrentGet() & ( Disconnect | Connect | Change_direction ) ) == 0 ) // przy (p)odłączaniu nie zwalniamy tu hamulca
|
||||||
&& ( std::abs( fAccGravity ) < 0.01 ) ) { // only do this on flats, on slopes keep applied the train brake
|
&& ( std::abs( fAccGravity ) < 0.01 ) ) { // only do this on flats, on slopes keep applied the train brake
|
||||||
// do it only if the vehicle actually has the independent brake
|
|
||||||
apply_independent_brake_only();
|
apply_independent_brake_only();
|
||||||
}
|
}
|
||||||
|
// if told to change direction don't confuse human driver with request to leave applied brake in the cab they're about to leave
|
||||||
|
if( ( OrderCurrentGet() & ( Change_direction ) ) != 0 ) {
|
||||||
|
cue_action( locale::string::driver_hint_independentbrakerelease );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7924,7 +7934,7 @@ TController::check_route_behind( double const Range ) {
|
|||||||
void
|
void
|
||||||
TController::UpdateBrakingHelper() {
|
TController::UpdateBrakingHelper() {
|
||||||
|
|
||||||
if (( HelperState > 0 ) && (-AccDesired < fBrake_a0[0] + 2 * fBrake_a1[0]) && (mvOccupied->Vel > 1)) {
|
if (( HelperState > 0 ) && (-AccDesired < fBrake_a0[0] + 2 * fBrake_a1[0]) && (mvOccupied->Vel > EU07_AI_NOMOVEMENT)) {
|
||||||
HelperState = 0;
|
HelperState = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
Driver.h
2
Driver.h
@@ -18,6 +18,8 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "translation.h"
|
#include "translation.h"
|
||||||
|
|
||||||
auto const EU07_AI_NOACCELERATION = -0.05;
|
auto const EU07_AI_NOACCELERATION = -0.05;
|
||||||
|
auto const EU07_AI_NOMOVEMENT = 0.05; // standstill velocity threshold
|
||||||
|
auto const EU07_AI_MOVEMENT = 1.0; // deliberate movement velocity threshold
|
||||||
auto const EU07_AI_SPEEDLIMITEXTENDSBEYONDSCANRANGE = 10000.0;
|
auto const EU07_AI_SPEEDLIMITEXTENDSBEYONDSCANRANGE = 10000.0;
|
||||||
|
|
||||||
enum TOrders
|
enum TOrders
|
||||||
|
|||||||
73
DynObj.cpp
73
DynObj.cpp
@@ -249,6 +249,9 @@ bool TDynamicObject::destination_data::deserialize_mapping( cParser &Input ) {
|
|||||||
else if( key == "parameters:" ) {
|
else if( key == "parameters:" ) {
|
||||||
parameters = Input.getToken<std::string>();
|
parameters = Input.getToken<std::string>();
|
||||||
}
|
}
|
||||||
|
else if( key == "background:" ) {
|
||||||
|
background = Input.getToken<std::string>();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4648,31 +4651,47 @@ void TDynamicObject::RenderSounds() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// attach/detach sounds
|
// attach/detach sounds
|
||||||
if( ( coupler.sounds & sound::attachcoupler ) != 0 ) {
|
if( ( coupler.sounds & sound::detach ) == 0 ) {
|
||||||
couplersounds.attach_coupler.play();
|
// potentially added some couplings
|
||||||
|
if( ( coupler.sounds & sound::attachcoupler ) != 0 ) {
|
||||||
|
couplersounds.attach_coupler.play();
|
||||||
|
}
|
||||||
|
if( ( coupler.sounds & sound::attachbrakehose ) != 0 ) {
|
||||||
|
couplersounds.attach_brakehose.play();
|
||||||
|
}
|
||||||
|
if( ( coupler.sounds & sound::attachmainhose ) != 0 ) {
|
||||||
|
couplersounds.attach_mainhose.play();
|
||||||
|
}
|
||||||
|
if( ( coupler.sounds & sound::attachcontrol ) != 0 ) {
|
||||||
|
couplersounds.attach_control.play();
|
||||||
|
}
|
||||||
|
if( ( coupler.sounds & sound::attachgangway ) != 0 ) {
|
||||||
|
couplersounds.attach_gangway.play();
|
||||||
|
}
|
||||||
|
if( ( coupler.sounds & sound::attachheating ) != 0 ) {
|
||||||
|
couplersounds.attach_heating.play();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( ( coupler.sounds & sound::attachbrakehose ) != 0 ) {
|
else {
|
||||||
couplersounds.attach_brakehose.play();
|
// potentially removed some couplings
|
||||||
}
|
if( ( coupler.sounds & sound::attachcoupler ) != 0 ) {
|
||||||
if( ( coupler.sounds & sound::attachmainhose ) != 0 ) {
|
couplersounds.detach_coupler.play();
|
||||||
couplersounds.attach_mainhose.play();
|
}
|
||||||
}
|
if( ( coupler.sounds & sound::attachbrakehose ) != 0 ) {
|
||||||
if( ( coupler.sounds & sound::attachcontrol ) != 0 ) {
|
couplersounds.detach_brakehose.play();
|
||||||
couplersounds.attach_control.play();
|
}
|
||||||
}
|
if( ( coupler.sounds & sound::attachmainhose ) != 0 ) {
|
||||||
if( ( coupler.sounds & sound::attachgangway ) != 0 ) {
|
couplersounds.detach_mainhose.play();
|
||||||
couplersounds.attach_gangway.play();
|
}
|
||||||
}
|
if( ( coupler.sounds & sound::attachcontrol ) != 0 ) {
|
||||||
if( ( coupler.sounds & sound::attachheating ) != 0 ) {
|
couplersounds.detach_control.play();
|
||||||
couplersounds.attach_heating.play();
|
}
|
||||||
}
|
if( ( coupler.sounds & sound::attachgangway ) != 0 ) {
|
||||||
if( true == TestFlag( coupler.sounds, sound::detachall ) ) {
|
couplersounds.detach_gangway.play();
|
||||||
couplersounds.detach_coupler.play();
|
}
|
||||||
couplersounds.detach_brakehose.play();
|
if( ( coupler.sounds & sound::attachheating ) != 0 ) {
|
||||||
couplersounds.detach_mainhose.play();
|
couplersounds.detach_heating.play();
|
||||||
couplersounds.detach_control.play();
|
}
|
||||||
couplersounds.detach_gangway.play();
|
|
||||||
couplersounds.detach_heating.play();
|
|
||||||
}
|
}
|
||||||
if( true == TestFlag( coupler.sounds, sound::attachadapter ) ) {
|
if( true == TestFlag( coupler.sounds, sound::attachadapter ) ) {
|
||||||
couplersounds.dsbAdapterAttach.play();
|
couplersounds.dsbAdapterAttach.play();
|
||||||
@@ -5992,12 +6011,15 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
// vehicle faces +Z in 'its' space, for motor locations negative value means ahead of centre
|
// vehicle faces +Z in 'its' space, for motor locations negative value means ahead of centre
|
||||||
auto const offset { std::atof( token.c_str() ) * -1.f };
|
auto const offset { std::atof( token.c_str() ) * -1.f };
|
||||||
// NOTE: we skip setting owner of the sounds, it'll be done during individual sound deserialization
|
// NOTE: we skip setting owner of the sounds, it'll be done during individual sound deserialization
|
||||||
sound_source motor { sound_placement::external }; // generally traction motor
|
sound_source motor { sound_placement::external }; // generic traction motor sounds
|
||||||
|
sound_source acmotor { sound_placement::external }; // inverter-specific traction motor sounds
|
||||||
sound_source motorblower { sound_placement::engine }; // associated motor blowers
|
sound_source motorblower { sound_placement::engine }; // associated motor blowers
|
||||||
// add entry to the list
|
// add entry to the list
|
||||||
auto const location { glm::vec3 { 0.f, 0.f, offset } };
|
auto const location { glm::vec3 { 0.f, 0.f, offset } };
|
||||||
motor.offset( location );
|
motor.offset( location );
|
||||||
m_powertrainsounds.motors.emplace_back( motor );
|
m_powertrainsounds.motors.emplace_back( motor );
|
||||||
|
acmotor.offset( location );
|
||||||
|
m_powertrainsounds.acmotors.emplace_back( acmotor );
|
||||||
motorblower.offset( location );
|
motorblower.offset( location );
|
||||||
m_powertrainsounds.motorblowers.emplace_back( motorblower );
|
m_powertrainsounds.motorblowers.emplace_back( motorblower );
|
||||||
}
|
}
|
||||||
@@ -6344,6 +6366,7 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
DestinationSign.script = asBaseDir + DestinationSign.script;
|
DestinationSign.script = asBaseDir + DestinationSign.script;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// NOTE: legacy key, now expected as optional "background:" parameter in pydestinationsign: { parameter block }
|
||||||
else if( token == "destinationsignbackground:" ) {
|
else if( token == "destinationsignbackground:" ) {
|
||||||
parser.getTokens();
|
parser.getTokens();
|
||||||
parser >> DestinationSign.background;
|
parser >> DestinationSign.background;
|
||||||
|
|||||||
8
Gauge.h
8
Gauge.h
@@ -58,6 +58,14 @@ public:
|
|||||||
// returns offset of submodel associated with the button from the model centre
|
// returns offset of submodel associated with the button from the model centre
|
||||||
glm::vec3 model_offset() const;
|
glm::vec3 model_offset() const;
|
||||||
TGaugeType type() const;
|
TGaugeType type() const;
|
||||||
|
inline
|
||||||
|
bool is_push() const {
|
||||||
|
return ( static_cast<int>( type() ) & static_cast<int>( TGaugeType::push ) ) != 0; }
|
||||||
|
inline
|
||||||
|
bool is_toggle() const {
|
||||||
|
return ( static_cast<int>( type() ) & static_cast<int>( TGaugeType::toggle ) ) != 0; }
|
||||||
|
bool is_delayed() const {
|
||||||
|
return ( static_cast<int>( type() ) & static_cast<int>( TGaugeType::delayed ) ) != 0; }
|
||||||
// members
|
// members
|
||||||
TSubModel *SubModel { nullptr }, // McZapkie-310302: zeby mozna bylo sprawdzac czy zainicjowany poprawnie
|
TSubModel *SubModel { nullptr }, // McZapkie-310302: zeby mozna bylo sprawdzac czy zainicjowany poprawnie
|
||||||
*SubModelOn { nullptr }; // optional submodel visible when the state input is set
|
*SubModelOn { nullptr }; // optional submodel visible when the state input is set
|
||||||
|
|||||||
@@ -174,6 +174,12 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
Parser >> EnvironmentAmbientVolume;
|
Parser >> EnvironmentAmbientVolume;
|
||||||
EnvironmentAmbientVolume = clamp(EnvironmentAmbientVolume, 0.f, 1.f);
|
EnvironmentAmbientVolume = clamp(EnvironmentAmbientVolume, 0.f, 1.f);
|
||||||
}
|
}
|
||||||
|
else if( token == "sound.volume.paused" ) {
|
||||||
|
// selected device for audio renderer
|
||||||
|
Parser.getTokens();
|
||||||
|
Parser >> PausedVolume;
|
||||||
|
EnvironmentAmbientVolume = clamp( EnvironmentAmbientVolume, 0.f, 1.f );
|
||||||
|
}
|
||||||
// else if (str==AnsiString("renderalpha")) //McZapkie-1312302 - dwuprzebiegowe renderowanie
|
// else if (str==AnsiString("renderalpha")) //McZapkie-1312302 - dwuprzebiegowe renderowanie
|
||||||
// bRenderAlpha=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
// bRenderAlpha=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||||
else if (token == "physicslog")
|
else if (token == "physicslog")
|
||||||
@@ -1035,6 +1041,7 @@ global_settings::export_as_text( std::ostream &Output ) const {
|
|||||||
export_as_text( Output, "sound.volume.vehicle", VehicleVolume );
|
export_as_text( Output, "sound.volume.vehicle", VehicleVolume );
|
||||||
export_as_text( Output, "sound.volume.positional", EnvironmentPositionalVolume );
|
export_as_text( Output, "sound.volume.positional", EnvironmentPositionalVolume );
|
||||||
export_as_text( Output, "sound.volume.ambient", EnvironmentAmbientVolume );
|
export_as_text( Output, "sound.volume.ambient", EnvironmentAmbientVolume );
|
||||||
|
export_as_text( Output, "sound.volume.paused", PausedVolume );
|
||||||
export_as_text( Output, "physicslog", WriteLogFlag );
|
export_as_text( Output, "physicslog", WriteLogFlag );
|
||||||
export_as_text( Output, "fullphysics", FullPhysics );
|
export_as_text( Output, "fullphysics", FullPhysics );
|
||||||
export_as_text( Output, "debuglog", iWriteLogEnabled );
|
export_as_text( Output, "debuglog", iWriteLogEnabled );
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ struct global_settings {
|
|||||||
float VehicleVolume{ 1.0f };
|
float VehicleVolume{ 1.0f };
|
||||||
float EnvironmentPositionalVolume{ 1.0f };
|
float EnvironmentPositionalVolume{ 1.0f };
|
||||||
float EnvironmentAmbientVolume{ 1.0f };
|
float EnvironmentAmbientVolume{ 1.0f };
|
||||||
|
float PausedVolume { 0.15f };
|
||||||
std::string AudioRenderer;
|
std::string AudioRenderer;
|
||||||
// input
|
// input
|
||||||
float fMouseXScale{ 1.5f };
|
float fMouseXScale{ 1.5f };
|
||||||
|
|||||||
@@ -243,7 +243,7 @@ enum sound {
|
|||||||
parallel = 1 << 4,
|
parallel = 1 << 4,
|
||||||
shuntfield = 1 << 5,
|
shuntfield = 1 << 5,
|
||||||
pneumatic = 1 << 6,
|
pneumatic = 1 << 6,
|
||||||
detachall = 1 << 7,
|
detach = 1 << 7,
|
||||||
attachcoupler = 1 << 8,
|
attachcoupler = 1 << 8,
|
||||||
attachbrakehose = 1 << 9,
|
attachbrakehose = 1 << 9,
|
||||||
attachmainhose = 1 << 10,
|
attachmainhose = 1 << 10,
|
||||||
@@ -1168,6 +1168,7 @@ public:
|
|||||||
bool UniCtrlIntegratedBrakeCtrl = false; /*zintegrowany nastawnik JH obsluguje hamowanie*/
|
bool UniCtrlIntegratedBrakeCtrl = false; /*zintegrowany nastawnik JH obsluguje hamowanie*/
|
||||||
bool UniCtrlIntegratedLocalBrakeCtrl = false; /*zintegrowany nastawnik JH obsluguje hamowanie hamulcem pomocniczym*/
|
bool UniCtrlIntegratedLocalBrakeCtrl = false; /*zintegrowany nastawnik JH obsluguje hamowanie hamulcem pomocniczym*/
|
||||||
int UniCtrlNoPowerPos{ 0 }; // cached highesr position not generating traction force
|
int UniCtrlNoPowerPos{ 0 }; // cached highesr position not generating traction force
|
||||||
|
std::pair<std::string, std::array<int, 2>> PantsPreset { "", { 0, 0 } }; // pantograph preset switches; .first holds possible setups as chars, .second holds currently selected preset in each cab
|
||||||
|
|
||||||
/*-sekcja parametrow dla lokomotywy elektrycznej*/
|
/*-sekcja parametrow dla lokomotywy elektrycznej*/
|
||||||
TSchemeTable RList; /*lista rezystorow rozruchowych i polaczen silnikow, dla dizla: napelnienia*/
|
TSchemeTable RList; /*lista rezystorow rozruchowych i polaczen silnikow, dla dizla: napelnienia*/
|
||||||
|
|||||||
@@ -511,23 +511,39 @@ bool TMoverParameters::Dettach(int ConnectNo)
|
|||||||
|
|
||||||
if( othervehicle == nullptr ) { return true; } // nie ma nic, to odczepiono
|
if( othervehicle == nullptr ) { return true; } // nie ma nic, to odczepiono
|
||||||
|
|
||||||
auto const i = DettachStatus(ConnectNo); // stan sprzęgu
|
auto couplingchange { coupler.CouplingFlag }; // presume we'll uncouple all active flags
|
||||||
if (i < 0) {
|
auto const couplingstate { DettachStatus( ConnectNo ) }; // stan sprzęgu
|
||||||
|
if (couplingstate < 0) {
|
||||||
// gdy scisniete zderzaki, chyba ze zerwany sprzeg (wirtualnego nie odpinamy z drugiej strony)
|
// gdy scisniete zderzaki, chyba ze zerwany sprzeg (wirtualnego nie odpinamy z drugiej strony)
|
||||||
std::tie( coupler.Connected, coupler.ConnectedNr, coupler.CouplingFlag )
|
std::tie( coupler.Connected, coupler.ConnectedNr, coupler.CouplingFlag )
|
||||||
= std::tie( othercoupler.Connected, othercoupler.ConnectedNr, othercoupler.CouplingFlag )
|
= std::tie( othercoupler.Connected, othercoupler.ConnectedNr, othercoupler.CouplingFlag )
|
||||||
= std::make_tuple( nullptr, -1, coupling::faux );
|
= std::make_tuple( nullptr, -1, coupling::faux );
|
||||||
// set sound event flag
|
|
||||||
SetFlag( coupler.sounds, sound::detachall );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else if (i > 0)
|
else if (couplingstate > 0)
|
||||||
{ // odłączamy węże i resztę, pozostaje sprzęg fizyczny, który wymaga dociśnięcia (z wirtualnym nic)
|
{ // odłączamy węże i resztę, pozostaje sprzęg fizyczny, który wymaga dociśnięcia (z wirtualnym nic)
|
||||||
coupler.CouplingFlag &= coupling::coupler;
|
coupler.CouplingFlag &= coupling::coupler;
|
||||||
othercoupler.CouplingFlag &= coupling::coupler;
|
othercoupler.CouplingFlag &= coupling::coupler;
|
||||||
}
|
}
|
||||||
return false; // jeszcze nie rozłączony
|
// set sound event flag
|
||||||
|
couplingchange ^= coupler.CouplingFlag; // remaining bits were removed from coupling
|
||||||
|
if( couplingchange != 0 ) {
|
||||||
|
int soundflag { sound::detach }; // HACK: use detach flag to indicate removal of listed coupling
|
||||||
|
std::vector<std::pair<coupling, sound>> const soundmappings = {
|
||||||
|
{ coupling::coupler, sound::attachcoupler },
|
||||||
|
{ coupling::brakehose, sound::attachbrakehose },
|
||||||
|
{ coupling::mainhose, sound::attachmainhose },
|
||||||
|
{ coupling::control, sound::attachcontrol},
|
||||||
|
{ coupling::gangway, sound::attachgangway},
|
||||||
|
{ coupling::heating, sound::attachheating} };
|
||||||
|
for( auto const &soundmapping : soundmappings ) {
|
||||||
|
if( ( couplingchange & soundmapping.first ) != 0 ) {
|
||||||
|
soundflag |= soundmapping.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetFlag( coupler.sounds, soundflag );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( couplingstate < 0 );
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TMoverParameters::DirectionForward()
|
bool TMoverParameters::DirectionForward()
|
||||||
@@ -10800,6 +10816,14 @@ void TMoverParameters::LoadFIZ_Switches( std::string const &Input ) {
|
|||||||
extract_value( UniversalResetButtonFlag[ 0 ], "RelayResetButton1", Input, "" );
|
extract_value( UniversalResetButtonFlag[ 0 ], "RelayResetButton1", Input, "" );
|
||||||
extract_value( UniversalResetButtonFlag[ 1 ], "RelayResetButton2", Input, "" );
|
extract_value( UniversalResetButtonFlag[ 1 ], "RelayResetButton2", Input, "" );
|
||||||
extract_value( UniversalResetButtonFlag[ 2 ], "RelayResetButton3", Input, "" );
|
extract_value( UniversalResetButtonFlag[ 2 ], "RelayResetButton3", Input, "" );
|
||||||
|
// pantograph presets
|
||||||
|
{
|
||||||
|
auto &presets { PantsPreset.first };
|
||||||
|
extract_value( presets, "PantographPresets", Input, "0|1|3|2" );
|
||||||
|
presets.erase(
|
||||||
|
std::remove( std::begin( presets ), std::end( presets ), '|' ),
|
||||||
|
std::end( presets ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMoverParameters::LoadFIZ_MotorParamTable( std::string const &Input ) {
|
void TMoverParameters::LoadFIZ_MotorParamTable( std::string const &Input ) {
|
||||||
|
|||||||
287
Train.cpp
287
Train.cpp
@@ -31,7 +31,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "dictionary.h"
|
|
||||||
/*
|
/*
|
||||||
namespace input {
|
namespace input {
|
||||||
|
|
||||||
@@ -72,6 +71,38 @@ control_mapper::contains( std::string const Control ) const {
|
|||||||
return ( m_names.find( Control ) != m_names.end() );
|
return ( m_names.find( Control ) != m_names.end() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TTrain::screen_entry::deserialize( cParser &Input ) {
|
||||||
|
|
||||||
|
while( true == deserialize_mapping( Input ) ) {
|
||||||
|
; // all work done by while()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TTrain::screen_entry::deserialize_mapping( cParser &Input ) {
|
||||||
|
// token can be a key or block end
|
||||||
|
auto const key { Input.getToken<std::string>( true, "\n\r\t ,;[]" ) };
|
||||||
|
|
||||||
|
if( ( true == key.empty() ) || ( key == "}" ) ) { return false; }
|
||||||
|
|
||||||
|
if( key == "{" ) {
|
||||||
|
script = Input.getToken<std::string>();
|
||||||
|
}
|
||||||
|
else if( key == "target:" ) {
|
||||||
|
target = Input.getToken<std::string>();
|
||||||
|
}
|
||||||
|
else if( key == "parameters:" ) {
|
||||||
|
parameters = dictionary_source( Input.getToken<std::string>() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// HACK: we expect this to be true only if the screen entry doesn't start with a { which means legacy configuration format
|
||||||
|
target = key;
|
||||||
|
script = Input.getToken<std::string>();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void TCab::Load(cParser &Parser)
|
void TCab::Load(cParser &Parser)
|
||||||
{
|
{
|
||||||
// NOTE: clearing control tables here is bit of a crutch, imposed by current scheme of loading compartments anew on each cab change
|
// NOTE: clearing control tables here is bit of a crutch, imposed by current scheme of loading compartments anew on each cab change
|
||||||
@@ -537,12 +568,12 @@ bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
dictionary_source *TTrain::GetTrainState() {
|
dictionary_source *TTrain::GetTrainState( dictionary_source const &Extraparameters ) {
|
||||||
|
|
||||||
if( ( mvOccupied == nullptr )
|
if( ( mvOccupied == nullptr )
|
||||||
|| ( mvControlled == nullptr ) ) { return nullptr; }
|
|| ( mvControlled == nullptr ) ) { return nullptr; }
|
||||||
|
|
||||||
auto *dict { new dictionary_source };
|
auto *dict { new dictionary_source( Extraparameters ) };
|
||||||
if( dict == nullptr ) { return nullptr; }
|
if( dict == nullptr ) { return nullptr; }
|
||||||
|
|
||||||
dict->insert( "name", DynamicObject->asName );
|
dict->insert( "name", DynamicObject->asName );
|
||||||
@@ -612,6 +643,7 @@ dictionary_source *TTrain::GetTrainState() {
|
|||||||
dict->insert( "distance_counter", m_distancecounter );
|
dict->insert( "distance_counter", m_distancecounter );
|
||||||
dict->insert( "pantpress", std::abs( mvPantographUnit->PantPress ) );
|
dict->insert( "pantpress", std::abs( mvPantographUnit->PantPress ) );
|
||||||
dict->insert( "universal3", InstrumentLightActive );
|
dict->insert( "universal3", InstrumentLightActive );
|
||||||
|
dict->insert( "radio", mvOccupied->Radio );
|
||||||
dict->insert( "radio_channel", RadioChannel() );
|
dict->insert( "radio_channel", RadioChannel() );
|
||||||
dict->insert( "radio_volume", Global.RadioVolume );
|
dict->insert( "radio_volume", Global.RadioVolume );
|
||||||
dict->insert( "door_lock", mvOccupied->Doors.lock_enabled );
|
dict->insert( "door_lock", mvOccupied->Doors.lock_enabled );
|
||||||
@@ -621,6 +653,7 @@ dictionary_source *TTrain::GetTrainState() {
|
|||||||
dict->insert( "tractionforce", std::abs( mvOccupied->Ft ) );
|
dict->insert( "tractionforce", std::abs( mvOccupied->Ft ) );
|
||||||
dict->insert( "slipping_wheels", mvOccupied->SlippingWheels );
|
dict->insert( "slipping_wheels", mvOccupied->SlippingWheels );
|
||||||
dict->insert( "sanding", mvOccupied->SandDose );
|
dict->insert( "sanding", mvOccupied->SandDose );
|
||||||
|
dict->insert( "odometer", mvOccupied->DistCounter );
|
||||||
// electric current data
|
// electric current data
|
||||||
dict->insert( "traction_voltage", std::abs( mvPantographUnit->PantographVoltage ) );
|
dict->insert( "traction_voltage", std::abs( mvPantographUnit->PantographVoltage ) );
|
||||||
dict->insert( "voltage", std::abs( mvControlled->EngineVoltage ) );
|
dict->insert( "voltage", std::abs( mvControlled->EngineVoltage ) );
|
||||||
@@ -1122,18 +1155,30 @@ void TTrain::OnCommand_tempomattoggle( TTrain *Train, command_data const &Comman
|
|||||||
if( Train->ggScndCtrlButton.type() == TGaugeType::push ) {
|
if( Train->ggScndCtrlButton.type() == TGaugeType::push ) {
|
||||||
// impulse switch
|
// impulse switch
|
||||||
if( Command.action == GLFW_RELEASE ) {
|
if( Command.action == GLFW_RELEASE ) {
|
||||||
// just move the button back to default position
|
// just move the button(s) back to default position
|
||||||
// visual feedback
|
// visual feedback
|
||||||
Train->ggScndCtrlButton.UpdateValue( 0.0, Train->dsbSwitch );
|
Train->ggScndCtrlButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
|
Train->ggScndCtrlOffButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// glfw_press
|
// glfw_press
|
||||||
if( Train->mvControlled->ScndCtrlPos == 0 ) {
|
if( Train->mvControlled->ScndCtrlPos == 0 ) {
|
||||||
// turn on if needed
|
// turn on if it's not active
|
||||||
Train->mvControlled->IncScndCtrl( 1 );
|
Train->mvControlled->IncScndCtrl( 1 );
|
||||||
|
// visual feedback
|
||||||
|
Train->ggScndCtrlButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// otherwise turn off
|
||||||
|
Train->mvControlled->DecScndCtrl( 2 );
|
||||||
|
// visual feedback
|
||||||
|
if( Train->m_controlmapper.contains( "tempomatoff_sw:" ) ) {
|
||||||
|
Train->ggScndCtrlOffButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Train->ggScndCtrlButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// visual feedback
|
|
||||||
Train->ggScndCtrlButton.UpdateValue( 1.0, Train->dsbSwitch );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// two-state switch
|
// two-state switch
|
||||||
@@ -2194,7 +2239,7 @@ void TTrain::OnCommand_batterydisable( TTrain *Train, command_data const &Comman
|
|||||||
void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
||||||
if( Train->ggPantSelectButton.SubModel ) { return; }
|
if( Train->m_controlmapper.contains( "pantselect_sw:" ) ) { return; }
|
||||||
|
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||||
@@ -2226,7 +2271,7 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
|
|||||||
void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
||||||
if( Train->ggPantSelectButton.SubModel ) { return; }
|
if( Train->m_controlmapper.contains( "pantselect_sw:" ) ) { return; }
|
||||||
|
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||||
@@ -2258,7 +2303,7 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
|
|||||||
void TTrain::OnCommand_pantographraisefront( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_pantographraisefront( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
||||||
if( Train->ggPantSelectButton.SubModel ) { return; }
|
if( Train->m_controlmapper.contains( "pantselect_sw:" ) ) { return; }
|
||||||
// prevent operation without submodel outside of engine compartment
|
// prevent operation without submodel outside of engine compartment
|
||||||
if( ( Train->iCabn != 0 )
|
if( ( Train->iCabn != 0 )
|
||||||
&& ( false == Train->m_controlmapper.contains( "pantfront_sw:" ) ) ) { return; }
|
&& ( false == Train->m_controlmapper.contains( "pantfront_sw:" ) ) ) { return; }
|
||||||
@@ -2285,7 +2330,7 @@ void TTrain::OnCommand_pantographraisefront( TTrain *Train, command_data const &
|
|||||||
void TTrain::OnCommand_pantographraiserear( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_pantographraiserear( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
||||||
if( Train->ggPantSelectButton.SubModel ) { return; }
|
if( Train->m_controlmapper.contains( "pantselect_sw:" ) ) { return; }
|
||||||
// prevent operation without submodel outside of engine compartment
|
// prevent operation without submodel outside of engine compartment
|
||||||
if( ( Train->iCabn != 0 )
|
if( ( Train->iCabn != 0 )
|
||||||
&& ( false == Train->m_controlmapper.contains( "pantrear_sw:" ) ) ) { return; }
|
&& ( false == Train->m_controlmapper.contains( "pantrear_sw:" ) ) ) { return; }
|
||||||
@@ -2312,7 +2357,7 @@ void TTrain::OnCommand_pantographraiserear( TTrain *Train, command_data const &C
|
|||||||
void TTrain::OnCommand_pantographlowerfront( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_pantographlowerfront( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
||||||
if( Train->ggPantSelectButton.SubModel ) { return; }
|
if( Train->m_controlmapper.contains( "pantselect_sw:" ) ) { return; }
|
||||||
// prevent operation without submodel outside of engine compartment
|
// prevent operation without submodel outside of engine compartment
|
||||||
if( ( Train->iCabn != 0 )
|
if( ( Train->iCabn != 0 )
|
||||||
&& ( false == Train->m_controlmapper.contains(
|
&& ( false == Train->m_controlmapper.contains(
|
||||||
@@ -2344,7 +2389,8 @@ void TTrain::OnCommand_pantographlowerfront( TTrain *Train, command_data const &
|
|||||||
void TTrain::OnCommand_pantographlowerrear( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_pantographlowerrear( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
// HACK: presence of pantograph selector prevents manual operation of the individual valves
|
||||||
if( Train->ggPantSelectButton.SubModel ) { return; }
|
if( Train->m_controlmapper.contains( "pantselect_sw:" ) ) { return; }
|
||||||
|
|
||||||
if( ( Train->iCabn != 0 )
|
if( ( Train->iCabn != 0 )
|
||||||
&& ( false == Train->m_controlmapper.contains(
|
&& ( false == Train->m_controlmapper.contains(
|
||||||
Train->mvOccupied->PantSwitchType == "impulse" ?
|
Train->mvOccupied->PantSwitchType == "impulse" ?
|
||||||
@@ -2404,7 +2450,7 @@ void TTrain::OnCommand_pantographselectnext( TTrain *Train, command_data const &
|
|||||||
|
|
||||||
if( Command.action != GLFW_PRESS ) { return; }
|
if( Command.action != GLFW_PRESS ) { return; }
|
||||||
|
|
||||||
if( Train->ggPantSelectButton.SubModel == nullptr ) { return; }
|
if( false == Train->m_controlmapper.contains( "pantselect_sw:" ) ) { return; }
|
||||||
|
|
||||||
Train->change_pantograph_selection( 1 );
|
Train->change_pantograph_selection( 1 );
|
||||||
}
|
}
|
||||||
@@ -2413,7 +2459,7 @@ void TTrain::OnCommand_pantographselectprevious( TTrain *Train, command_data con
|
|||||||
|
|
||||||
if( Command.action != GLFW_PRESS ) { return; }
|
if( Command.action != GLFW_PRESS ) { return; }
|
||||||
|
|
||||||
if( Train->ggPantSelectButton.SubModel == nullptr ) { return; }
|
if( false == Train->m_controlmapper.contains( "pantselect_sw:" ) ) { return; }
|
||||||
|
|
||||||
Train->change_pantograph_selection( -1 );
|
Train->change_pantograph_selection( -1 );
|
||||||
}
|
}
|
||||||
@@ -2508,19 +2554,19 @@ void TTrain::OnCommand_pantographlowerselected( TTrain *Train, command_data cons
|
|||||||
|
|
||||||
void TTrain::change_pantograph_selection( int const Change ) {
|
void TTrain::change_pantograph_selection( int const Change ) {
|
||||||
|
|
||||||
auto const initialstate { m_pantselection };
|
auto const &presets { mvOccupied->PantsPreset.first };
|
||||||
|
auto &selection { mvOccupied->PantsPreset.second[ cab_to_end() ] };
|
||||||
|
auto const initialstate { selection };
|
||||||
|
selection = clamp<int>( selection + Change, 0, std::max<int>( presets.size() - 1, 0 ) );
|
||||||
|
|
||||||
m_pantselection = clamp( m_pantselection + Change, 0, 3 );
|
if( selection == initialstate ) { return; } // no change, nothing to do
|
||||||
// visual feedback
|
|
||||||
ggPantSelectButton.UpdateValue( m_pantselection );
|
|
||||||
|
|
||||||
if( m_pantselection == initialstate ) { return; } // no change, nothing to do
|
|
||||||
|
|
||||||
// configure pantograph valves matching the new state
|
// configure pantograph valves matching the new state
|
||||||
|
auto const preset { presets[ selection ] - '0' };
|
||||||
auto const swapends { cab_to_end() != end::front };
|
auto const swapends { cab_to_end() != end::front };
|
||||||
// check desired states for both pantographs; value: whether the pantograph should be raised
|
// check desired states for both pantographs; value: whether the pantograph should be raised
|
||||||
auto const frontstate{ ( m_pantselection == 2 ) || ( m_pantselection == ( swapends ? 1 : 3 ) ) };
|
auto const frontstate { preset & ( swapends ? 1 : 2 ) };
|
||||||
auto const rearstate{ ( m_pantselection == 2 ) || ( m_pantselection == ( swapends ? 3 : 1 ) ) };
|
auto const rearstate { preset & ( swapends ? 2 : 1 ) };
|
||||||
// potentially adjust pantograph valves
|
// potentially adjust pantograph valves
|
||||||
mvOccupied->OperatePantographValve( end::front, ( frontstate ? operation_t::enable : operation_t::disable ) );
|
mvOccupied->OperatePantographValve( end::front, ( frontstate ? operation_t::enable : operation_t::disable ) );
|
||||||
mvOccupied->OperatePantographValve( end::rear, ( rearstate ? operation_t::enable : operation_t::disable ) );
|
mvOccupied->OperatePantographValve( end::rear, ( rearstate ? operation_t::enable : operation_t::disable ) );
|
||||||
@@ -5503,9 +5549,27 @@ void TTrain::OnCommand_doorcloseall( TTrain *Train, command_data const &Command
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TTrain::OnCommand_doorsteptoggle( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_doorsteptoggle( TTrain *Train, command_data const &Command ) {
|
||||||
|
// TODO: move logic/visualization code to the gauge, on_command() should return hint whether it should invoke a reaction
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
Train->mvOccupied->PermitDoorStep( false == Train->mvOccupied->Doors.step_enabled );
|
// effect
|
||||||
|
if( false == Train->ggDoorStepButton.is_delayed() ) {
|
||||||
|
Train->mvOccupied->PermitDoorStep( false == Train->mvOccupied->Doors.step_enabled );
|
||||||
|
}
|
||||||
|
// visual feedback
|
||||||
|
auto const isactive { (
|
||||||
|
Train->ggDoorStepButton.is_push() // always press push button
|
||||||
|
|| Train->mvOccupied->Doors.step_enabled ) }; // for toggle buttons indicate item state
|
||||||
|
Train->ggDoorStepButton.UpdateValue( isactive ? 1 : 0 );
|
||||||
|
}
|
||||||
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
|
// effect
|
||||||
|
if( Train->ggDoorStepButton.is_delayed() ) {
|
||||||
|
Train->mvOccupied->PermitDoorStep( false == Train->mvOccupied->Doors.step_enabled );
|
||||||
|
}
|
||||||
|
// visual feedback
|
||||||
|
if( Train->ggDoorStepButton.is_push() ) {
|
||||||
|
Train->ggDoorStepButton.UpdateValue( 0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6964,6 +7028,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
ggScndCtrl.Update();
|
ggScndCtrl.Update();
|
||||||
}
|
}
|
||||||
ggScndCtrlButton.Update( lowvoltagepower );
|
ggScndCtrlButton.Update( lowvoltagepower );
|
||||||
|
ggScndCtrlOffButton.Update( lowvoltagepower );
|
||||||
ggDistanceCounterButton.Update();
|
ggDistanceCounterButton.Update();
|
||||||
if (ggDirKey.SubModel) {
|
if (ggDirKey.SubModel) {
|
||||||
if (mvControlled->TrainType != dt_EZT)
|
if (mvControlled->TrainType != dt_EZT)
|
||||||
@@ -7047,16 +7112,17 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
// NBMX wrzesien 2003 - drzwi
|
// NBMX wrzesien 2003 - drzwi
|
||||||
ggDoorLeftPermitButton.Update( lowvoltagepower );
|
ggDoorLeftPermitButton.Update( lowvoltagepower );
|
||||||
ggDoorRightPermitButton.Update( lowvoltagepower );
|
ggDoorRightPermitButton.Update( lowvoltagepower );
|
||||||
ggDoorPermitPresetButton.Update();
|
ggDoorPermitPresetButton.Update( lowvoltagepower );
|
||||||
ggDoorLeftButton.Update();
|
ggDoorLeftButton.Update( lowvoltagepower );
|
||||||
ggDoorRightButton.Update();
|
ggDoorRightButton.Update( lowvoltagepower );
|
||||||
ggDoorLeftOnButton.Update();
|
ggDoorLeftOnButton.Update( lowvoltagepower );
|
||||||
ggDoorRightOnButton.Update();
|
ggDoorRightOnButton.Update( lowvoltagepower );
|
||||||
ggDoorLeftOffButton.Update();
|
ggDoorLeftOffButton.Update( lowvoltagepower );
|
||||||
ggDoorRightOffButton.Update();
|
ggDoorRightOffButton.Update( lowvoltagepower );
|
||||||
ggDoorAllOnButton.Update();
|
ggDoorAllOnButton.Update( lowvoltagepower );
|
||||||
ggDoorAllOffButton.Update( lowvoltagepower );
|
ggDoorAllOffButton.Update( lowvoltagepower );
|
||||||
ggDoorSignallingButton.Update();
|
ggDoorSignallingButton.Update( lowvoltagepower );
|
||||||
|
ggDoorStepButton.Update( lowvoltagepower );
|
||||||
// NBMX dzwignia sprezarki
|
// NBMX dzwignia sprezarki
|
||||||
ggCompressorButton.Update();
|
ggCompressorButton.Update();
|
||||||
ggCompressorLocalButton.Update();
|
ggCompressorLocalButton.Update();
|
||||||
@@ -7125,7 +7191,6 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
ggPantAllDownButton.Update();
|
ggPantAllDownButton.Update();
|
||||||
ggPantSelectedDownButton.Update();
|
ggPantSelectedDownButton.Update();
|
||||||
ggPantSelectedButton.Update();
|
ggPantSelectedButton.Update();
|
||||||
ggPantSelectButton.Update();
|
|
||||||
ggPantCompressorButton.Update();
|
ggPantCompressorButton.Update();
|
||||||
ggPantCompressorValve.Update();
|
ggPantCompressorValve.Update();
|
||||||
|
|
||||||
@@ -7237,13 +7302,13 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
&& ( fScreenTimer > std::max( fScreenUpdateRate, Global.PythonScreenUpdateRate ) * 0.001f )
|
&& ( fScreenTimer > std::max( fScreenUpdateRate, Global.PythonScreenUpdateRate ) * 0.001f )
|
||||||
&& ( false == FreeFlyModeFlag ) ) { // don't bother if we're outside
|
&& ( false == FreeFlyModeFlag ) ) { // don't bother if we're outside
|
||||||
fScreenTimer = 0.f;
|
fScreenTimer = 0.f;
|
||||||
for( auto const &screen : m_screens ) {
|
for( auto &screen : m_screens ) {
|
||||||
auto state_dict = GetTrainState();
|
auto *state_dict = GetTrainState( screen.parameters );
|
||||||
/*
|
/*
|
||||||
state_dict->insert("touches", *screen.touch_list);
|
state_dict->insert("touches", *screen.touch_list);
|
||||||
screen.touch_list->clear();
|
screen.touch_list->clear();
|
||||||
*/
|
*/
|
||||||
Application.request({ screen.rendererpath, state_dict, screen.rt } );
|
Application.request( { screen.script, state_dict, screen.rt } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// sounds
|
// sounds
|
||||||
@@ -8038,60 +8103,62 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
|||||||
// TODO: add "pydestination:"
|
// TODO: add "pydestination:"
|
||||||
else if (token == "pyscreen:")
|
else if (token == "pyscreen:")
|
||||||
{
|
{
|
||||||
std::string submodelname, renderername;
|
screen_entry screen;
|
||||||
parser.getTokens( 2 );
|
screen.deserialize(parser);
|
||||||
parser
|
if ((false == screen.script.empty()) && (substr_path(screen.script).empty()))
|
||||||
>> submodelname
|
{
|
||||||
>> renderername;
|
screen.script = DynamicObject->asBaseDir + screen.script;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string rendererpath {
|
opengl_texture *tex = nullptr;
|
||||||
substr_path(renderername).empty() ? // supply vehicle folder as path if none is provided
|
|
||||||
DynamicObject->asBaseDir + renderername :
|
|
||||||
renderername };
|
|
||||||
|
|
||||||
opengl_texture *tex = nullptr;
|
|
||||||
TSubModel *submodel = nullptr;
|
TSubModel *submodel = nullptr;
|
||||||
if (submodelname != "none") {
|
if (screen.target != "none")
|
||||||
submodel = (
|
{
|
||||||
DynamicObject->mdKabina ? DynamicObject->mdKabina->GetFromName( submodelname ) :
|
submodel = (DynamicObject->mdKabina ?
|
||||||
DynamicObject->mdLowPolyInt ? DynamicObject->mdLowPolyInt->GetFromName( submodelname ) :
|
DynamicObject->mdKabina->GetFromName(screen.target) :
|
||||||
nullptr );
|
DynamicObject->mdLowPolyInt ?
|
||||||
if( submodel == nullptr ) {
|
DynamicObject->mdLowPolyInt->GetFromName(screen.target) :
|
||||||
WriteLog( "Python Screen: submodel " + submodelname + " not found - Ignoring screen" );
|
nullptr);
|
||||||
continue;
|
if (submodel == nullptr)
|
||||||
}
|
{
|
||||||
auto const material { submodel->GetMaterial() };
|
WriteLog("Python Screen: submodel " + screen.target +
|
||||||
if( material <= 0 ) {
|
" not found - Ignoring screen");
|
||||||
// sub model nie posiada tekstury lub tekstura wymienna - nie obslugiwana
|
continue;
|
||||||
WriteLog( "Python Screen: invalid texture id " + std::to_string( material ) + " - Ignoring screen" );
|
}
|
||||||
continue;
|
auto const material{submodel->GetMaterial()};
|
||||||
}
|
if (material <= 0)
|
||||||
|
{
|
||||||
|
// sub model nie posiada tekstury lub tekstura wymienna - nie obslugiwana
|
||||||
|
WriteLog("Python Screen: invalid texture id " + std::to_string(material) +
|
||||||
|
" - Ignoring screen");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
tex = &GfxRenderer->Texture(GfxRenderer->Material(material).textures[0]);
|
tex = &GfxRenderer->Texture(GfxRenderer->Material(material).textures[0]);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
// TODO: fix leak
|
{
|
||||||
tex = new opengl_texture();
|
// TODO: fix leak
|
||||||
tex->make_stub();
|
tex = new opengl_texture();
|
||||||
}
|
tex->make_stub();
|
||||||
|
}
|
||||||
|
|
||||||
tex->create( true ); // make the surface static so it doesn't get destroyed by garbage collector if the user spends long time outside cab
|
tex->create(true); // make the surface static so it doesn't get destroyed by garbage
|
||||||
// TBD, TODO: keep texture handles around, so we can undo the static switch when the user changes cabs?
|
// collector if the user spends long time outside cab
|
||||||
|
// TBD, TODO: keep texture handles around, so we can undo the static switch when the
|
||||||
|
// user changes cabs?
|
||||||
|
auto rt = std::make_shared<python_rt>();
|
||||||
|
rt->shared_tex = tex->id;
|
||||||
|
|
||||||
auto touch_list = std::make_shared<std::vector<glm::vec2>>();
|
|
||||||
auto rt = std::make_shared<python_rt>();
|
|
||||||
rt->shared_tex = tex->id;
|
|
||||||
/*
|
|
||||||
if (submodel)
|
|
||||||
submodel->screen_touch_list = touch_list;
|
|
||||||
*/
|
|
||||||
// record renderer and material binding for future update requests
|
// record renderer and material binding for future update requests
|
||||||
m_screens.emplace_back();
|
m_screens.emplace_back(screen);
|
||||||
m_screens.back().rendererpath = rendererpath;
|
|
||||||
m_screens.back().rt = rt;
|
m_screens.back().rt = rt;
|
||||||
/*
|
/*
|
||||||
m_screens.back().touch_list = touch_list;
|
m_screens.back().touch_list = std::make_shared<std::vector<glm::vec2>>();
|
||||||
|
if (submodel) // guaranteed at this point
|
||||||
|
submodel->screen_touch_list = m_screens.back().touch_list;
|
||||||
|
*/
|
||||||
|
/*
|
||||||
if (Global.python_displaywindows)
|
if (Global.python_displaywindows)
|
||||||
m_screens.back().viewer = std::make_unique<python_screen_viewer>(rt, touch_list, rendererpath);
|
m_screens.back().viewer = std::make_unique<python_screen_viewer>(rt, touch_list, rendererpath);
|
||||||
*/
|
*/
|
||||||
@@ -8280,8 +8347,14 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
|||||||
target_train->Occupied()->LimPipePress = target_train->Occupied()->PipePress;
|
target_train->Occupied()->LimPipePress = target_train->Occupied()->PipePress;
|
||||||
target_train->Occupied()->CabActivisation( true ); // załączenie rozrządu (wirtualne kabiny)
|
target_train->Occupied()->CabActivisation( true ); // załączenie rozrządu (wirtualne kabiny)
|
||||||
target_train->Dynamic()->MechInside = true;
|
target_train->Dynamic()->MechInside = true;
|
||||||
target_train->Dynamic()->Controller = ( target_train->Dynamic()->Mechanik ? !target_train->Dynamic()->Mechanik->AIControllFlag : Humandriver );
|
if( target_train->Dynamic()->Mechanik ) {
|
||||||
} else {
|
target_train->Dynamic()->Controller = target_train->Dynamic()->Mechanik->AIControllFlag;
|
||||||
|
target_train->Dynamic()->Mechanik->DirectionChange();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
target_train->Dynamic()->Controller = Humandriver;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
target_train->Dynamic()->bDisplayCab = false;
|
target_train->Dynamic()->bDisplayCab = false;
|
||||||
target_train->Dynamic()->ABuSetModelShake( {} );
|
target_train->Dynamic()->ABuSetModelShake( {} );
|
||||||
}
|
}
|
||||||
@@ -8327,7 +8400,13 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
|||||||
Occupied()->LimPipePress = Occupied()->PipePress;
|
Occupied()->LimPipePress = Occupied()->PipePress;
|
||||||
Occupied()->CabActivisation( true ); // załączenie rozrządu (wirtualne kabiny)
|
Occupied()->CabActivisation( true ); // załączenie rozrządu (wirtualne kabiny)
|
||||||
Dynamic()->MechInside = true;
|
Dynamic()->MechInside = true;
|
||||||
Dynamic()->Controller = ( Dynamic()->Mechanik ? Dynamic()->Mechanik->AIControllFlag : Humandriver );
|
if( Dynamic()->Mechanik ) {
|
||||||
|
Dynamic()->Controller = Dynamic()->Mechanik->AIControllFlag;
|
||||||
|
Dynamic()->Mechanik->DirectionChange();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Dynamic()->Controller = Humandriver;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Dynamic()->bDisplayCab = false;
|
Dynamic()->bDisplayCab = false;
|
||||||
Dynamic()->ABuSetModelShake( {} );
|
Dynamic()->ABuSetModelShake( {} );
|
||||||
@@ -8429,6 +8508,7 @@ void TTrain::clear_cab_controls()
|
|||||||
ggMainCtrlAct.Clear();
|
ggMainCtrlAct.Clear();
|
||||||
ggScndCtrl.Clear();
|
ggScndCtrl.Clear();
|
||||||
ggScndCtrlButton.Clear();
|
ggScndCtrlButton.Clear();
|
||||||
|
ggScndCtrlOffButton.Clear();
|
||||||
ggDistanceCounterButton.Clear();
|
ggDistanceCounterButton.Clear();
|
||||||
ggDirKey.Clear();
|
ggDirKey.Clear();
|
||||||
ggDirForwardButton.Clear();
|
ggDirForwardButton.Clear();
|
||||||
@@ -8512,6 +8592,7 @@ void TTrain::clear_cab_controls()
|
|||||||
ggTrainHeatingButton.Clear();
|
ggTrainHeatingButton.Clear();
|
||||||
ggSignallingButton.Clear();
|
ggSignallingButton.Clear();
|
||||||
ggDoorSignallingButton.Clear();
|
ggDoorSignallingButton.Clear();
|
||||||
|
ggDoorStepButton.Clear();
|
||||||
ggDepartureSignalButton.Clear();
|
ggDepartureSignalButton.Clear();
|
||||||
ggCompressorButton.Clear();
|
ggCompressorButton.Clear();
|
||||||
ggCompressorLocalButton.Clear();
|
ggCompressorLocalButton.Clear();
|
||||||
@@ -8528,7 +8609,6 @@ void TTrain::clear_cab_controls()
|
|||||||
ggPantAllDownButton.Clear();
|
ggPantAllDownButton.Clear();
|
||||||
ggPantSelectedButton.Clear();
|
ggPantSelectedButton.Clear();
|
||||||
ggPantSelectedDownButton.Clear();
|
ggPantSelectedDownButton.Clear();
|
||||||
ggPantSelectButton.Clear();
|
|
||||||
ggPantCompressorButton.Clear();
|
ggPantCompressorButton.Clear();
|
||||||
ggPantCompressorValve.Clear();
|
ggPantCompressorValve.Clear();
|
||||||
ggI1B.Clear();
|
ggI1B.Clear();
|
||||||
@@ -8705,13 +8785,6 @@ void TTrain::set_cab_controls( int const Cab ) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// front/end pantograph selection is relative to occupied cab
|
// front/end pantograph selection is relative to occupied cab
|
||||||
m_pantselection = (
|
|
||||||
m_pantselection == 1 ? ( cab_to_end( Cab ) == cab_to_end() ? 1 : 3 ) :
|
|
||||||
m_pantselection == 3 ? ( cab_to_end( Cab ) == cab_to_end() ? 3 : 1 ) :
|
|
||||||
m_pantselection ); // other settings affect both pantographs
|
|
||||||
if( ggPantSelectButton.SubModel ) {
|
|
||||||
ggPantSelectButton.PutValue( m_pantselection );
|
|
||||||
}
|
|
||||||
if( ggPantSelectedButton.type() == TGaugeType::toggle ) {
|
if( ggPantSelectedButton.type() == TGaugeType::toggle ) {
|
||||||
ggPantSelectedButton.PutValue(
|
ggPantSelectedButton.PutValue(
|
||||||
( mvPantographUnit->PantsValve.is_enabled ?
|
( mvPantographUnit->PantsValve.is_enabled ?
|
||||||
@@ -8825,10 +8898,10 @@ void TTrain::set_cab_controls( int const Cab ) {
|
|||||||
1.f :
|
1.f :
|
||||||
0.f ) );
|
0.f ) );
|
||||||
// doors permits
|
// doors permits
|
||||||
if( ggDoorLeftPermitButton.type() != TGaugeType::push ) {
|
if( false == ggDoorLeftPermitButton.is_push() ) {
|
||||||
ggDoorLeftPermitButton.PutValue( mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::left : side::right ) ].open_permit ? 1.f : 0.f );
|
ggDoorLeftPermitButton.PutValue( mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::left : side::right ) ].open_permit ? 1.f : 0.f );
|
||||||
}
|
}
|
||||||
if( ggDoorRightPermitButton.type() != TGaugeType::push ) {
|
if( false == ggDoorRightPermitButton.is_push() ) {
|
||||||
ggDoorRightPermitButton.PutValue( mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::right : side::left ) ].open_permit ? 1.f : 0.f );
|
ggDoorRightPermitButton.PutValue( mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::right : side::left ) ].open_permit ? 1.f : 0.f );
|
||||||
}
|
}
|
||||||
ggDoorPermitPresetButton.PutValue( mvOccupied->Doors.permit_preset );
|
ggDoorPermitPresetButton.PutValue( mvOccupied->Doors.permit_preset );
|
||||||
@@ -8840,8 +8913,15 @@ void TTrain::set_cab_controls( int const Cab ) {
|
|||||||
mvOccupied->Doors.lock_enabled ?
|
mvOccupied->Doors.lock_enabled ?
|
||||||
1.f :
|
1.f :
|
||||||
0.f );
|
0.f );
|
||||||
|
// door step
|
||||||
|
if( false == ggDoorStepButton.is_push() ) {
|
||||||
|
ggDoorStepButton.PutValue(
|
||||||
|
mvOccupied->Doors.step_enabled ?
|
||||||
|
1.f :
|
||||||
|
0.f );
|
||||||
|
}
|
||||||
// heating
|
// heating
|
||||||
if( ggTrainHeatingButton.type() != TGaugeType::push ) {
|
if( false == ggTrainHeatingButton.is_push() ) {
|
||||||
ggTrainHeatingButton.PutValue(
|
ggTrainHeatingButton.PutValue(
|
||||||
mvControlled->Heating ?
|
mvControlled->Heating ?
|
||||||
1.f :
|
1.f :
|
||||||
@@ -8946,7 +9026,7 @@ void TTrain::set_cab_controls( int const Cab ) {
|
|||||||
0.f );
|
0.f );
|
||||||
}
|
}
|
||||||
// tempomat
|
// tempomat
|
||||||
if( ggScndCtrlButton.type() != TGaugeType::push ) {
|
if( false == ggScndCtrlButton.is_push() ) {
|
||||||
ggScndCtrlButton.PutValue(
|
ggScndCtrlButton.PutValue(
|
||||||
( mvControlled->ScndCtrlPos > 0 ) ?
|
( mvControlled->ScndCtrlPos > 0 ) ?
|
||||||
1.f :
|
1.f :
|
||||||
@@ -9225,7 +9305,6 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
{ "pantalloff_sw:", ggPantAllDownButton },
|
{ "pantalloff_sw:", ggPantAllDownButton },
|
||||||
{ "pantselected_sw:", ggPantSelectedButton },
|
{ "pantselected_sw:", ggPantSelectedButton },
|
||||||
{ "pantselectedoff_sw:", ggPantSelectedDownButton },
|
{ "pantselectedoff_sw:", ggPantSelectedDownButton },
|
||||||
{ "pantselect_sw:", ggPantSelectButton },
|
|
||||||
{ "pantcompressor_sw:", ggPantCompressorButton },
|
{ "pantcompressor_sw:", ggPantCompressorButton },
|
||||||
{ "pantcompressorvalve_sw:", ggPantCompressorValve },
|
{ "pantcompressorvalve_sw:", ggPantCompressorValve },
|
||||||
{ "trainheating_sw:", ggTrainHeatingButton },
|
{ "trainheating_sw:", ggTrainHeatingButton },
|
||||||
@@ -9265,9 +9344,12 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: move viable gauges to the state driven array
|
// dedicated gauges with state-driven optional submodel
|
||||||
|
// TODO: move viable gauges here
|
||||||
|
// TODO: convert dedicated gauges to auto-allocated ones, replace dedicated references in command handlers to mapper lookups
|
||||||
std::unordered_map<std::string, std::tuple<TGauge &, bool const *> > const stategauges = {
|
std::unordered_map<std::string, std::tuple<TGauge &, bool const *> > const stategauges = {
|
||||||
{ "tempomat_sw:", { ggScndCtrlButton, &mvOccupied->SpeedCtrlUnit.IsActive } },
|
{ "tempomat_sw:", { ggScndCtrlButton, &mvOccupied->SpeedCtrlUnit.IsActive } },
|
||||||
|
{ "tempomatoff_sw:", { ggScndCtrlOffButton, &mvOccupied->SpeedCtrlUnit.IsActive } },
|
||||||
{ "speedinc_bt:", { ggSpeedControlIncreaseButton, &mvOccupied->SpeedCtrlUnit.IsActive } },
|
{ "speedinc_bt:", { ggSpeedControlIncreaseButton, &mvOccupied->SpeedCtrlUnit.IsActive } },
|
||||||
{ "speeddec_bt:", { ggSpeedControlDecreaseButton, &mvOccupied->SpeedCtrlUnit.IsActive } },
|
{ "speeddec_bt:", { ggSpeedControlDecreaseButton, &mvOccupied->SpeedCtrlUnit.IsActive } },
|
||||||
{ "speedctrlpowerinc_bt:", { ggSpeedControlPowerIncreaseButton, &mvOccupied->SpeedCtrlUnit.IsActive } },
|
{ "speedctrlpowerinc_bt:", { ggSpeedControlPowerIncreaseButton, &mvOccupied->SpeedCtrlUnit.IsActive } },
|
||||||
@@ -9285,7 +9367,8 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
{ "doorleftpermit_sw:", { ggDoorLeftPermitButton, &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::left : side::right ) ].open_permit } },
|
{ "doorleftpermit_sw:", { ggDoorLeftPermitButton, &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::left : side::right ) ].open_permit } },
|
||||||
{ "doorrightpermit_sw:", { ggDoorRightPermitButton, &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::right : side::left ) ].open_permit } },
|
{ "doorrightpermit_sw:", { ggDoorRightPermitButton, &mvOccupied->Doors.instances[ ( cab_to_end() == end::front ? side::right : side::left ) ].open_permit } },
|
||||||
{ "dooralloff_sw:", { ggDoorAllOffButton, &m_doors } },
|
{ "dooralloff_sw:", { ggDoorAllOffButton, &m_doors } },
|
||||||
{ "dirforward_bt:", { ggDirForwardButton, &m_dirforward } },
|
{ "doorstep_sw:", { ggDoorStepButton, &mvOccupied->Doors.step_enabled } },
|
||||||
|
{ "dirforward_bt:", { ggDirForwardButton, &m_dirforward } },
|
||||||
{ "dirneutral_bt:", { ggDirNeutralButton, &m_dirneutral } },
|
{ "dirneutral_bt:", { ggDirNeutralButton, &m_dirneutral } },
|
||||||
{ "dirbackward_bt:", { ggDirBackwardButton, &m_dirbackward } },
|
{ "dirbackward_bt:", { ggDirBackwardButton, &m_dirbackward } },
|
||||||
};
|
};
|
||||||
@@ -9302,7 +9385,6 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
// TODO: move viable dedicated gauges to the automatic array
|
// TODO: move viable dedicated gauges to the automatic array
|
||||||
std::unordered_map<std::string, bool *> const autoboolgauges = {
|
std::unordered_map<std::string, bool *> const autoboolgauges = {
|
||||||
{ "doormode_sw:", &mvOccupied->Doors.remote_only },
|
{ "doormode_sw:", &mvOccupied->Doors.remote_only },
|
||||||
{ "doorstep_sw:", &mvOccupied->Doors.step_enabled },
|
|
||||||
{ "coolingfans_sw:", &mvControlled->RVentForceOn },
|
{ "coolingfans_sw:", &mvControlled->RVentForceOn },
|
||||||
{ "pantfront_sw:", &mvPantographUnit->Pantographs[end::front].valve.is_enabled },
|
{ "pantfront_sw:", &mvPantographUnit->Pantographs[end::front].valve.is_enabled },
|
||||||
{ "pantrear_sw:", &mvPantographUnit->Pantographs[end::rear].valve.is_enabled },
|
{ "pantrear_sw:", &mvPantographUnit->Pantographs[end::rear].valve.is_enabled },
|
||||||
@@ -9326,6 +9408,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
// TODO: move viable dedicated gauges to the automatic array
|
// TODO: move viable dedicated gauges to the automatic array
|
||||||
std::unordered_map<std::string, int *> const autointgauges = {
|
std::unordered_map<std::string, int *> const autointgauges = {
|
||||||
{ "manualbrake:", &mvOccupied->ManualBrakePos },
|
{ "manualbrake:", &mvOccupied->ManualBrakePos },
|
||||||
|
{ "pantselect_sw:", &mvOccupied->PantsPreset.second[cab_to_end()] },
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
auto lookup = autointgauges.find( Label );
|
auto lookup = autointgauges.find( Label );
|
||||||
|
|||||||
32
Train.h
32
Train.h
@@ -17,6 +17,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "PyInt.h"
|
#include "PyInt.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
#include "dictionary.h"
|
||||||
|
|
||||||
#undef snprintf // pyint.h->python
|
#undef snprintf // pyint.h->python
|
||||||
|
|
||||||
@@ -113,15 +114,21 @@ class TTrain {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct screen_entry {
|
struct screen_entry {
|
||||||
std::string rendererpath;
|
|
||||||
|
std::string script;
|
||||||
|
std::string target;
|
||||||
std::shared_ptr<python_rt> rt;
|
std::shared_ptr<python_rt> rt;
|
||||||
/*
|
/*
|
||||||
std::unique_ptr<python_screen_viewer> viewer;
|
std::unique_ptr<python_screen_viewer> viewer;
|
||||||
std::shared_ptr<std::vector<glm::vec2>> touch_list;
|
std::shared_ptr<std::vector<glm::vec2>> touch_list;
|
||||||
*/
|
*/
|
||||||
|
dictionary_source parameters; // cached pre-processed optional per-screen parameters
|
||||||
|
|
||||||
|
void deserialize( cParser &Input );
|
||||||
|
bool deserialize_mapping( cParser &Input );
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<screen_entry> screen_map;
|
typedef std::vector<screen_entry> screenentry_sequence;
|
||||||
|
|
||||||
// constructors
|
// constructors
|
||||||
TTrain();
|
TTrain();
|
||||||
@@ -132,16 +139,23 @@ class TTrain {
|
|||||||
// McZapkie-010302
|
// McZapkie-010302
|
||||||
bool Init(TDynamicObject *NewDynamicObject, bool e3d = false);
|
bool Init(TDynamicObject *NewDynamicObject, bool e3d = false);
|
||||||
|
|
||||||
inline Math3D::vector3 GetDirection() { return DynamicObject->VectorFront(); };
|
inline
|
||||||
inline Math3D::vector3 GetUp() { return DynamicObject->VectorUp(); };
|
Math3D::vector3 GetDirection() const {
|
||||||
inline std::string GetLabel( TSubModel const *Control ) const { return m_controlmapper.find( Control ); }
|
return DynamicObject->VectorFront(); };
|
||||||
|
inline
|
||||||
|
Math3D::vector3 GetUp() const {
|
||||||
|
return DynamicObject->VectorUp(); };
|
||||||
|
inline
|
||||||
|
std::string GetLabel( TSubModel const *Control ) const {
|
||||||
|
return m_controlmapper.find( Control ); }
|
||||||
void UpdateCab();
|
void UpdateCab();
|
||||||
bool Update( double const Deltatime );
|
bool Update( double const Deltatime );
|
||||||
void add_distance( double const Distance );
|
void add_distance( double const Distance );
|
||||||
// McZapkie-310302: ladowanie parametrow z pliku
|
// McZapkie-310302: ladowanie parametrow z pliku
|
||||||
bool LoadMMediaFile(std::string const &asFileName);
|
bool LoadMMediaFile(std::string const &asFileName);
|
||||||
dictionary_source *GetTrainState();
|
dictionary_source *GetTrainState( dictionary_source const &Extraparameters );
|
||||||
state_t get_state() const;
|
state_t get_state() const;
|
||||||
|
// basic_table interface
|
||||||
inline
|
inline
|
||||||
std::string name() const {
|
std::string name() const {
|
||||||
return Dynamic()->name(); }
|
return Dynamic()->name(); }
|
||||||
@@ -464,6 +478,7 @@ public: // reszta może by?publiczna
|
|||||||
TGauge ggMainCtrlAct;
|
TGauge ggMainCtrlAct;
|
||||||
TGauge ggScndCtrl;
|
TGauge ggScndCtrl;
|
||||||
TGauge ggScndCtrlButton;
|
TGauge ggScndCtrlButton;
|
||||||
|
TGauge ggScndCtrlOffButton;
|
||||||
TGauge ggDirKey;
|
TGauge ggDirKey;
|
||||||
TGauge ggDirForwardButton;
|
TGauge ggDirForwardButton;
|
||||||
TGauge ggDirNeutralButton;
|
TGauge ggDirNeutralButton;
|
||||||
@@ -572,6 +587,7 @@ public: // reszta może by?publiczna
|
|||||||
TGauge ggDoorAllOnButton;
|
TGauge ggDoorAllOnButton;
|
||||||
TGauge ggDoorAllOffButton;
|
TGauge ggDoorAllOffButton;
|
||||||
TGauge ggDepartureSignalButton;
|
TGauge ggDepartureSignalButton;
|
||||||
|
TGauge ggDoorStepButton;
|
||||||
|
|
||||||
// Winger 160204 - obsluga pantografow - ZROBIC
|
// Winger 160204 - obsluga pantografow - ZROBIC
|
||||||
/*
|
/*
|
||||||
@@ -583,7 +599,6 @@ public: // reszta może by?publiczna
|
|||||||
TGauge ggPantAllDownButton;
|
TGauge ggPantAllDownButton;
|
||||||
TGauge ggPantSelectedButton;
|
TGauge ggPantSelectedButton;
|
||||||
TGauge ggPantSelectedDownButton;
|
TGauge ggPantSelectedDownButton;
|
||||||
TGauge ggPantSelectButton;
|
|
||||||
TGauge ggPantCompressorButton;
|
TGauge ggPantCompressorButton;
|
||||||
TGauge ggPantCompressorValve;
|
TGauge ggPantCompressorValve;
|
||||||
// Winger 020304 - wlacznik ogrzewania
|
// Winger 020304 - wlacznik ogrzewania
|
||||||
@@ -790,11 +805,10 @@ private:
|
|||||||
float fPPress, fNPress;
|
float fPPress, fNPress;
|
||||||
bool m_mastercontrollerinuse { false };
|
bool m_mastercontrollerinuse { false };
|
||||||
float m_mastercontrollerreturndelay { 0.f };
|
float m_mastercontrollerreturndelay { 0.f };
|
||||||
screen_map m_screens;
|
screenentry_sequence m_screens;
|
||||||
uint16_t vid { 0 }; // train network recipient id
|
uint16_t vid { 0 }; // train network recipient id
|
||||||
float m_distancecounter { -1.f }; // distance traveled since meter was activated or -1 if inactive
|
float m_distancecounter { -1.f }; // distance traveled since meter was activated or -1 if inactive
|
||||||
double m_brakehandlecp{ 0.0 };
|
double m_brakehandlecp{ 0.0 };
|
||||||
int m_pantselection{ 0 };
|
|
||||||
bool m_doors{ false }; // helper, true if any door is open
|
bool m_doors{ false }; // helper, true if any door is open
|
||||||
bool m_dirforward{ false }; // helper, true if direction set to forward
|
bool m_dirforward{ false }; // helper, true if direction set to forward
|
||||||
bool m_dirneutral{ false }; // helper, true if direction set to neutral
|
bool m_dirneutral{ false }; // helper, true if direction set to neutral
|
||||||
|
|||||||
@@ -335,7 +335,7 @@ void
|
|||||||
openal_renderer::update( double const Deltatime ) {
|
openal_renderer::update( double const Deltatime ) {
|
||||||
// update listener
|
// update listener
|
||||||
// gain
|
// gain
|
||||||
::alListenerf( AL_GAIN, clamp( Global.AudioVolume, 0.f, 2.f ) * ( Global.iPause == 0 ? 1.f : 0.15f ) );
|
::alListenerf( AL_GAIN, clamp( Global.AudioVolume, 0.f, 2.f ) * ( Global.iPause == 0 ? 1.f : Global.PausedVolume ) );
|
||||||
// orientation
|
// orientation
|
||||||
glm::dmat4 cameramatrix;
|
glm::dmat4 cameramatrix;
|
||||||
Global.pCamera.SetMatrix( cameramatrix );
|
Global.pCamera.SetMatrix( cameramatrix );
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ scenario_panel::render() {
|
|||||||
// hints
|
// hints
|
||||||
if( owner != nullptr ) {
|
if( owner != nullptr ) {
|
||||||
auto const hintheader{ locale::strings[ locale::string::driver_hint_header ] };
|
auto const hintheader{ locale::strings[ locale::string::driver_hint_header ] };
|
||||||
if( true == ImGui::CollapsingHeader( hintheader.c_str() ) ) {
|
if( true == ImGui::CollapsingHeader( hintheader.c_str(), ImGuiTreeNodeFlags_DefaultOpen ) ) {
|
||||||
for( auto const &hint : owner->m_hints ) {
|
for( auto const &hint : owner->m_hints ) {
|
||||||
auto const isdone { std::get<TController::hintpredicate>( hint )( std::get<float>( hint ) ) };
|
auto const isdone { std::get<TController::hintpredicate>( hint )( std::get<float>( hint ) ) };
|
||||||
auto const hintcolor{ (
|
auto const hintcolor{ (
|
||||||
@@ -1254,14 +1254,15 @@ debug_panel::update_section_eventqueue( std::vector<text_line> &Output ) {
|
|||||||
&& ( ( false == m_eventqueueactivevehicleonly )
|
&& ( ( false == m_eventqueueactivevehicleonly )
|
||||||
|| ( event->m_activator == m_input.vehicle ) ) ) {
|
|| ( event->m_activator == m_input.vehicle ) ) ) {
|
||||||
|
|
||||||
|
auto const label { event->m_name + ( event->m_activator ? " (by: " + event->m_activator->asName + ")" : "" ) };
|
||||||
|
|
||||||
if( ( false == searchfilter.empty() )
|
if( ( false == searchfilter.empty() )
|
||||||
&& ( event->m_name.find( searchfilter ) == std::string::npos ) ) {
|
&& ( label.find( searchfilter ) == std::string::npos ) ) {
|
||||||
event = event->m_next;
|
event = event->m_next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const delay { " " + to_string( std::max( 0.0, event->m_launchtime - time ), 1 ) };
|
auto const delay { " " + to_string( std::max( 0.0, event->m_launchtime - time ), 1 ) };
|
||||||
auto const label { event->m_name + ( event->m_activator ? " (by: " + event->m_activator->asName + ")" : "" ) };
|
|
||||||
textline =
|
textline =
|
||||||
delay.substr( delay.length() - 6 )
|
delay.substr( delay.length() - 6 )
|
||||||
+ " "
|
+ " "
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ class debug_panel : public ui_panel {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
debug_panel( std::string const &Name, bool const Isopen )
|
debug_panel( std::string const &Name, bool const Isopen )
|
||||||
: ui_panel( Name, Isopen ) {}
|
: ui_panel( Name, Isopen ) {
|
||||||
|
m_eventsearch.fill( 0 ); }
|
||||||
|
|
||||||
void update() override;
|
void update() override;
|
||||||
void render() override;
|
void render() override;
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ world_environment::update() {
|
|||||||
// twilight factor can be reset later down, so we do it here while it's still reflecting state of the sun
|
// twilight factor can be reset later down, so we do it here while it's still reflecting state of the sun
|
||||||
// turbidity varies from 2-3 during the day based on overcast, 3-4 after sunset to deal with sunlight bleeding too much into the sky from below horizon
|
// turbidity varies from 2-3 during the day based on overcast, 3-4 after sunset to deal with sunlight bleeding too much into the sky from below horizon
|
||||||
m_skydome.SetTurbidity(
|
m_skydome.SetTurbidity(
|
||||||
2.f
|
2.25f
|
||||||
+ clamp( Global.Overcast, 0.f, 1.f )
|
+ clamp( Global.Overcast, 0.f, 1.f )
|
||||||
+ interpolate( 0.f, 1.f, clamp( twilightfactor * 1.5f, 0.f, 1.f ) ) );
|
+ interpolate( 0.f, 1.f, clamp( twilightfactor * 1.5f, 0.f, 1.f ) ) );
|
||||||
m_skydome.SetOvercastFactor( Global.Overcast );
|
m_skydome.SetOvercastFactor( Global.Overcast );
|
||||||
@@ -173,8 +173,9 @@ world_environment::update() {
|
|||||||
|
|
||||||
// update the fog. setting it to match the average colour of the sky dome is cheap
|
// update the fog. setting it to match the average colour of the sky dome is cheap
|
||||||
// but quite effective way to make the distant items blend with background better
|
// but quite effective way to make the distant items blend with background better
|
||||||
// NOTE: base brightness calculation provides scaled up value, so we bring it back to 'real' one here
|
Global.FogColor =
|
||||||
Global.FogColor = m_skydome.GetAverageHorizonColor();
|
interpolate( m_skydome.GetAverageColor(), m_skydome.GetAverageHorizonColor(), 0.33f )
|
||||||
|
* clamp<float>( Global.fLuminance, 0.25f, 1.f );
|
||||||
|
|
||||||
// weather-related simulation factors
|
// weather-related simulation factors
|
||||||
Global.FrictionWeatherFactor = (
|
Global.FrictionWeatherFactor = (
|
||||||
|
|||||||
@@ -264,6 +264,10 @@ void CSkyDome::RebuildColors() {
|
|||||||
colorconverter.z = 1.0f - std::exp( -m_expfactor * colorconverter.z );
|
colorconverter.z = 1.0f - std::exp( -m_expfactor * colorconverter.z );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( colorconverter.z > 0.85f ) {
|
||||||
|
colorconverter.z = 0.85f + ( colorconverter.z - 0.85f ) * 0.35f;
|
||||||
|
}
|
||||||
|
|
||||||
colorconverter.y = clamp( colorconverter.y * 1.15f, 0.0f, 1.0f );
|
colorconverter.y = clamp( colorconverter.y * 1.15f, 0.0f, 1.0f );
|
||||||
// desaturate sky colour, based on overcast level
|
// desaturate sky colour, based on overcast level
|
||||||
if( colorconverter.y > 0.0f ) {
|
if( colorconverter.y > 0.0f ) {
|
||||||
@@ -310,14 +314,14 @@ void CSkyDome::RebuildColors() {
|
|||||||
// save
|
// save
|
||||||
m_colours[ i ] = color;
|
m_colours[ i ] = color;
|
||||||
averagecolor += color;
|
averagecolor += color;
|
||||||
if( ( m_vertices.size() - i ) <= ( m_tesselation * 2 ) ) {
|
if( ( m_vertices.size() - i ) <= ( m_tesselation * 3 + 3 ) ) {
|
||||||
// calculate horizon colour from the bottom band of tris
|
// calculate horizon colour from the bottom band of tris
|
||||||
averagehorizoncolor += color;
|
averagehorizoncolor += color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_averagecolour = glm::max( glm::vec3(), averagecolor / static_cast<float>( m_vertices.size() ) );
|
m_averagecolour = glm::max( glm::vec3(), averagecolor / static_cast<float>( m_vertices.size() ) );
|
||||||
m_averagehorizoncolour = glm::max( glm::vec3(), averagehorizoncolor / static_cast<float>( m_tesselation * 2 ) );
|
m_averagehorizoncolour = glm::max( glm::vec3(), averagehorizoncolor / static_cast<float>( m_tesselation * 3 + 3 ) );
|
||||||
|
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ ui_layer::init( GLFWwindow *Window ) {
|
|||||||
|
|
||||||
static ImWchar const glyphranges[] = {
|
static ImWchar const glyphranges[] = {
|
||||||
0x0020, 0x00FF, // ascii + extension
|
0x0020, 0x00FF, // ascii + extension
|
||||||
|
0x0100, 0x017F, // latin extended-a
|
||||||
0x2070, 0x2079, // superscript
|
0x2070, 0x2079, // superscript
|
||||||
0x2500, 0x256C, // box drawings
|
0x2500, 0x256C, // box drawings
|
||||||
0,
|
0,
|
||||||
|
|||||||
Reference in New Issue
Block a user