mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 17:59:19 +02:00
Merge branch 'tmj-dev' into milek-dev
This commit is contained in:
11
DynObj.cpp
11
DynObj.cpp
@@ -1735,7 +1735,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
)
|
||||
{ // Ustawienie początkowe pojazdu
|
||||
iDirection = (Reversed ? 0 : 1); // Ra: 0, jeśli ma być wstawiony jako obrócony tyłem
|
||||
asBaseDir = "dynamic/" + BaseDir + "/"; // McZapkie-310302
|
||||
asBaseDir = szDynamicPath + BaseDir + "/"; // McZapkie-310302
|
||||
asName = Name;
|
||||
std::string asAnimName = ""; // zmienna robocza do wyszukiwania osi i wózków
|
||||
// Ra: zmieniamy znaczenie obsady na jednoliterowe, żeby dosadzić kierownika
|
||||
@@ -1782,8 +1782,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
(fVel > 0 ? 1 : -1) * Cab *
|
||||
(iDirection ? 1 : -1))) // jak jedzie lub obsadzony to gotowy do drogi
|
||||
{
|
||||
Error("Parameters mismatch: dynamic object " + asName + " from\n" + BaseDir + "/" +
|
||||
Type_Name);
|
||||
Error("Parameters mismatch: dynamic object " + asName + " from \"" + BaseDir + "/" + Type_Name + "\"" );
|
||||
return 0.0; // zerowa długość to brak pojazdu
|
||||
}
|
||||
// ustawienie pozycji hamulca
|
||||
@@ -4175,12 +4174,16 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
m_materialdata.multi_textures = 0; // czy jest wiele tekstur wymiennych?
|
||||
parser.getTokens();
|
||||
parser >> asModel;
|
||||
std::replace(asModel.begin(), asModel.end(), '\\', '/');
|
||||
replace_slashes( asModel );
|
||||
if( asModel[asModel.size() - 1] == '#' ) // Ra 2015-01: nie podoba mi siê to
|
||||
{ // model wymaga wielu tekstur wymiennych
|
||||
m_materialdata.multi_textures = 1;
|
||||
asModel.erase( asModel.length() - 1 );
|
||||
}
|
||||
// name can contain leading slash, erase it to avoid creation of double slashes when the name is combined with current directory
|
||||
if( asModel[ 0 ] == '/' ) {
|
||||
asModel.erase( 0, 1 );
|
||||
}
|
||||
std::size_t i = asModel.find( ',' );
|
||||
if ( i != std::string::npos )
|
||||
{ // Ra 2015-01: może szukać przecinka w nazwie modelu, a po przecinku była by liczba tekstur?
|
||||
|
||||
4
EU07.cpp
4
EU07.cpp
@@ -405,8 +405,8 @@ int main(int argc, char *argv[])
|
||||
*/
|
||||
if( Global.iConvertModels < 0 ) {
|
||||
Global.iConvertModels = -Global.iConvertModels;
|
||||
World.CreateE3D( "models/" ); // rekurencyjne przeglądanie katalogów
|
||||
World.CreateE3D( "dynamic/", true );
|
||||
World.CreateE3D( szModelPath ); // rekurencyjne przeglądanie katalogów
|
||||
World.CreateE3D( szDynamicPath, true );
|
||||
} // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -473,9 +473,8 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org)
|
||||
}
|
||||
else if (token.substr(token.length() - 4, 4) == ".vmd") // na razie tu, może będzie inaczej
|
||||
{ // animacja z pliku VMD
|
||||
// TFileStream *fs = new TFileStream( "models/" + AnsiString( token.c_str() ), fmOpenRead );
|
||||
{
|
||||
std::ifstream file( "models/" + token, std::ios::binary | std::ios::ate ); file.unsetf( std::ios::skipws );
|
||||
std::ifstream file( szModelPath + token, std::ios::binary | std::ios::ate ); file.unsetf( std::ios::skipws );
|
||||
auto size = file.tellg(); // ios::ate already positioned us at the end of the file
|
||||
file.seekg( 0, std::ios::beg ); // rewind the caret afterwards
|
||||
Params[ 7 ].asInt = size;
|
||||
|
||||
@@ -302,6 +302,11 @@ global_settings::ConfigParse(cParser &Parser) {
|
||||
// max 8 lights per opengl specs, minus one used for sun. at least one light for controlled vehicle
|
||||
DynamicLightCount = clamp( DynamicLightCount, 1, 7 );
|
||||
}
|
||||
else if( token == "scenario.time.offset" ) {
|
||||
// shift (in hours) applied to train timetables
|
||||
Parser.getTokens( 1, false );
|
||||
Parser >> ScenarioTimeOffset;
|
||||
}
|
||||
else if( token == "scalespeculars" ) {
|
||||
// whether strength of specular highlights should be adjusted (generally needed for legacy 3d models)
|
||||
Parser.getTokens();
|
||||
|
||||
@@ -81,6 +81,7 @@ struct global_settings {
|
||||
bool FakeLight{ false }; // toggle between fixed and dynamic daylight
|
||||
double fTimeSpeed{ 1.0 }; // przyspieszenie czasu, zmienna do testów
|
||||
double fLatitudeDeg{ 52.0 }; // szerokość geograficzna
|
||||
float ScenarioTimeOffset { 0.f }; // time shift (in hours) applied to train timetables
|
||||
bool bInactivePause{ true }; // automatyczna pauza, gdy okno nieaktywne
|
||||
int iSlowMotionMask{ -1 }; // maska wyłączanych właściwości
|
||||
bool bHideConsole{ false }; // hunter-271211: ukrywanie konsoli
|
||||
|
||||
@@ -3078,89 +3078,175 @@ void TMoverParameters::UpdateBrakePressure(double dt)
|
||||
// Q: 20160712
|
||||
// Obliczanie pracy sprężarki
|
||||
// *************************************************************************************************
|
||||
// TODO: clean the method up, a lot of the code is redundant
|
||||
void TMoverParameters::CompressorCheck(double dt)
|
||||
{
|
||||
if( VeselVolume == 0.0 ) { return; }
|
||||
|
||||
CompressedVolume = std::max( 0.0, CompressedVolume - dt * AirLeakRate * 0.1 ); // nieszczelności: 0.001=1l/s
|
||||
|
||||
// if (CompressorSpeed>0.0) then //ten warunek został sprawdzony przy wywołaniu funkcji
|
||||
if (VeselVolume > 0)
|
||||
{
|
||||
if (MaxCompressor - MinCompressor < 0.0001)
|
||||
{
|
||||
// if (Mains && (MainCtrlPos > 1))
|
||||
if (CompressorAllow && CompressorAllowLocal && Mains && (MainCtrlPos > 0))
|
||||
{
|
||||
if (Compressor < MaxCompressor)
|
||||
if ((EngineType == DieselElectric) && (CompressorPower > 0))
|
||||
CompressedVolume += dt * CompressorSpeed *
|
||||
(2.0 * MaxCompressor - Compressor) / MaxCompressor *
|
||||
(DElist[MainCtrlPos].RPM / DElist[MainCtrlPosNo].RPM);
|
||||
else
|
||||
{
|
||||
CompressedVolume +=
|
||||
dt * CompressorSpeed * (2.0 * MaxCompressor - Compressor) / MaxCompressor;
|
||||
TotalCurrent += 0.0015
|
||||
* Voltage; // tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę
|
||||
}
|
||||
if( ( true == CompressorGovernorLock )
|
||||
&& ( Compressor < MinCompressor ) ) {
|
||||
// if the pressure drops below the cut-in level, we can reset compressor governor
|
||||
// TBD, TODO: don't operate the lock without battery power?
|
||||
CompressorGovernorLock = false;
|
||||
}
|
||||
|
||||
if (MaxCompressor - MinCompressor < 0.0001) {
|
||||
// TODO: investigate purpose of this branch and whether it can be removed as it duplicates later code
|
||||
if( ( true == CompressorAllow )
|
||||
&& ( true == CompressorAllowLocal )
|
||||
&& ( true == Mains )
|
||||
&& ( MainCtrlPos > 0 ) ) {
|
||||
if( Compressor < MaxCompressor ) {
|
||||
if( ( EngineType == DieselElectric )
|
||||
&& ( CompressorPower > 0 ) ) {
|
||||
CompressedVolume +=
|
||||
CompressorSpeed
|
||||
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
|
||||
* ( DElist[ MainCtrlPos ].RPM / DElist[ MainCtrlPosNo ].RPM )
|
||||
* dt;
|
||||
}
|
||||
else {
|
||||
CompressedVolume +=
|
||||
CompressorSpeed
|
||||
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
|
||||
* dt;
|
||||
TotalCurrent += 0.0015 * Voltage; // tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę
|
||||
}
|
||||
}
|
||||
else {
|
||||
CompressedVolume = CompressedVolume * 0.8;
|
||||
SetFlag(SoundFlag, sound::relay | sound::loud);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( ( ( CompressorPower == 0 )
|
||||
|| ( CompressorPower == 3 ) )
|
||||
&& ( ( EngineType == DieselEngine )
|
||||
|| ( EngineType == DieselElectric ) ) ) {
|
||||
// experimental: make sure compressor coupled with diesel engine is always ready for work
|
||||
CompressorAllow = true;
|
||||
}
|
||||
if (CompressorFlag) // jeśli sprężarka załączona
|
||||
{ // sprawdzić możliwe warunki wyłączenia sprężarki
|
||||
if (CompressorPower == 5) // jeśli zasilanie z sąsiedniego członu
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if (Couplers[1].Connected != NULL)
|
||||
CompressorFlag =
|
||||
( Couplers[ 1 ].Connected->CompressorAllow
|
||||
&& Couplers[ 1 ].Connected->CompressorAllowLocal
|
||||
&& Couplers[ 1 ].Connected->Mains
|
||||
&& Couplers[ 1 ].Connected->ConverterFlag );
|
||||
else
|
||||
{
|
||||
CompressedVolume = CompressedVolume * 0.8;
|
||||
SetFlag(SoundFlag, sound::relay | sound::loud);
|
||||
// SetFlag(SoundFlag, sound::loud);
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
else if (CompressorPower == 4) // jeśli zasilanie z poprzedniego członu
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if (Couplers[0].Connected != NULL)
|
||||
CompressorFlag =
|
||||
( Couplers[ 0 ].Connected->CompressorAllow
|
||||
&& Couplers[ 0 ].Connected->CompressorAllowLocal
|
||||
&& Couplers[ 0 ].Connected->Mains
|
||||
&& Couplers[ 0 ].Connected->ConverterFlag );
|
||||
else
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
else
|
||||
CompressorFlag =
|
||||
( ( CompressorAllow )
|
||||
&& ( CompressorAllowLocal )
|
||||
&& ( Mains )
|
||||
&& ( ( ConverterFlag )
|
||||
|| ( CompressorPower == 0 )
|
||||
|| ( CompressorPower == 3 ) ) );
|
||||
|
||||
if( Compressor > MaxCompressor ) {
|
||||
// wyłącznik ciśnieniowy jest niezależny od sposobu zasilania
|
||||
// TBD, TODO: don't operate the lock without battery power?
|
||||
if( ( CompressorPower == 0 )
|
||||
|| ( CompressorPower == 3 ) ) {
|
||||
// if the compressor is powered directly by the engine the lock can't turn it off and instead just changes the output
|
||||
if( false == CompressorGovernorLock ) {
|
||||
// emit relay sound when the lock engages (the state change itself is below) and presumably changes where the air goes
|
||||
SetFlag( SoundFlag, sound::relay | sound::loud );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// if the compressor isn't coupled with the engine the lock can control its state freely
|
||||
CompressorFlag = false;
|
||||
}
|
||||
CompressorGovernorLock = true; // prevent manual activation until the pressure goes below cut-in level
|
||||
}
|
||||
|
||||
if( ( TrainType == dt_ET41 )
|
||||
|| ( TrainType == dt_ET42 ) ) {
|
||||
// for these multi-unit engines compressors turn off whenever any of them was affected by the governor
|
||||
// NOTE: this is crude implementation, TODO: re-implement when a more elegant/flexible system is in place
|
||||
if( ( Couplers[ 1 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
CompressorFlag &= ( Couplers[ 1 ].Connected->CompressorGovernorLock == false );
|
||||
}
|
||||
if( ( Couplers[ 0 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the second unit isn't allowed to start its compressor until first unit can start its own as well
|
||||
CompressorFlag &= ( Couplers[ 0 ].Connected->CompressorGovernorLock == false );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ( CompressorPower == 0 )
|
||||
&& ( ( EngineType == DieselEngine )
|
||||
|| ( EngineType == DieselElectric ) ) ) {
|
||||
// experimental: make sure compressor coupled with diesel engine is always ready for work
|
||||
CompressorAllow = true;
|
||||
}
|
||||
if (CompressorFlag) // jeśli sprężarka załączona
|
||||
{ // sprawdzić możliwe warunki wyłączenia sprężarki
|
||||
if (CompressorPower == 5) // jeśli zasilanie z sąsiedniego członu
|
||||
else {
|
||||
// jeśli nie załączona
|
||||
if( ( LastSwitchingTime > CtrlDelay )
|
||||
&& ( ( Compressor < MinCompressor )
|
||||
|| ( ( Compressor < MaxCompressor )
|
||||
&& ( false == CompressorGovernorLock ) ) ) ) {
|
||||
// załączenie przy małym ciśnieniu
|
||||
// jeśli nie załączona, a ciśnienie za małe
|
||||
// or if the switch is on and the pressure isn't maxed
|
||||
if( CompressorPower == 5 ) // jeśli zasilanie z następnego członu
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if (Couplers[1].Connected != NULL)
|
||||
if( Couplers[ 1 ].Connected != nullptr ) {
|
||||
CompressorFlag =
|
||||
( Couplers[ 1 ].Connected->CompressorAllow
|
||||
&& Couplers[ 1 ].Connected->CompressorAllowLocal
|
||||
&& Couplers[ 1 ].Connected->Mains
|
||||
&& Couplers[ 1 ].Connected->ConverterFlag );
|
||||
else
|
||||
}
|
||||
else {
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
}
|
||||
else if (CompressorPower == 4) // jeśli zasilanie z poprzedniego członu
|
||||
else if( CompressorPower == 4 ) // jeśli zasilanie z poprzedniego członu
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if (Couplers[0].Connected != NULL)
|
||||
if( Couplers[ 0 ].Connected != nullptr ) {
|
||||
CompressorFlag =
|
||||
( Couplers[ 0 ].Connected->CompressorAllow
|
||||
&& Couplers[ 0 ].Connected->CompressorAllowLocal
|
||||
&& Couplers[ 0 ].Connected->Mains
|
||||
&& Couplers[ 0 ].Connected->ConverterFlag );
|
||||
else
|
||||
}
|
||||
else {
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
CompressorFlag =
|
||||
( ( CompressorAllow )
|
||||
&& ( CompressorAllowLocal )
|
||||
&& ( Mains )
|
||||
&& ( ( ConverterFlag )
|
||||
|| ( CompressorPower == 0 ) ) );
|
||||
|
||||
if( Compressor > MaxCompressor ) {
|
||||
// wyłącznik ciśnieniowy jest niezależny od sposobu zasilania
|
||||
CompressorFlag = false;
|
||||
CompressorGovernorLock = true; // prevent manual activation until the pressure goes below cut-in level
|
||||
|| ( CompressorPower == 0 )
|
||||
|| ( CompressorPower == 3 ) ) );
|
||||
}
|
||||
|
||||
// NOTE: crude way to enforce simultaneous activation of compressors in multi-unit setups
|
||||
// TODO: replace this with a more universal activation system down the road
|
||||
if( ( TrainType == dt_ET41 )
|
||||
|| ( TrainType == dt_ET42 ) ) {
|
||||
// for these multi-unit engines compressors turn off whenever any of them was affected by the governor
|
||||
// NOTE: this is crude implementation, TODO: re-implement when a more elegant/flexible system is in place
|
||||
if( ( Couplers[ 1 ].Connected != nullptr )
|
||||
|
||||
if( ( Couplers[1].Connected != nullptr )
|
||||
&& ( true == TestFlag( Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
CompressorFlag &= ( Couplers[ 1 ].Connected->CompressorGovernorLock == false );
|
||||
@@ -3171,110 +3257,67 @@ void TMoverParameters::CompressorCheck(double dt)
|
||||
CompressorFlag &= ( Couplers[ 0 ].Connected->CompressorGovernorLock == false );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// jeśli nie załączona
|
||||
if( Compressor < MinCompressor ) {
|
||||
// if the pressure drops below the cut-in level, we can reset compressor governor
|
||||
CompressorGovernorLock = false;
|
||||
}
|
||||
|
||||
if( ( ( Compressor < MinCompressor )
|
||||
|| ( ( Compressor < MaxCompressor )
|
||||
&& ( false == CompressorGovernorLock ) ) )
|
||||
&& ( LastSwitchingTime > CtrlDelay ) ) {
|
||||
// załączenie przy małym ciśnieniu
|
||||
// jeśli nie załączona, a ciśnienie za małe
|
||||
// or if the switch is on and the pressure isn't maxed
|
||||
if( CompressorPower == 5 ) // jeśli zasilanie z następnego członu
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if( Couplers[ 1 ].Connected != nullptr ) {
|
||||
CompressorFlag =
|
||||
( Couplers[ 1 ].Connected->CompressorAllow
|
||||
&& Couplers[ 1 ].Connected->CompressorAllowLocal
|
||||
&& Couplers[ 1 ].Connected->Mains
|
||||
&& Couplers[ 1 ].Connected->ConverterFlag );
|
||||
}
|
||||
else {
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
}
|
||||
else if( CompressorPower == 4 ) // jeśli zasilanie z poprzedniego członu
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if( Couplers[ 0 ].Connected != nullptr ) {
|
||||
CompressorFlag =
|
||||
( Couplers[ 0 ].Connected->CompressorAllow
|
||||
&& Couplers[ 0 ].Connected->CompressorAllowLocal
|
||||
&& Couplers[ 0 ].Connected->Mains
|
||||
&& Couplers[ 0 ].Connected->ConverterFlag );
|
||||
}
|
||||
else {
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
}
|
||||
else {
|
||||
CompressorFlag =
|
||||
( ( CompressorAllow )
|
||||
&& ( CompressorAllowLocal )
|
||||
&& ( Mains )
|
||||
&& ( ( ConverterFlag )
|
||||
|| ( CompressorPower == 0 ) ) );
|
||||
}
|
||||
|
||||
// NOTE: crude way to enforce simultaneous activation of compressors in multi-unit setups
|
||||
// TODO: replace this with a more universal activation system down the road
|
||||
if( ( TrainType == dt_ET41 )
|
||||
|| ( TrainType == dt_ET42 ) ) {
|
||||
|
||||
if( ( Couplers[1].Connected != nullptr )
|
||||
&& ( true == TestFlag( Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
CompressorFlag &= ( Couplers[ 1 ].Connected->CompressorGovernorLock == false );
|
||||
}
|
||||
if( ( Couplers[ 0 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the second unit isn't allowed to start its compressor until first unit can start its own as well
|
||||
CompressorFlag &= ( Couplers[ 0 ].Connected->CompressorGovernorLock == false );
|
||||
}
|
||||
}
|
||||
|
||||
if( CompressorFlag ) {
|
||||
// jeśli została załączona
|
||||
LastSwitchingTime = 0; // to trzeba ograniczyć ponowne włączenie
|
||||
}
|
||||
if( CompressorFlag ) {
|
||||
// jeśli została załączona
|
||||
LastSwitchingTime = 0; // to trzeba ograniczyć ponowne włączenie
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( CompressorFlag ) {
|
||||
if( ( EngineType == DieselElectric ) && ( CompressorPower > 0 ) ) {
|
||||
if( CompressorFlag ) {
|
||||
if( ( EngineType == DieselElectric )
|
||||
&& ( ( CompressorPower == 0 )
|
||||
|| ( CompressorPower == 3 ) ) ) {
|
||||
if( false == CompressorGovernorLock ) {
|
||||
CompressedVolume +=
|
||||
dt * CompressorSpeed
|
||||
CompressorSpeed
|
||||
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
|
||||
* ( DElist[ MainCtrlPos ].RPM / DElist[ MainCtrlPosNo ].RPM );
|
||||
* ( DElist[ MainCtrlPos ].RPM / DElist[ MainCtrlPosNo ].RPM )
|
||||
* dt;
|
||||
}
|
||||
else if( ( EngineType == DieselEngine ) && ( CompressorPower == 0 ) ) {
|
||||
/*
|
||||
else {
|
||||
// the lock is active, air is being vented out
|
||||
CompressedVolume -= 0.1 * dt;
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if( ( EngineType == DieselEngine )
|
||||
&& ( ( CompressorPower == 0 )
|
||||
|| ( CompressorPower == 3 ) ) ) {
|
||||
if( false == CompressorGovernorLock ) {
|
||||
// experimental: compressor coupled with diesel engine, output scaled by current engine rotational speed
|
||||
CompressedVolume +=
|
||||
dt * CompressorSpeed
|
||||
CompressorSpeed
|
||||
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
|
||||
* ( std::abs( enrot ) / nmax );
|
||||
* ( std::abs( enrot ) / nmax )
|
||||
* dt;
|
||||
}
|
||||
/*
|
||||
else {
|
||||
// the lock is active, air is being vented out
|
||||
CompressedVolume -= 0.1 * dt;
|
||||
}
|
||||
*/
|
||||
}
|
||||
else {
|
||||
CompressedVolume +=
|
||||
CompressorSpeed
|
||||
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
|
||||
* dt;
|
||||
|
||||
if( ( CompressorPower == 5 ) && ( Couplers[ 1 ].Connected != NULL ) ) {
|
||||
// tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę
|
||||
Couplers[ 1 ].Connected->TotalCurrent += 0.0015 * Couplers[ 1 ].Connected->Voltage;
|
||||
}
|
||||
else if( ( CompressorPower == 4 ) && ( Couplers[ 0 ].Connected != NULL ) ) {
|
||||
// tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę
|
||||
Couplers[ 0 ].Connected->TotalCurrent += 0.0015 * Couplers[ 0 ].Connected->Voltage;
|
||||
}
|
||||
else {
|
||||
CompressedVolume +=
|
||||
dt * CompressorSpeed * ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor;
|
||||
if( ( CompressorPower == 5 ) && ( Couplers[ 1 ].Connected != NULL ) )
|
||||
Couplers[ 1 ].Connected->TotalCurrent +=
|
||||
0.0015 * Couplers[ 1 ].Connected->Voltage; // tymczasowo tylko obciążenie
|
||||
// sprężarki, tak z 5A na
|
||||
// sprężarkę
|
||||
else if( ( CompressorPower == 4 ) && ( Couplers[ 0 ].Connected != NULL ) )
|
||||
Couplers[ 0 ].Connected->TotalCurrent +=
|
||||
0.0015 * Couplers[ 0 ].Connected->Voltage; // tymczasowo tylko obciążenie
|
||||
// sprężarki, tak z 5A na
|
||||
// sprężarkę
|
||||
else
|
||||
TotalCurrent += 0.0015 *
|
||||
Voltage; // tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę
|
||||
// tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę
|
||||
TotalCurrent += 0.0015 * Voltage;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7285,11 +7328,12 @@ void TMoverParameters::LoadFIZ_Brake( std::string const &line ) {
|
||||
extract_value( CompressorSpeed, "CompressorSpeed", line, "" );
|
||||
{
|
||||
std::map<std::string, int> compressorpowers{
|
||||
{ "Main", 0 },
|
||||
// 1: default, powered by converter, with manual state control
|
||||
{ "Converter", 2 },
|
||||
{ "Engine", 3 },
|
||||
{ "Engine", 3 }, // equivalent of 0, TODO: separate 'main' and 'engine' in the code
|
||||
{ "Coupler1", 4 },//włączana w silnikowym EZT z przodu
|
||||
{ "Coupler2", 5 },//włączana w silnikowym EZT z tyłu
|
||||
{ "Main", 0 }
|
||||
{ "Coupler2", 5 } //włączana w silnikowym EZT z tyłu
|
||||
};
|
||||
auto lookup = compressorpowers.find( extract_value( "CompressorPower", line ) );
|
||||
CompressorPower =
|
||||
|
||||
@@ -83,10 +83,10 @@ TModelsManager::GetModel(std::string const &Name, bool const Dynamic)
|
||||
std::string filename { Name };
|
||||
if( Name.find( '/' ) != std::string::npos && !Dynamic ) {
|
||||
// pobieranie tekstur z katalogu, w którym jest model
|
||||
// when loading vehicles the path is set by the calling routine, so we can skip it here
|
||||
Global.asCurrentTexturePath += Name;
|
||||
Global.asCurrentTexturePath.erase( Global.asCurrentTexturePath.rfind( "/" ) + 1 );
|
||||
Global.asCurrentTexturePath.erase( Global.asCurrentTexturePath.rfind( '/' ) + 1 );
|
||||
}
|
||||
|
||||
erase_extension( filename );
|
||||
filename = ToLower( filename );
|
||||
|
||||
|
||||
110
Train.cpp
110
Train.cpp
@@ -223,6 +223,9 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
||||
{ user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle },
|
||||
{ user_command::linebreakeropen, &TTrain::OnCommand_linebreakeropen },
|
||||
{ user_command::linebreakerclose, &TTrain::OnCommand_linebreakerclose },
|
||||
{ user_command::fuelpumptoggle, &TTrain::OnCommand_fuelpumptoggle },
|
||||
{ user_command::fuelpumpenable, &TTrain::OnCommand_fuelpumpenable },
|
||||
{ user_command::fuelpumpdisable, &TTrain::OnCommand_fuelpumpdisable },
|
||||
{ user_command::convertertoggle, &TTrain::OnCommand_convertertoggle },
|
||||
{ user_command::converterenable, &TTrain::OnCommand_converterenable },
|
||||
{ user_command::converterdisable, &TTrain::OnCommand_converterdisable },
|
||||
@@ -2003,6 +2006,45 @@ void TTrain::OnCommand_linebreakerclose( TTrain *Train, command_data const &Comm
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_fuelpumptoggle( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( false == Train->mvControlled->FuelPump.is_enabled ) {
|
||||
// turn on
|
||||
OnCommand_fuelpumpenable( Train, Command );
|
||||
}
|
||||
else {
|
||||
//turn off
|
||||
OnCommand_fuelpumpdisable( Train, Command );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_fuelpumpenable( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// visual feedback
|
||||
Train->ggFuelPumpButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
|
||||
if( true == Train->mvControlled->FuelPump.is_enabled ) { return; } // already enabled
|
||||
|
||||
Train->mvControlled->FuelPumpSwitch( true );
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_fuelpumpdisable( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// visual feedback
|
||||
Train->ggFuelPumpButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
|
||||
if( false == Train->mvControlled->FuelPump.is_enabled ) { return; } // already disabled
|
||||
|
||||
Train->mvControlled->FuelPumpSwitch( false );
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
@@ -3869,12 +3911,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
}
|
||||
}
|
||||
if( m_linebreakerstate == 1 ) {
|
||||
if( ( mvControlled->EngineType == DieselElectric )
|
||||
&& ( false == mvControlled->ConverterFlag ) ) {
|
||||
// converter acts as a make-believe fuel pump so if it's off, kill the engine
|
||||
// TODO: implement actual fuel system and move this check to the mover update
|
||||
mvControlled->MainSwitch( false );
|
||||
}
|
||||
if( false == mvControlled->Mains ) {
|
||||
// crude way to catch cases where the main was knocked out and the user is trying to restart it
|
||||
// because the state of the line breaker isn't changed to match, we need to do it here manually
|
||||
@@ -3922,6 +3958,9 @@ bool TTrain::Update( double const Deltatime )
|
||||
// finalize state change of the line breaker
|
||||
m_linebreakerstate = 1;
|
||||
}
|
||||
else {
|
||||
m_linebreakerstate = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3959,6 +3998,23 @@ bool TTrain::Update( double const Deltatime )
|
||||
|
||||
if (DynamicObject->mdKabina)
|
||||
{ // Ra: TODO: odczyty klawiatury/pulpitu nie powinny być uzależnione od istnienia modelu kabiny
|
||||
|
||||
if( ( DynamicObject->Mechanik != nullptr )
|
||||
&& ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI
|
||||
&& ( ( mvOccupied->TrainType == dt_ET40 )
|
||||
|| ( mvOccupied->TrainType == dt_EP05 ) ) ) {
|
||||
// dla ET40 i EU05 automatyczne cofanie nastawnika - i tak nie będzie to działać dobrze...
|
||||
// TODO: remove direct keyboard check, use deltatime to stabilize speed
|
||||
if( ( glfwGetKey( Global.window, GLFW_KEY_KP_ADD ) != GLFW_TRUE )
|
||||
&& ( mvOccupied->MainCtrlPos > mvOccupied->MainCtrlActualPos ) ) {
|
||||
mvOccupied->DecMainCtrl( 1 );
|
||||
}
|
||||
if( ( glfwGetKey( Global.window, GLFW_KEY_KP_SUBTRACT ) != GLFW_TRUE )
|
||||
&& ( mvOccupied->MainCtrlPos < mvOccupied->MainCtrlActualPos ) ) {
|
||||
mvOccupied->IncMainCtrl( 1 ); // Ra 15-01: a to nie miało być tylko cofanie?
|
||||
}
|
||||
}
|
||||
|
||||
tor = DynamicObject->GetTrack(); // McZapkie-180203
|
||||
// McZapkie: predkosc wyswietlana na tachometrze brana jest z obrotow kol
|
||||
float maxtacho = 3;
|
||||
@@ -4443,6 +4499,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
btLampkaNapNastHam.Turn(mvControlled->ActiveDir != 0); // napiecie na nastawniku hamulcowym
|
||||
btLampkaSprezarka.Turn(mvControlled->CompressorFlag); // mutopsitka dziala
|
||||
btLampkaSprezarkaOff.Turn( false == mvControlled->CompressorFlag );
|
||||
btLampkaFuelPumpOff.Turn( false == mvControlled->FuelPump.is_active );
|
||||
// boczniki
|
||||
unsigned char scp; // Ra: dopisałem "unsigned"
|
||||
// Ra: w SU45 boczniki wchodzą na MainCtrlPos, a nie na MainCtrlActualPos
|
||||
@@ -4482,6 +4539,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
btLampkaNadmPrzetw.Turn( false );
|
||||
btLampkaSprezarka.Turn( false );
|
||||
btLampkaSprezarkaOff.Turn( false );
|
||||
btLampkaFuelPumpOff.Turn( false );
|
||||
btLampkaBezoporowa.Turn( false );
|
||||
}
|
||||
if (mvControlled->Signalling == true) {
|
||||
@@ -4883,6 +4941,8 @@ bool TTrain::Update( double const Deltatime )
|
||||
ggCabLightButton.Update();
|
||||
ggCabLightDimButton.Update();
|
||||
ggBatteryButton.Update();
|
||||
|
||||
ggFuelPumpButton.Update();
|
||||
//------
|
||||
pyScreens.update();
|
||||
}
|
||||
@@ -5166,15 +5226,22 @@ TTrain::update_sounds( double const Deltatime ) {
|
||||
volume *= 1 + 0.125 * brakeforceratio;
|
||||
}
|
||||
// scale volume by track quality
|
||||
volume *= ( 20.0 + DynamicObject->MyTrack->iDamageFlag ) / 21;
|
||||
// scale volume with vehicle speed
|
||||
// TBD, TODO: disable the scaling for sounds combined from speed-based samples?
|
||||
// TODO: track quality and/or environment factors as separate subroutine
|
||||
volume *=
|
||||
interpolate(
|
||||
0.0, 1.0,
|
||||
0.8, 1.2,
|
||||
clamp(
|
||||
mvOccupied->Vel / 40.0,
|
||||
DynamicObject->MyTrack->iQualityFlag / 20.0,
|
||||
0.0, 1.0 ) );
|
||||
// for single sample sounds muffle the playback at low speeds
|
||||
if( false == rsRunningNoise.is_combined() ) {
|
||||
volume *=
|
||||
interpolate(
|
||||
0.0, 1.0,
|
||||
clamp(
|
||||
mvOccupied->Vel / 40.0,
|
||||
0.0, 1.0 ) );
|
||||
}
|
||||
|
||||
if( volume > 0.05 ) {
|
||||
rsRunningNoise
|
||||
@@ -5927,6 +5994,8 @@ void TTrain::clear_cab_controls()
|
||||
ggMainGearStatus.Clear();
|
||||
ggIgnitionKey.Clear();
|
||||
|
||||
ggFuelPumpButton.Clear();
|
||||
|
||||
btLampkaPrzetw.Clear();
|
||||
btLampkaPrzetwB.Clear();
|
||||
btLampkaPrzetwBOff.Clear();
|
||||
@@ -5966,6 +6035,7 @@ void TTrain::clear_cab_controls()
|
||||
btLampkaSprezarkaB.Clear();
|
||||
btLampkaSprezarkaOff.Clear();
|
||||
btLampkaSprezarkaBOff.Clear();
|
||||
btLampkaFuelPumpOff.Clear();
|
||||
btLampkaNapNastHam.Clear();
|
||||
btLampkaStycznB.Clear();
|
||||
btLampkaHamowanie1zes.Clear();
|
||||
@@ -6088,9 +6158,14 @@ void TTrain::set_cab_controls() {
|
||||
1.0 :
|
||||
0.0 );
|
||||
// motor overload relay threshold / shunt mode
|
||||
if( mvControlled->Imax == mvControlled->ImaxHi ) {
|
||||
ggMaxCurrentCtrl.PutValue( 1.0 );
|
||||
}
|
||||
ggMaxCurrentCtrl.PutValue(
|
||||
( true == mvControlled->ShuntModeAllow ?
|
||||
( true == mvControlled->ShuntMode ?
|
||||
1.0 :
|
||||
0.0 ) :
|
||||
( mvControlled->Imax == mvControlled->ImaxHi ?
|
||||
1.0 :
|
||||
0.0 ) ) );
|
||||
// lights
|
||||
ggLightsButton.PutValue( mvOccupied->LightsPos - 1 );
|
||||
|
||||
@@ -6185,6 +6260,11 @@ void TTrain::set_cab_controls() {
|
||||
ShowNextCurrent ?
|
||||
1.0 :
|
||||
0.0 );
|
||||
// fuel pump
|
||||
ggFuelPumpButton.PutValue(
|
||||
mvOccupied->FuelPump.is_enabled ?
|
||||
1.0 :
|
||||
0.0 );
|
||||
|
||||
// we reset all indicators, as they're set during the update pass
|
||||
// TODO: when cleaning up break setting indicator state into a separate function, so we can reuse it
|
||||
@@ -6248,6 +6328,7 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
{ "i-compressorb:", btLampkaSprezarkaB },
|
||||
{ "i-compressoroff:", btLampkaSprezarkaOff },
|
||||
{ "i-compressorboff:", btLampkaSprezarkaBOff },
|
||||
{ "i-fuelpumpoff:", btLampkaFuelPumpOff },
|
||||
{ "i-voltbrake:", btLampkaNapNastHam },
|
||||
{ "i-resistorsb:", btLampkaOporyB },
|
||||
{ "i-contactorsb:", btLampkaStycznB },
|
||||
@@ -6348,6 +6429,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "converterlocal_sw:", ggConverterLocalButton },
|
||||
{ "converteroff_sw:", ggConverterOffButton },
|
||||
{ "main_sw:", ggMainButton },
|
||||
{ "fuelpump_sw:", ggFuelPumpButton },
|
||||
{ "radio_sw:", ggRadioButton },
|
||||
{ "radiochannel_sw:", ggRadioChannelSelector },
|
||||
{ "radiochannelprev_sw:", ggRadioChannelPrevious },
|
||||
|
||||
1
Train.h
1
Train.h
@@ -454,6 +454,7 @@ public: // reszta może by?publiczna
|
||||
TButton btLampkaSprezarkaB;
|
||||
TButton btLampkaSprezarkaOff;
|
||||
TButton btLampkaSprezarkaBOff;
|
||||
TButton btLampkaFuelPumpOff;
|
||||
TButton btLampkaBocznik1;
|
||||
TButton btLampkaBocznik2;
|
||||
TButton btLampkaBocznik3;
|
||||
|
||||
13
World.cpp
13
World.cpp
@@ -64,9 +64,11 @@ simulation_time::init() {
|
||||
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
|
||||
::memcpy( m_monthdaycounts, monthdaycounts, sizeof( monthdaycounts ) );
|
||||
|
||||
// potentially adjust scenario clock
|
||||
auto const requestedtime { clamp_circular<int>( m_time.wHour * 60 + m_time.wMinute + Global.ScenarioTimeOffset * 60, 1440 ) };
|
||||
auto const requestedhour { ( requestedtime / 60 ) % 60 };
|
||||
auto const requestedminute { requestedtime % 60 };
|
||||
// cache requested elements, if any
|
||||
WORD const requestedhour = m_time.wHour;
|
||||
WORD const requestedminute = m_time.wMinute;
|
||||
|
||||
#ifdef __linux__
|
||||
timespec ts;
|
||||
@@ -89,10 +91,11 @@ simulation_time::init() {
|
||||
daymonth( m_time.wDay, m_time.wMonth, m_time.wYear, static_cast<WORD>( Global.fMoveLight ) );
|
||||
}
|
||||
|
||||
if( requestedhour != (WORD)-1 ) { m_time.wHour = clamp( requestedhour, static_cast<WORD>( 0 ), static_cast<WORD>( 23 ) ); }
|
||||
if( requestedminute != (WORD)-1 ) { m_time.wMinute = clamp( requestedminute, static_cast<WORD>( 0 ), static_cast<WORD>( 59 ) ); }
|
||||
if( requestedhour != -1 ) { m_time.wHour = static_cast<WORD>( clamp( requestedhour, 0, 23 ) ); }
|
||||
if( requestedminute != -1 ) { m_time.wMinute = static_cast<WORD>( clamp( requestedminute, 0, 59 ) ); }
|
||||
// if the time is taken from the local clock leave the seconds intact, otherwise set them to zero
|
||||
if( ( requestedhour != (WORD)-1 ) || ( requestedminute != (WORD)-1 ) ) {
|
||||
if( ( requestedhour != -1 )
|
||||
|| ( requestedminute != 1 ) ) {
|
||||
m_time.wSecond = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,9 @@ http://mozilla.org/MPL/2.0/.
|
||||
// helper, returns potential path part from provided file name
|
||||
std::string path( std::string const &Filename )
|
||||
{
|
||||
std::string fn = Filename;
|
||||
return (
|
||||
fn.rfind( '/' ) != std::string::npos ?
|
||||
fn.substr( 0, fn.rfind( '/' ) + 1 ) :
|
||||
Filename.rfind( '/' ) != std::string::npos ?
|
||||
Filename.substr( 0, Filename.rfind( '/' ) + 1 ) :
|
||||
"" );
|
||||
}
|
||||
|
||||
@@ -115,6 +114,7 @@ material_manager::create( std::string const &Filename, bool const Loadnow ) {
|
||||
filename.erase( filename.find( '|' ) ); // po | może być nazwa kolejnej tekstury
|
||||
|
||||
erase_extension( filename );
|
||||
|
||||
filename += ".mat";
|
||||
|
||||
// try to locate requested material in the databank
|
||||
|
||||
@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "stdafx.h"
|
||||
#include "mtable.h"
|
||||
#include "World.h"
|
||||
#include "Globals.h"
|
||||
#include "utilities.h"
|
||||
|
||||
double CompareTime(double t1h, double t1m, double t2h, double t2m) /*roznica czasu w minutach*/
|
||||
@@ -520,20 +521,21 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
||||
// NextStationName:=TimeTable[1].StationName;
|
||||
/* TTVmax:=TimeTable[1].vmax; */
|
||||
}
|
||||
if ((iPlus != 0)) // jeżeli jest przesunięcie rozkładu
|
||||
auto const timeoffset { static_cast<int>( Global.ScenarioTimeOffset * 60 ) + iPlus };
|
||||
if( timeoffset != 0.0 ) // jeżeli jest przesunięcie rozkładu
|
||||
{
|
||||
long i_end = StationCount + 1;
|
||||
for (i = 1; i < i_end; ++i) // bez with, bo ciężko się przenosi na C++
|
||||
{
|
||||
if ((TimeTable[i].Ah >= 0))
|
||||
{
|
||||
time = iPlus + TimeTable[i].Ah * 60 + TimeTable[i].Am; // nowe minuty
|
||||
time = clamp_circular( TimeTable[i].Ah * 60 + TimeTable[i].Am + timeoffset, 1440 ); // nowe minuty
|
||||
TimeTable[i].Am = time % 60;
|
||||
TimeTable[i].Ah = (time /*div*/ / 60) % 60;
|
||||
}
|
||||
if ((TimeTable[i].Dh >= 0))
|
||||
{
|
||||
time = iPlus + TimeTable[i].Dh * 60 + TimeTable[i].Dm; // nowe minuty
|
||||
time = clamp_circular( TimeTable[i].Dh * 60 + TimeTable[i].Dm + timeoffset, 1440 ); // nowe minuty
|
||||
TimeTable[i].Dm = time % 60;
|
||||
TimeTable[i].Dh = (time /*div*/ / 60) % 60;
|
||||
}
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
void
|
||||
cStars::init() {
|
||||
|
||||
m_stars = TModelsManager::GetModel( "models/skydome_stars.t3d", false );
|
||||
m_stars = TModelsManager::GetModel( "skydome_stars.t3d", false );
|
||||
}
|
||||
|
||||
@@ -334,3 +334,12 @@ erase_extension( std::string &Filename ) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// potentially replaces backward slashes in provided file path with unix-compatible forward slashes
|
||||
void
|
||||
replace_slashes( std::string &Filename ) {
|
||||
|
||||
std::replace(
|
||||
std::begin( Filename ), std::end( Filename ),
|
||||
'\\', '/' );
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#define szSceneryPath "scenery/"
|
||||
#define szTexturePath "textures/"
|
||||
#define szModelPath "models/"
|
||||
#define szDynamicPath "dynamic/"
|
||||
#define szSoundPath "sounds/"
|
||||
|
||||
#define MAKE_ID4(a,b,c,d) (((std::uint32_t)(d)<<24)|((std::uint32_t)(c)<<16)|((std::uint32_t)(b)<<8)|(std::uint32_t)(a))
|
||||
@@ -183,6 +184,10 @@ std::time_t last_modified( std::string const &Filename );
|
||||
bool
|
||||
erase_extension( std::string &Filename );
|
||||
|
||||
// potentially replaces backward slashes in provided file path with unix-compatible forward slashes
|
||||
void
|
||||
replace_slashes( std::string &Filename );
|
||||
|
||||
template <typename Type_>
|
||||
void SafeDelete( Type_ &Pointer ) {
|
||||
delete Pointer;
|
||||
|
||||
Reference in New Issue
Block a user