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

build 200824. emergency_brake getvalues event support, utf bom parsing fix, brake state vehicle debug panel enhancement, ai cab change logic fixes, ai door operation logic fixes, minor ai logic fixes, gfx renderer framerate calculation tweak, minor bug fixes

This commit is contained in:
tmj-fstate
2020-08-26 13:43:24 +02:00
parent 55687e975e
commit c4ef056102
17 changed files with 180 additions and 106 deletions

View File

@@ -189,11 +189,22 @@ void TCamera::Update()
// attached movement position update // attached movement position update
auto movement { Velocity * -2.0 }; auto movement { Velocity * -2.0 };
movement.y = -movement.y; movement.y = -movement.y;
auto const *owner { (
m_owner->Mechanik ?
m_owner->Mechanik :
m_owner->ctOwner ) };
if( ( owner )
&& ( owner->Occupied()->CabOccupied < 0 ) ) {
movement *= -1.f;
movement.y = -movement.y;
}
/*
if( ( m_owner->ctOwner ) if( ( m_owner->ctOwner )
&& ( m_owner->ctOwner->Vehicle()->DirectionGet() != m_owner->DirectionGet() ) ) { && ( m_owner->ctOwner->Vehicle()->DirectionGet() != m_owner->DirectionGet() ) ) {
movement *= -1.f; movement *= -1.f;
movement.y = -movement.y; movement.y = -movement.y;
} }
*/
movement.RotateY( Angle.y ); movement.RotateY( Angle.y );
m_owneroffset += movement * deltatime; m_owneroffset += movement * deltatime;

View File

@@ -76,7 +76,8 @@ enum class TCommandType
cm_ChangeDirection, cm_ChangeDirection,
cm_PassengerStopPoint, cm_PassengerStopPoint,
cm_OutsideStation, cm_OutsideStation,
cm_Shunt, // cm_Shunt, // unused?
cm_EmergencyBrake,
cm_Command // komenda pobierana z komórki cm_Command // komenda pobierana z komórki
}; };

View File

@@ -268,12 +268,18 @@ void TSpeedPos::CommandCheck()
fVelNext = -1; fVelNext = -1;
iFlags |= spOutsideStation; // W5 iFlags |= spOutsideStation; // W5
break; break;
case TCommandType::cm_EmergencyBrake:
fVelNext = -1;
break;
default: default:
// inna komenda w evencie skanowanym powoduje zatrzymanie i wysłanie tej komendy // inna komenda w evencie skanowanym powoduje zatrzymanie i wysłanie tej komendy
// nie manewrowa, nie przystanek, nie zatrzymać na SBL // nie manewrowa, nie przystanek, nie zatrzymać na SBL
iFlags &= ~(spShuntSemaphor | spPassengerStopPoint | spStopOnSBL); iFlags &= ~(spShuntSemaphor | spPassengerStopPoint | spStopOnSBL);
// jak nieznana komenda w komórce sygnałowej, to zatrzymujemy // jak nieznana komenda w komórce sygnałowej, to zatrzymujemy
fVelNext = 0.0; fVelNext = (
evEvent->is_command() ?
0.0 : // ask for a stop if we have a command for the vehicle
-1.0 ); // if we don't or it was already passed then don't be a bother
} }
}; };
@@ -339,7 +345,11 @@ std::string TSpeedPos::GetName() const
if( iFlags & spTrack ) // jeśli tor if( iFlags & spTrack ) // jeśli tor
return trTrack->name(); return trTrack->name();
else if( iFlags & spEvent ) // jeśli event else if( iFlags & spEvent ) // jeśli event
return evEvent->m_name; return
evEvent->m_name
+ " [" + to_string( static_cast<int>( evEvent->input_value( 1 ) ) )
+ ", " + to_string( static_cast<int>( evEvent->input_value( 2 ) ) )
+ "]";
else else
return ""; return "";
} }
@@ -998,7 +1008,6 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// w razie przełączenia na AI ma nie podciągać do W4, gdy użytkownik zatrzymał za daleko // w razie przełączenia na AI ma nie podciągać do W4, gdy użytkownik zatrzymał za daleko
iDrivigFlags &= ~moveStopCloser; iDrivigFlags &= ~moveStopCloser;
} }
if (TrainParams.UpdateMTable( simulation::Time, asNextStop) ) { if (TrainParams.UpdateMTable( simulation::Time, asNextStop) ) {
// to się wykona tylko raz po zatrzymaniu na W4 // to się wykona tylko raz po zatrzymaniu na W4
if( TrainParams.StationIndex < TrainParams.StationCount ) { if( TrainParams.StationIndex < TrainParams.StationCount ) {
@@ -1012,12 +1021,13 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// HACK: manual check if we didn't already do load exchange at this stop // HACK: manual check if we didn't already do load exchange at this stop
// TODO: remove the check once the station system is in place // TODO: remove the check once the station system is in place
if( m_lastexchangestop != asNextStop ) { if( m_lastexchangestop != asNextStop ) {
auto const platformside = static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ) ) ) % 10; m_lastexchangestop = asNextStop;
auto const exchangetime = simulation::Station.update_load( pVehicles[ end::front ], TrainParams, platformside ); m_lastexchangedirection = pVehicle->DirectionGet();
m_lastexchangeplatforms = static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ) ) ) % 10;
auto const exchangetime { simulation::Station.update_load( pVehicles[ end::front ], TrainParams, m_lastexchangeplatforms ) };
WaitingSet( exchangetime ); WaitingSet( exchangetime );
// announce the stop name while at it // announce the stop name while at it
announce( announcement_t::current ); announce( announcement_t::current );
m_lastexchangestop = asNextStop;
m_makenextstopannouncement = true; m_makenextstopannouncement = true;
} }
@@ -1053,11 +1063,21 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
} }
} }
if( pVehicle->DirectionGet() != m_lastexchangedirection ) {
// generally means the ai driver moved to the opposite end of the consist
// TODO: investigate whether user playing with the reverser can mess this up
auto const left { ( m_lastexchangedirection > 0 ) ? 1 : 2 };
auto const right { 3 - left };
m_lastexchangeplatforms =
( ( m_lastexchangeplatforms & left ) != 0 ? right : 0 )
+ ( ( m_lastexchangeplatforms & right ) != 0 ? left : 0 );
m_lastexchangedirection = pVehicle->DirectionGet();
}
if( ( false == TrainParams.IsMaintenance() ) if( ( false == TrainParams.IsMaintenance() )
&& ( ( false == TestFlag( iDrivigFlags, moveDoorOpened ) ) && ( ( false == TestFlag( iDrivigFlags, moveDoorOpened ) )
|| ( true == DoesAnyDoorNeedOpening ) ) ) { || ( true == DoesAnyDoorNeedOpening ) ) ) {
iDrivigFlags |= moveDoorOpened; // nie wykonywać drugi raz iDrivigFlags |= moveDoorOpened; // nie wykonywać drugi raz
Doors( true, static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ) ) ) % 10 ); Doors( true, m_lastexchangeplatforms );
} }
if (OrderCurrentGet() & ( Shunt | Loose_shunt )) { if (OrderCurrentGet() & ( Shunt | Loose_shunt )) {
@@ -1181,6 +1201,15 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
} }
SemNextStopIndex = -1; // jeśli minęliśmy semafor od ograniczenia to go kasujemy ze zmiennej sprawdzającej dla skanowania w przód SemNextStopIndex = -1; // jeśli minęliśmy semafor od ograniczenia to go kasujemy ze zmiennej sprawdzającej dla skanowania w przód
} }
switch( sSpeedTable[ i ].evEvent->input_command() ) {
case TCommandType::cm_EmergencyBrake: {
pVehicle->RadioStop();
sSpeedTable[ i ].iFlags = 0; // signal reveived, deactivate
}
default: {
break;
}
}
} }
if( sSpeedTable[ i ].fDist > 0.0 ) { if( sSpeedTable[ i ].fDist > 0.0 ) {
// check signals ahead // check signals ahead
@@ -1888,52 +1917,68 @@ void TController::Activation()
iDirection = iDirectionOrder; // kierunek (względem sprzęgów pojazdu z AI) właśnie został ustalony (zmieniony) iDirection = iDirectionOrder; // kierunek (względem sprzęgów pojazdu z AI) właśnie został ustalony (zmieniony)
if (iDirection) if (iDirection)
{ // jeśli jest ustalony kierunek { // jeśli jest ustalony kierunek
TDynamicObject *old = pVehicle, *d = pVehicle; // w tym siedzi AI auto *initialvehicle { pVehicle };
TController *drugi; // jakby były dwa, to zamienić miejscami, a nie robić wycieku pamięci poprzez nadpisanie /*
auto const localbrakelevel { mvOccupied->LocalBrakePosA }; auto const initiallocalbrakelevel { mvOccupied->LocalBrakePosA };
*/
auto const initialspringbrakestate { mvOccupied->SpringBrake.Activate };
// switch off tempomat // switch off tempomat
SpeedCntrl( 0.0 ); SpeedCntrl( 0.0 );
mvControlling->DecScndCtrl( 2 ); mvControlling->DecScndCtrl( 2 );
// reset controls // reset controls
ZeroSpeed(); ZeroSpeed();
ZeroDirection(); ZeroDirection();
mvOccupied->SpringBrakeActivate( true );
if (TestFlag(d->MoverParameters->Couplers[iDirectionOrder < 0 ? end::rear : end::front].CouplingFlag, coupling::control)) {
mvControlling->MainSwitch( false ); // dezaktywacja czuwaka, jeśli przejście do innego członu
mvOccupied->DecLocalBrakeLevel(LocalBrakePosNo); // zwolnienie hamulca w opuszczanym pojeździe
// mvOccupied->BrakeLevelSet((mvOccupied->BrakeHandle==FVel6)?4:-2); //odcięcie na
// zaworze maszynisty, FVel6 po drugiej stronie nie luzuje
mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos(bh_NP) ); // odcięcie na zaworze maszynisty
BrakeLevelSet( gbh_NP ); //ustawienie zmiennej GBH
}
mvOccupied->CabOccupied = mvOccupied->CabActive; // użytkownik moze zmienić CabOccupied wychodząc mvOccupied->CabOccupied = mvOccupied->CabActive; // użytkownik moze zmienić CabOccupied wychodząc
mvOccupied->CabDeactivisation(); // tak jest w Train.cpp mvOccupied->CabDeactivisation(); // tak jest w Train.cpp
if (TestFlag(pVehicle->MoverParameters->Couplers[iDirectionOrder < 0 ? end::rear : end::front].CouplingFlag, coupling::control)) {
ZeroLocalBrake();
if( initialspringbrakestate ) {
mvOccupied->SpringBrakeActivate( false );
}
// odcięcie na zaworze maszynisty, FVel6 po drugiej stronie nie luzuje
mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos(bh_NP) ); // odcięcie na zaworze maszynisty
BrakeLevelSet( mvOccupied->BrakeCtrlPos ); //ustawienie zmiennej GBH
}
// przejście AI na drugą stronę EN57, ET41 itp. // przejście AI na drugą stronę EN57, ET41 itp.
// TODO: clean this up, there's lot of redundancy with TMoverParameters::ChangeCab() and TTrain::MoveToVehicle()
{ {
int movedirection { ( iDirection < 0 ? end::rear : end::front ) }; int movedirection { ( iDirection < 0 ? end::rear : end::front ) };
d = pVehicle->FirstFind( movedirection, coupling::control ); auto *targetvehicle { pVehicle->FirstFind( movedirection, coupling::control ) };
if( pVehicle != d ) { if( pVehicle != targetvehicle ) {
drugi = d->Mechanik; // zapamiętanie tego, co ewentualnie tam siedzi, żeby w razie dwóch zamienić miejscami auto *targetvehicledriver { targetvehicle->Mechanik }; // zapamiętanie tego, co ewentualnie tam siedzi, żeby w razie dwóch zamienić miejscami
d->Mechanik = this; // na razie bilokacja // move to the new vehicle
d->MoverParameters->SetInternalCommand("", 0, 0); // usunięcie ewentualnie zalegającej komendy (Change_direction?) targetvehicle->Mechanik = this; // na razie bilokacja
if( d->DirectionGet() != pVehicle->DirectionGet() ) { targetvehicle->MoverParameters->SetInternalCommand("", 0, 0); // usunięcie ewentualnie zalegającej komendy (Change_direction?)
if( targetvehicle->DirectionGet() != pVehicle->DirectionGet() ) {
// jeśli są przeciwne do siebie to będziemy jechać w drugą stronę względem zasiedzianego pojazdu // jeśli są przeciwne do siebie to będziemy jechać w drugą stronę względem zasiedzianego pojazdu
iDirection = -iDirection; iDirection = -iDirection;
} }
pVehicle->Mechanik = drugi; // wsadzamy tego, co ewentualnie był (podwójna trakcja) // move the other driver to our old vehicle
/* pVehicle->Mechanik = targetvehicledriver; // wsadzamy tego, co ewentualnie był (podwójna trakcja)
pVehicle->MoverParameters->CabActive = 0; // wyłączanie kabin po drodze // NOTE: having caboccupied != 0 (by swapping in the driver from the target vehicle) may lead to dysfunctional brake
pVehicle->MoverParameters->CabOccupied = 0; // i zaznaczenie, że nie ma tam nikogo // TODO: investigate and resolve if necessary
*/ pVehicle->MoverParameters->CabOccupied = targetvehicle->MoverParameters->CabOccupied;
pVehicle = d; // a mechu ma nowy pojazd (no, człon) if( pVehicle->Mechanik ) { // not guaranteed, as target vehicle can be empty
pVehicle->Mechanik->BrakeLevelSet( pVehicle->MoverParameters->BrakeCtrlPos );
}
// finish driver swap
pVehicle = targetvehicle;
} }
} }
if (pVehicle != old) if (pVehicle != initialvehicle)
{ // jeśli zmieniony został pojazd prowadzony { // jeśli zmieniony został pojazd prowadzony
TTrain *train = simulation::Trains.find(old->name()); auto *train { simulation::Trains.find( initialvehicle->name() ) };
if (train) if( train ) {
train->MoveToVehicle( pVehicle ); train->MoveToVehicle( pVehicle );
}
ControllingSet(); // utworzenie połączenia do sterowanego pojazdu (może się zmienić) - silnikowy dla EZT ControllingSet(); // utworzenie połączenia do sterowanego pojazdu (może się zmienić) - silnikowy dla EZT
if( ( mvOccupied->BrakeCtrlPosNo > 0 )
&& ( ( mvOccupied->BrakeSystem == TBrakeSystem::Pneumatic )
|| ( mvOccupied->BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) ) {
mvOccupied->LimPipePress = mvOccupied->PipePress;
mvOccupied->ActFlowSpeed = 0;
}
BrakeLevelSet( mvOccupied->BrakeCtrlPos );
} }
if( mvControlling->EngineType == TEngineType::DieselEngine ) { if( mvControlling->EngineType == TEngineType::DieselEngine ) {
// dla 2Ls150 - przed ustawieniem kierunku - można zmienić tryb pracy // dla 2Ls150 - przed ustawieniem kierunku - można zmienić tryb pracy
@@ -1945,12 +1990,17 @@ void TController::Activation()
} }
// Ra: to przełączanie poniżej jest tu bez sensu // Ra: to przełączanie poniżej jest tu bez sensu
mvOccupied->CabOccupied = iDirection; // aktywacja kabiny w prowadzonym pojeżdzie (silnikowy może być odwrotnie?) mvOccupied->CabOccupied = iDirection; // aktywacja kabiny w prowadzonym pojeżdzie (silnikowy może być odwrotnie?)
// mvOccupied->CabActive=iDirection;
// mvOccupied->DirActive=0; //żeby sam ustawił kierunek
mvOccupied->CabActivisation(); // uruchomienie kabin w członach mvOccupied->CabActivisation(); // uruchomienie kabin w członach
DirectionForward(true); // nawrotnik do przodu DirectionForward(true); // nawrotnik do przodu
if (localbrakelevel > 0.0) // hamowanie tylko jeśli był wcześniej zahamowany (bo możliwe, że jedzie!) /*
mvOccupied->LocalBrakePosA = localbrakelevel; // zahamuj jak wcześniej // NOTE: this won't restore local brake if the vehicle has integrated local brake control
// TBD, TODO: fix or let the ai activate the brake again as part of its standard logic?
if (initiallocalbrakelevel > 0.0) // hamowanie tylko jeśli był wcześniej zahamowany (bo możliwe, że jedzie!)
mvOccupied->LocalBrakePosA = initiallocalbrakelevel; // zahamuj jak wcześniej
*/
if( initialspringbrakestate ) {
mvOccupied->SpringBrakeActivate( initialspringbrakestate );
}
CheckVehicles(); // sprawdzenie składu, AI zapali światła CheckVehicles(); // sprawdzenie składu, AI zapali światła
TableClear(); // resetowanie tabelki skanowania torów TableClear(); // resetowanie tabelki skanowania torów
} }
@@ -3180,13 +3230,15 @@ bool TController::DecBrake()
return OK; return OK;
}; };
bool TController::ZeroLocalBrake() { void TController::ZeroLocalBrake() {
if( mvOccupied->UniCtrlIntegratedLocalBrakeCtrl ) { if( mvOccupied->UniCtrlIntegratedLocalBrakeCtrl ) {
return DecBrakeEIM(); while( DecBrakeEIM() ) {
;
}
} }
else { else {
return mvOccupied->DecLocalBrakeLevel( 2 ); mvOccupied->DecLocalBrakeLevel( LocalBrakePosNo );
} }
} }
@@ -3197,7 +3249,8 @@ bool TController::DecBrakeEIM()
{ {
case 0: { case 0: {
if( mvOccupied->MED_amax != 9.81 ) { if( mvOccupied->MED_amax != 9.81 ) {
auto const brakeposition { clamp( -1.0 * mvOccupied->AIHintLocalBrakeAccFactor * std::max( 0.0, AccDesired ) / mvOccupied->MED_amax, 0.0, 1.0 ) }; auto const desiredacceleration { ( mvOccupied->Vel > 0.01 ? AccDesired : std::max( 0.0, AccDesired ) ) };
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;
} }
@@ -3244,7 +3297,7 @@ bool TController::IncSpeed()
// zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime) // zamykanie drzwi - tutaj wykonuje tylko AI (zmienia fActionTime)
Doors( false ); Doors( false );
} }
if (mvOccupied->SpringBrake.IsActive && mvOccupied->SpringBrake.Activate) { if (mvOccupied->SpringBrake.Activate) {
mvOccupied->SpringBrakeActivate(false); mvOccupied->SpringBrakeActivate(false);
} }
// Doors() call can potentially adjust fActionTime // Doors() call can potentially adjust fActionTime
@@ -6482,6 +6535,7 @@ TController::UpdateSituation(double dt) {
if( ( mvOccupied->EqvtPipePress < 4.5 ) if( ( mvOccupied->EqvtPipePress < 4.5 )
&& ( fReady > 0.35 ) && ( fReady > 0.35 )
&& ( mvOccupied->Compressor >= 7.5 ) // don't charge without sufficient pressure in the tank
&& ( BrakeChargingCooldown >= 0.0 ) && ( BrakeChargingCooldown >= 0.0 )
&& ( ( ActualProximityDist > 100.0 ) // don't charge if we're about to be braking soon && ( ( ActualProximityDist > 100.0 ) // don't charge if we're about to be braking soon
|| ( min_speed( mvOccupied->Vel, VelNext ) == mvOccupied->Vel ) ) ) { || ( min_speed( mvOccupied->Vel, VelNext ) == mvOccupied->Vel ) ) ) {
@@ -6504,8 +6558,9 @@ TController::UpdateSituation(double dt) {
*/ */
} }
if( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition < 0 ) if( ( mvOccupied->Compressor < 5.0 )
&& ( mvOccupied->EqvtPipePress > ( fReady < 0.25 ? 5.1 : 5.2 ) ) ) { || ( ( /*GBH mvOccupied->BrakeCtrlPos*/BrakeCtrlPosition < 0 )
&& ( mvOccupied->EqvtPipePress > ( fReady < 0.25 ? 5.1 : 5.2 ) ) ) ) {
/* GBH mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); */ /* GBH mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_RP ) ); */
BrakeLevelSet( gbh_RP ); BrakeLevelSet( gbh_RP );
} }

View File

@@ -233,7 +233,7 @@ private:
void SetDriverPsyche(); void SetDriverPsyche();
bool IncBrake(); bool IncBrake();
bool DecBrake(); bool DecBrake();
bool ZeroLocalBrake(); void ZeroLocalBrake();
bool IncSpeed(); bool IncSpeed();
bool DecSpeed( bool force = false ); bool DecSpeed( bool force = false );
void ZeroSpeed( bool const Enforce = false ); void ZeroSpeed( bool const Enforce = false );
@@ -450,6 +450,8 @@ private:
std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu
int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu
std::string m_lastexchangestop; // HACK: safeguard to prevent multiple load exchanges per station std::string m_lastexchangestop; // HACK: safeguard to prevent multiple load exchanges per station
int m_lastexchangeplatforms { 0 }; // cached station platforms for last exchange
int m_lastexchangedirection { 0 }; //
double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku
int iRadioChannel = 1; // numer aktualnego kanału radiowego int iRadioChannel = 1; // numer aktualnego kanału radiowego
int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia) int iGuardRadio = 0; // numer kanału radiowego kierownika (0, gdy nie używa radia)

View File

@@ -2632,7 +2632,7 @@ bool TDynamicObject::UpdateForce(double dt)
} }
// initiates load change by specified amounts, with a platform on specified side // initiates load change by specified amounts, with a platform on specified side
void TDynamicObject::LoadExchange( int const Disembark, int const Embark, int const Platform ) { void TDynamicObject::LoadExchange( int const Disembark, int const Embark, int const Platforms ) {
/* /*
if( ( MoverParameters->Doors.open_control == control_t::passenger ) if( ( MoverParameters->Doors.open_control == control_t::passenger )
|| ( MoverParameters->Doors.open_control == control_t::mixed ) ) { || ( MoverParameters->Doors.open_control == control_t::mixed ) ) {
@@ -2647,15 +2647,21 @@ void TDynamicObject::LoadExchange( int const Disembark, int const Embark, int co
} }
} }
*/ */
if( Platform == 0 ) { return; } // edge case, if there's no accessible platforms discard the request if( Platforms == 0 ) { return; } // edge case, if there's no accessible platforms discard the request
m_exchange.unload_count += Disembark; m_exchange.unload_count += Disembark;
m_exchange.load_count += Embark; m_exchange.load_count += Embark;
m_exchange.platforms = Platform; m_exchange.platforms = Platforms;
m_exchange.time = 0.0; m_exchange.time = 0.0;
} }
// calculates time needed to complete current load change // calculates time needed to complete current load change
float TDynamicObject::LoadExchangeTime( int const Platforms ) {
m_exchange.platforms = Platforms;
return LoadExchangeTime();
}
float TDynamicObject::LoadExchangeTime() const { float TDynamicObject::LoadExchangeTime() const {
if( ( m_exchange.unload_count < 0.01 ) && ( m_exchange.load_count < 0.01 ) ) { return 0.f; } if( ( m_exchange.unload_count < 0.01 ) && ( m_exchange.load_count < 0.01 ) ) { return 0.f; }
@@ -4754,8 +4760,7 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
token = ""; token = "";
parser.getTokens(); parser >> token; parser.getTokens(); parser >> token;
if( ( token == "models:" ) if( token == "models:" ) {
|| ( token == "\xef\xbb\xbfmodels:" ) ) { // crude way to handle utf8 bom potentially appearing before the first token
// modele i podmodele // modele i podmodele
m_materialdata.multi_textures = 0; // czy jest wiele tekstur wymiennych? m_materialdata.multi_textures = 0; // czy jest wiele tekstur wymiennych?
parser.getTokens(); parser.getTokens();

View File

@@ -598,8 +598,10 @@ private:
void AttachNext(TDynamicObject *Object, int iType = 1); void AttachNext(TDynamicObject *Object, int iType = 1);
bool UpdateForce(double dt); bool UpdateForce(double dt);
// initiates load change by specified amounts, with a platform on specified side // initiates load change by specified amounts, with a platform on specified side
void LoadExchange( int const Disembark, int const Embark, int const Platform ); void LoadExchange( int const Disembark, int const Embark, int const Platforms );
// calculates time needed to complete current load change // calculates time needed to complete current load change, using specified platforms
float LoadExchangeTime( int const Platforms );
// calculates time needed to complete current load change, using previously specified platforms
float LoadExchangeTime() const; float LoadExchangeTime() const;
// calculates current load exchange factor, where 1 = nominal rate, higher = faster // calculates current load exchange factor, where 1 = nominal rate, higher = faster
float LoadExchangeSpeed() const; // TODO: make private when cleaning up float LoadExchangeSpeed() const; // TODO: make private when cleaning up

View File

@@ -609,42 +609,20 @@ bool TMoverParameters::DecBrakeLevel()
bool TMoverParameters::ChangeCab(int direction) bool TMoverParameters::ChangeCab(int direction)
{ // zmiana kabiny i resetowanie ustawien { // zmiana kabiny i resetowanie ustawien
if (abs(CabOccupied + direction) < 2) if (std::abs(CabOccupied + direction) < 2)
{ {
// if (CabOccupied+direction=0) then LastCab:=CabOccupied;
CabOccupied = CabOccupied + direction; CabOccupied = CabOccupied + direction;
if( ( BrakeCtrlPosNo > 0 ) if( ( BrakeCtrlPosNo > 0 )
&& ( ( BrakeSystem == TBrakeSystem::Pneumatic ) && ( ( BrakeSystem == TBrakeSystem::Pneumatic )
|| ( BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) ) { || ( BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) ) {
// if (BrakeHandle==FV4a) //!!!POBIERAĆ WARTOŚĆ Z KLASY ZAWORU!!!
// BrakeLevelSet(-2); //BrakeCtrlPos=-2;
// else if ((BrakeHandle==FVel6)||(BrakeHandle==St113))
// BrakeLevelSet(2);
// else
// BrakeLevelSet(1);
BrakeLevelSet(Handle->GetPos(bh_NP)); BrakeLevelSet(Handle->GetPos(bh_NP));
LimPipePress = PipePress; LimPipePress = PipePress;
ActFlowSpeed = 0; ActFlowSpeed = 0;
} }
else else
// if (TrainType=dt_EZT) and (BrakeCtrlPosNo>0) then
// BrakeCtrlPos:=5; //z Megapacka
// else
// BrakeLevelSet(0); //BrakeCtrlPos=0;
BrakeLevelSet(Handle->GetPos(bh_NP)); BrakeLevelSet(Handle->GetPos(bh_NP));
// if not TestFlag(BrakeStatus,b_dmg) then
// BrakeStatus:=b_off; //z Megapacka
MainCtrlPos = MainCtrlNoPowerPos(); MainCtrlPos = MainCtrlNoPowerPos();
ScndCtrlPos = 0; ScndCtrlPos = 0;
// Ra: to poniżej jest bez sensu - można przejść nie wyłączając
// if ((EngineType!=DieselEngine)&&(EngineType!=DieselElectric))
//{
// Mains=false;
// CompressorAllow=false;
// ConverterAllow=false;
//}
// DirActive=0;
// DirAbsolute=0;
return true; return true;
} }
return false; return false;
@@ -6170,7 +6148,7 @@ double TMoverParameters::TractionForce( double dt ) {
if( ( RlistSize > 0 ) if( ( RlistSize > 0 )
&& ( ( std::abs( eimv[ eimv_If ] ) > 1.0 ) && ( ( std::abs( eimv[ eimv_If ] ) > 1.0 )
&& ( tmpV > 0.1 ) ) ) { && ( tmpV > 0.0001 ) ) ) {
int i = 0; int i = 0;
while( ( i < RlistSize - 1 ) while( ( i < RlistSize - 1 )

View File

@@ -81,6 +81,11 @@ TCommandType TMemCell::CommandCheck()
eCommand = TCommandType::cm_SetProximityVelocity; eCommand = TCommandType::cm_SetProximityVelocity;
bCommand = false; // ta komenda nie jest wysyłana bCommand = false; // ta komenda nie jest wysyłana
} }
else if( szText == "Emergency_brake" )
{
eCommand = TCommandType::cm_EmergencyBrake;
bCommand = false;
}
else else
{ {
eCommand = TCommandType::cm_Unknown; // ciąg nierozpoznany (nie jest komendą) eCommand = TCommandType::cm_Unknown; // ciąg nierozpoznany (nie jest komendą)

View File

@@ -136,8 +136,8 @@ driverkeyboard_input::default_bindings() {
{ user_command::hornhighactivate, GLFW_KEY_S }, { user_command::hornhighactivate, GLFW_KEY_S },
{ user_command::whistleactivate, GLFW_KEY_Z }, { user_command::whistleactivate, GLFW_KEY_Z },
{ user_command::radiotoggle, GLFW_KEY_R | keymodifier::control }, { user_command::radiotoggle, GLFW_KEY_R | keymodifier::control },
{ user_command::radiochannelincrease, GLFW_KEY_R | keymodifier::shift }, { user_command::radiochannelincrease, GLFW_KEY_EQUAL },
{ user_command::radiochanneldecrease, GLFW_KEY_R }, { user_command::radiochanneldecrease, GLFW_KEY_MINUS },
{ user_command::radiostopsend, GLFW_KEY_PAUSE | keymodifier::shift | keymodifier::control }, { user_command::radiostopsend, GLFW_KEY_PAUSE | keymodifier::shift | keymodifier::control },
{ user_command::radiostoptest, GLFW_KEY_R | keymodifier::shift | keymodifier::control }, { user_command::radiostoptest, GLFW_KEY_R | keymodifier::shift | keymodifier::control },
{ user_command::radiocall3send, GLFW_KEY_BACKSPACE }, { user_command::radiocall3send, GLFW_KEY_BACKSPACE },

View File

@@ -763,10 +763,12 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
locale::strings[ locale::string::debug_vehicle_brakespressures ].c_str(), locale::strings[ locale::string::debug_vehicle_brakespressures ].c_str(),
// brakes // brakes
mover.fBrakeCtrlPos, mover.fBrakeCtrlPos,
mover.LocalBrakePosA,
mover.BrakeOpModeFlag, mover.BrakeOpModeFlag,
update_vehicle_brake().c_str(), update_vehicle_brake().c_str(),
mover.LoadFlag, mover.LoadFlag,
mover.LocalBrakePosA,
( mover.ManualBrakePos / ManualBrakePosNo ),
( mover.SpringBrake.Activate ? 1.f : 0.f ),
// cylinders // cylinders
mover.BrakePress, mover.BrakePress,
mover.LocBrakePress, mover.LocBrakePress,

View File

@@ -467,7 +467,9 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
{ {
auto const stationware { Split( record->StationWare, ',' ) }; auto const stationware { Split( record->StationWare, ',' ) };
for( auto const &entry : stationware ) { for( auto const &entry : stationware ) {
if( entry.front() == 'R' ) { if( entry.front() != 'R' ) {
continue;
}
auto const entrysplit { split_string_and_number( entry ) }; auto const entrysplit { split_string_and_number( entry ) };
if( ( entrysplit.first == "R" ) if( ( entrysplit.first == "R" )
&& ( entrysplit.second <= 10 ) ) { && ( entrysplit.second <= 10 ) ) {
@@ -481,9 +483,8 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
} }
} }
} }
}
if( record->radio_channel != -1 ) { if( record->radio_channel != -1 ) {
activeradiochannel == record->radio_channel; activeradiochannel = record->radio_channel;
} }
} }
record->TrackNo = atoi(s.c_str()); record->TrackNo = atoi(s.c_str());

View File

@@ -4112,7 +4112,7 @@ void opengl33_renderer::Update(double const Deltatime)
// TODO: it doesn't make much sense with vsync // TODO: it doesn't make much sense with vsync
if( Global.targetfps == 0.0f ) { if( Global.targetfps == 0.0f ) {
// automatic adjustment // automatic adjustment
auto const framerate = interpolate( 1000.f / Timer::subsystem.gfx_color.average(), m_framerate, 0.25f ); auto const framerate = interpolate( 1000.f / Timer::subsystem.gfx_color.average(), m_framerate, 0.75f );
float targetfactor; float targetfactor;
if( framerate > 120.0 ) { targetfactor = 3.00f; } if( framerate > 120.0 ) { targetfactor = 3.00f; }
else if( framerate > 90.0 ) { targetfactor = 1.50f; } else if( framerate > 90.0 ) { targetfactor = 1.50f; }

View File

@@ -4170,7 +4170,7 @@ opengl_renderer::Update( double const Deltatime ) {
// adjust draw ranges etc, based on recent performance // adjust draw ranges etc, based on recent performance
if( Global.targetfps == 0.0f ) { if( Global.targetfps == 0.0f ) {
// automatic adjustment // automatic adjustment
auto const framerate = 0.5f * ( m_framerate + 1000.f / Timer::subsystem.gfx_color.average() ); auto const framerate = interpolate( 1000.f / Timer::subsystem.gfx_color.average(), m_framerate, 0.75f );
float targetfactor; float targetfactor;
if( framerate > 120.0 ) { targetfactor = 3.00f; } if( framerate > 120.0 ) { targetfactor = 3.00f; }
else if( framerate > 90.0 ) { targetfactor = 1.50f; } else if( framerate > 90.0 ) { targetfactor = 1.50f; }

View File

@@ -211,6 +211,17 @@ std::string cParser::readToken( bool ToLower, const char *Break ) {
} }
} while( token == "" && mStream->peek() != EOF ); // double check in case of consecutive separators } while( token == "" && mStream->peek() != EOF ); // double check in case of consecutive separators
} }
// check the first token for potential presence of utf bom
if( mFirstToken ) {
mFirstToken = false;
if( token.rfind( "\xef\xbb\xbf", 0 ) == 0 ) {
token.erase( 0, 3 );
}
if( true == token.empty() ) {
// potentially possible if our first token was standalone utf bom
token = readToken( ToLower, Break );
}
}
if( false == parameters.empty() ) { if( false == parameters.empty() ) {
// if there's parameter list, check the token for potential parameters to replace // if there's parameter list, check the token for potential parameters to replace

View File

@@ -104,6 +104,7 @@ class cParser //: public std::stringstream
std::streamoff mSize { 0 }; // size of open stream, for progress report. std::streamoff mSize { 0 }; // size of open stream, for progress report.
std::size_t mLine { 0 }; // currently processed line std::size_t mLine { 0 }; // currently processed line
bool mIncFile { false }; // the parser is processing an *.inc file bool mIncFile { false }; // the parser is processing an *.inc file
bool mFirstToken { true }; // processing first token in the current file; helper used when checking for utf bom
typedef std::map<std::string, std::string> commentmap; typedef std::map<std::string, std::string> commentmap;
commentmap mComments { commentmap mComments {
commentmap::value_type( "/*", "*/" ), commentmap::value_type( "/*", "*/" ),

View File

@@ -76,7 +76,7 @@ init() {
"Controllers:\n master: %d(%d), secondary: %s\nEngine output: %.1f, current: %.0f\nRevolutions:\n engine: %.0f, motors: %.0f\n engine fans: %.0f, motor fans: %.0f+%.0f, cooling fans: %.0f+%.0f", "Controllers:\n master: %d(%d), secondary: %s\nEngine output: %.1f, current: %.0f\nRevolutions:\n engine: %.0f, motors: %.0f\n engine fans: %.0f, motor fans: %.0f+%.0f, cooling fans: %.0f+%.0f",
" (shunt mode)", " (shunt mode)",
"\nTemperatures:\n engine: %.2f, oil: %.2f, water: %.2f%c%.2f", "\nTemperatures:\n engine: %.2f, oil: %.2f, water: %.2f%c%.2f",
"Brakes:\n train: %.2f, independent: %.2f, mode: %d, delay: %s, load flag: %d\nBrake cylinder pressures:\n train: %.2f, independent: %.2f, status: 0x%.2x\nPipe pressures:\n brake: %.2f (hat: %.2f), main: %.2f, control: %.2f\nTank pressures:\n auxiliary: %.2f, main: %.2f, control: %.2f", "Brakes:\n train: %.2f (mode: %d, delay: %s, load flag: %d)\n independent: %.2f, manual: %.2f, spring: %.2f\nBrake cylinder pressures:\n train: %.2f, independent: %.2f, status: 0x%.2x\nPipe pressures:\n brake: %.2f (hat: %.2f), main: %.2f, control: %.2f\nTank pressures:\n auxiliary: %.2f, main: %.2f, control: %.2f",
" pantograph: %.2f%cMT", " pantograph: %.2f%cMT",
"Forces:\n tractive: %.1f, brake: %.1f, friction: %.2f%s\nAcceleration:\n tangential: %.2f, normal: %.2f (path radius: %s)\nVelocity: %.2f, distance traveled: %.2f\nPosition: [%.2f, %.2f, %.2f]", "Forces:\n tractive: %.1f, brake: %.1f, friction: %.2f%s\nAcceleration:\n tangential: %.2f, normal: %.2f (path radius: %s)\nVelocity: %.2f, distance traveled: %.2f\nPosition: [%.2f, %.2f, %.2f]",
@@ -281,7 +281,7 @@ init() {
"Nastawniki:\n glowny: %d(%d), dodatkowy: %s\nMoc silnika: %.1f, prad silnika: %.0f\nObroty:\n silnik: %.0f, motory: %.0f\n went.silnika: %.0f, went.motorow: %.0f+%.0f, went.chlodnicy: %.0f+%.0f", "Nastawniki:\n glowny: %d(%d), dodatkowy: %s\nMoc silnika: %.1f, prad silnika: %.0f\nObroty:\n silnik: %.0f, motory: %.0f\n went.silnika: %.0f, went.motorow: %.0f+%.0f, went.chlodnicy: %.0f+%.0f",
" (tryb manewrowy)", " (tryb manewrowy)",
"\nTemperatury:\n silnik: %.2f, olej: %.2f, woda: %.2f%c%.2f", "\nTemperatury:\n silnik: %.2f, olej: %.2f, woda: %.2f%c%.2f",
"Hamulce:\n zespolony: %.2f, pomocniczy: %.2f, tryb: %d, nastawa: %s, ladunek: %d\nCisnienie w cylindrach:\n zespolony: %.2f, pomocniczy: %.2f, status: 0x%.2x\nCisnienia w przewodach:\n glowny: %.2f (kapturek: %.2f), zasilajacy: %.2f, kontrolny: %.2f\nCisnienia w zbiornikach:\n pomocniczy: %.2f, glowny: %.2f, sterujacy: %.2f", "Hamulce:\n zespolony: %.2f (tryb: %d, nastawa: %s, ladunek: %d)\n pomocniczy: %.2f, postojowy: %.2f, sprezynowy: %.2f\nCisnienie w cylindrach:\n zespolony: %.2f, pomocniczy: %.2f, status: 0x%.2x\nCisnienia w przewodach:\n glowny: %.2f (kapturek: %.2f), zasilajacy: %.2f, kontrolny: %.2f\nCisnienia w zbiornikach:\n pomocniczy: %.2f, glowny: %.2f, sterujacy: %.2f",
" pantograf: %.2f%cZG", " pantograf: %.2f%cZG",
"Sily:\n napedna: %.1f, hamowania: %.1f, tarcie: %.2f%s\nPrzyspieszenia:\n styczne: %.2f, normalne: %.2f (promien: %s)\nPredkosc: %.2f, pokonana odleglosc: %.2f\nPozycja: [%.2f, %.2f, %.2f]", "Sily:\n napedna: %.1f, hamowania: %.1f, tarcie: %.2f%s\nPrzyspieszenia:\n styczne: %.2f, normalne: %.2f (promien: %s)\nPredkosc: %.2f, pokonana odleglosc: %.2f\nPozycja: [%.2f, %.2f, %.2f]",

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 20 #define VERSION_MAJOR 20
#define VERSION_MINOR 806 #define VERSION_MINOR 824
#define VERSION_REVISION 0 #define VERSION_REVISION 0