mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-21 15:59:18 +02:00
Merge remote-tracking branch 'upstream/master' into utilities-simplification
This commit is contained in:
@@ -1754,6 +1754,8 @@ class TMoverParameters
|
|||||||
bool HasCamshaft{false};
|
bool HasCamshaft{false};
|
||||||
int DynamicBrakeType = 0; /*patrz dbrake_**/
|
int DynamicBrakeType = 0; /*patrz dbrake_**/
|
||||||
int DynamicBrakeAmpmeters = 2; /*liczba amperomierzy przy hamowaniu ED*/
|
int DynamicBrakeAmpmeters = 2; /*liczba amperomierzy przy hamowaniu ED*/
|
||||||
|
bool SplitEDPneumaticBrake = false; /*czy hamulec ED i pneumatyczny pomocniczy są rozdzielone na osobne nastawniki*/
|
||||||
|
int DynamicBrakeCtrlPosNo = 10; /*ilosc pozycji nastawnika hamulca ED (DBPN, domyslnie 10)*/
|
||||||
double DynamicBrakeRes = 5.8; /*rezystancja oporników przy hamowaniu ED*/
|
double DynamicBrakeRes = 5.8; /*rezystancja oporników przy hamowaniu ED*/
|
||||||
double DynamicBrakeRes1 = 5.8; /*rezystancja oporników przy hamowaniu ED - 1 tryb*/
|
double DynamicBrakeRes1 = 5.8; /*rezystancja oporników przy hamowaniu ED - 1 tryb*/
|
||||||
double DynamicBrakeRes2 = 5.8; /*rezystancja oporników przy hamowaniu ED - 2 tryb*/
|
double DynamicBrakeRes2 = 5.8; /*rezystancja oporników przy hamowaniu ED - 2 tryb*/
|
||||||
@@ -2030,6 +2032,7 @@ class TMoverParameters
|
|||||||
int ManualBrakePos = 0; /*nastawa hamulca recznego*/
|
int ManualBrakePos = 0; /*nastawa hamulca recznego*/
|
||||||
double LocalBrakePosA = 0.0; /*nastawa hamulca pomocniczego*/
|
double LocalBrakePosA = 0.0; /*nastawa hamulca pomocniczego*/
|
||||||
double LocalBrakePosAEIM = 0.0; /*pozycja hamulca pomocniczego ep dla asynchronicznych ezt*/
|
double LocalBrakePosAEIM = 0.0; /*pozycja hamulca pomocniczego ep dla asynchronicznych ezt*/
|
||||||
|
double DynamicBrakeCtrlPos = 0.0; /*nastawa nastawnika hamulca elektrodynamicznego (0..1) - aktywne tylko gdy SplitEDPneumaticBrake*/
|
||||||
bool UniversalBrakeButtonActive[3] = {false, false, false}; /* brake button pressed */
|
bool UniversalBrakeButtonActive[3] = {false, false, false}; /* brake button pressed */
|
||||||
/*
|
/*
|
||||||
int BrakeStatus = b_off; //0 - odham, 1 - ham., 2 - uszk., 4 - odluzniacz, 8 - antyposlizg, 16 - uzyte EP, 32 - pozycja R, 64 - powrot z R
|
int BrakeStatus = b_off; //0 - odham, 1 - ham., 2 - uszk., 4 - odluzniacz, 8 - antyposlizg, 16 - uzyte EP, 32 - pozycja R, 64 - powrot z R
|
||||||
@@ -2380,6 +2383,12 @@ class TMoverParameters
|
|||||||
/*! ABu 010205: - skrajne polozenia ham. pomocniczego*/
|
/*! ABu 010205: - skrajne polozenia ham. pomocniczego*/
|
||||||
bool IncManualBrakeLevel(int CtrlSpeed);
|
bool IncManualBrakeLevel(int CtrlSpeed);
|
||||||
bool DecManualBrakeLevel(int CtrlSpeed);
|
bool DecManualBrakeLevel(int CtrlSpeed);
|
||||||
|
/*! oddzielny nastawnik hamulca elektrodynamicznego (gdy SplitEDPneumaticBrake)*/
|
||||||
|
bool IncDynamicBrakeLevel(float const CtrlSpeed);
|
||||||
|
bool DecDynamicBrakeLevel(float const CtrlSpeed);
|
||||||
|
bool DynamicBrakeLevelSet(double Position);
|
||||||
|
double DynamicBrakeRatio(void) const;
|
||||||
|
bool DynamicBrakeAvailable(void) const; /*czy ED dostepny w aktualnym oknie predkosci Vh0..Vh1*/
|
||||||
bool DynamicBrakeSwitch(bool Switch);
|
bool DynamicBrakeSwitch(bool Switch);
|
||||||
bool RadiostopSwitch(bool Switch);
|
bool RadiostopSwitch(bool Switch);
|
||||||
bool AlarmChainSwitch(bool const State);
|
bool AlarmChainSwitch(bool const State);
|
||||||
|
|||||||
@@ -3882,6 +3882,79 @@ bool TMoverParameters::DecLocalBrakeLevel(float const CtrlSpeed)
|
|||||||
return DBL;
|
return DBL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************************
|
||||||
|
// zwiększenie nastawy nastawnika hamulca elektrodynamicznego (DynamicBrakeCtrl)
|
||||||
|
// uzywane gdy SplitEDPneumaticBrake = true
|
||||||
|
// *************************************************************************************************
|
||||||
|
bool TMoverParameters::IncDynamicBrakeLevel(float const CtrlSpeed)
|
||||||
|
{
|
||||||
|
if (false == SplitEDPneumaticBrake)
|
||||||
|
return false;
|
||||||
|
if (DynamicBrakeCtrlPosNo < 1)
|
||||||
|
return false;
|
||||||
|
if (DynamicBrakeCtrlPos < 1.0)
|
||||||
|
{
|
||||||
|
DynamicBrakeCtrlPos = std::min(1.0, DynamicBrakeCtrlPos + (double)CtrlSpeed / (double)DynamicBrakeCtrlPosNo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************************
|
||||||
|
// zmniejszenie nastawy nastawnika hamulca elektrodynamicznego (DynamicBrakeCtrl)
|
||||||
|
// *************************************************************************************************
|
||||||
|
bool TMoverParameters::DecDynamicBrakeLevel(float const CtrlSpeed)
|
||||||
|
{
|
||||||
|
if (false == SplitEDPneumaticBrake)
|
||||||
|
return false;
|
||||||
|
if (DynamicBrakeCtrlPosNo < 1)
|
||||||
|
return false;
|
||||||
|
if (DynamicBrakeCtrlPos > 0.0)
|
||||||
|
{
|
||||||
|
DynamicBrakeCtrlPos = std::max(0.0, DynamicBrakeCtrlPos - (double)CtrlSpeed / (double)DynamicBrakeCtrlPosNo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************************
|
||||||
|
// bezposrednie ustawienie nastawnika hamulca elektrodynamicznego (DynamicBrakeCtrl)
|
||||||
|
// *************************************************************************************************
|
||||||
|
bool TMoverParameters::DynamicBrakeLevelSet(double Position)
|
||||||
|
{
|
||||||
|
if (false == SplitEDPneumaticBrake)
|
||||||
|
return false;
|
||||||
|
DynamicBrakeCtrlPos = clamp(Position, 0.0, 1.0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************************
|
||||||
|
// odczyt nastawy nastawnika hamulca elektrodynamicznego (DynamicBrakeCtrl)
|
||||||
|
// zwraca 0 jezeli SplitEDPneumaticBrake nie jest aktywne (dla zachowania starej logiki)
|
||||||
|
// *************************************************************************************************
|
||||||
|
double TMoverParameters::DynamicBrakeRatio(void) const
|
||||||
|
{
|
||||||
|
if (false == SplitEDPneumaticBrake)
|
||||||
|
return 0.0;
|
||||||
|
return clamp(DynamicBrakeCtrlPos, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// *************************************************************************************************
|
||||||
|
// czy hamulec ED jest aktualnie dostepny w oknie predkosci Vh0..Vh1
|
||||||
|
// *************************************************************************************************
|
||||||
|
bool TMoverParameters::DynamicBrakeAvailable(void) const
|
||||||
|
{
|
||||||
|
double const vh0{eimc[eimc_p_Vh0]};
|
||||||
|
double const vh1{eimc[eimc_p_Vh1]};
|
||||||
|
if (vh1 <= 0.001)
|
||||||
|
{
|
||||||
|
// brak zdefiniowanej strefy - ED dziala zawsze
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// strefa wylaczenia jest definiowana przez Vh0 (minimum); powyzej Vh0 ED dziala
|
||||||
|
return (Vel >= vh0);
|
||||||
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
// Q: 20160711
|
// Q: 20160711
|
||||||
// zwiększenie nastawy hamulca ręcznego
|
// zwiększenie nastawy hamulca ręcznego
|
||||||
@@ -4438,7 +4511,13 @@ void TMoverParameters::UpdatePipePressure(double dt)
|
|||||||
dpLocalValve = LocHandle->GetPF(std::max(lbpa, LocalBrakePosAEIM), Hamulec->GetBCP(), ScndPipePress, dt, 0);
|
dpLocalValve = LocHandle->GetPF(std::max(lbpa, LocalBrakePosAEIM), Hamulec->GetBCP(), ScndPipePress, dt, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dpLocalValve = LocHandle->GetPF(LocalBrakePosAEIM, Hamulec->GetBCP(), ScndPipePress, dt, 0);
|
{
|
||||||
|
// in EIM stock the pneumatic local brake is normally driven only by the MED algorithm
|
||||||
|
// (LocalBrakePosAEIM). When SplitEDPneumaticBrake is active the dedicated LocalBrake
|
||||||
|
// lever should apply pneumatic pressure on the locomotive directly, bypassing MED.
|
||||||
|
double lbpa = SplitEDPneumaticBrake ? LocalBrakePosA : 0.0;
|
||||||
|
dpLocalValve = LocHandle->GetPF(std::max(lbpa, LocalBrakePosAEIM), Hamulec->GetBCP(), ScndPipePress, dt, 0);
|
||||||
|
}
|
||||||
|
|
||||||
LockPipe = PipePress < (LockPipe ? LockPipeOff : LockPipeOn);
|
LockPipe = PipePress < (LockPipe ? LockPipeOff : LockPipeOn);
|
||||||
bool lock_new = (LockPipe && !UnlockPipe && (BrakeCtrlPosR > HandleUnlock)) || ((EmergencyCutsOffHandle) && (EmergencyValveFlow > 0)); // new simple codition based on .fiz
|
bool lock_new = (LockPipe && !UnlockPipe && (BrakeCtrlPosR > HandleUnlock)) || ((EmergencyCutsOffHandle) && (EmergencyValveFlow > 0)); // new simple codition based on .fiz
|
||||||
@@ -6232,14 +6311,19 @@ double TMoverParameters::TractionForce(double dt)
|
|||||||
}
|
}
|
||||||
double edBCP = Hamulec->GetEDBCP();
|
double edBCP = Hamulec->GetEDBCP();
|
||||||
auto const localbrakeactive{(CabOccupied != 0) && (LocHandle->GetCP() > 0.25)};
|
auto const localbrakeactive{(CabOccupied != 0) && (LocHandle->GetCP() > 0.25)};
|
||||||
|
// gdy SplitEDPneumaticBrake jest aktywne, hamulec pomocniczy (LocalBrake) NIE wymusza
|
||||||
|
// zalaczenia hamulca elektrodynamicznego - ED jest sterowany wlasnym nastawnikiem
|
||||||
|
auto const dynbrakectrlactive{SplitEDPneumaticBrake && (DynamicBrakeRatio() > 0.01) && DynamicBrakeAvailable()};
|
||||||
|
auto const localbrakeforED{SplitEDPneumaticBrake ? false : localbrakeactive};
|
||||||
if ((false == Doors.instances[side::left].is_closed) || (false == Doors.instances[side::right].is_closed) ||
|
if ((false == Doors.instances[side::left].is_closed) || (false == Doors.instances[side::right].is_closed) ||
|
||||||
(Doors.permit_needed && (Doors.instances[side::left].open_permit || Doors.instances[side::right].open_permit)))
|
(Doors.permit_needed && (Doors.instances[side::left].open_permit || Doors.instances[side::right].open_permit)))
|
||||||
{
|
{
|
||||||
DynamicBrakeFlag = true;
|
DynamicBrakeFlag = true;
|
||||||
}
|
}
|
||||||
else if (((edBCP < 0.25) && (false == localbrakeactive) && (AnPos < 0.01)) || ((edBCP < 0.25) && (ShuntModeAllow) && (LocalBrakePosA < 0.01)))
|
else if (((edBCP < 0.25) && (false == localbrakeforED) && (false == dynbrakectrlactive) && (AnPos < 0.01)) ||
|
||||||
|
((edBCP < 0.25) && (ShuntModeAllow) && (false == dynbrakectrlactive) && (LocalBrakePosA < 0.01)))
|
||||||
DynamicBrakeFlag = false;
|
DynamicBrakeFlag = false;
|
||||||
else if ((((BrakePress > 0.25) && (edBCP > 0.25) || localbrakeactive)) || (AnPos > 0.02))
|
else if ((((BrakePress > 0.25) && (edBCP > 0.25) || localbrakeforED)) || (AnPos > 0.02) || dynbrakectrlactive)
|
||||||
DynamicBrakeFlag = true;
|
DynamicBrakeFlag = true;
|
||||||
edBCP = Hamulec->GetEDBCP() * eimc[eimc_p_abed]; // stala napedu
|
edBCP = Hamulec->GetEDBCP() * eimc[eimc_p_abed]; // stala napedu
|
||||||
if ((DynamicBrakeFlag))
|
if ((DynamicBrakeFlag))
|
||||||
@@ -6266,8 +6350,21 @@ double TMoverParameters::TractionForce(double dt)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PosRatio = -std::max(std::min(edBCP * 1.0 / MaxBrakePress[0], 1.0), AnPos) * std::max(0.0, std::min(1.0, (Vel - eimc[eimc_p_Vh0]) / (eimc[eimc_p_Vh1] - eimc[eimc_p_Vh0])));
|
// strefa wylaczenia ED (Vh0..Vh1) - mnoznik 0..1 zaleznie od predkosci
|
||||||
eimv[eimv_Fzad] = -std::min(1.0, std::max(LocalBrakeRatio(), edBCP / MaxBrakePress[0]));
|
double const vhRamp = std::max(0.0, std::min(1.0, (Vel - eimc[eimc_p_Vh0]) / (eimc[eimc_p_Vh1] - eimc[eimc_p_Vh0])));
|
||||||
|
if (SplitEDPneumaticBrake)
|
||||||
|
{
|
||||||
|
// w trybie split LocalBrake nie zaleca ED; uzywany jest DynamicBrakeCtrl
|
||||||
|
// oraz zwykle zapotrzebowanie z hamulca zespolonego (edBCP)
|
||||||
|
double const edLeverDemand = DynamicBrakeRatio();
|
||||||
|
PosRatio = -std::max(std::max(edLeverDemand, std::min(edBCP / MaxBrakePress[0], 1.0)), AnPos) * vhRamp;
|
||||||
|
eimv[eimv_Fzad] = -std::min(1.0, std::max(edLeverDemand, edBCP / MaxBrakePress[0]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PosRatio = -std::max(std::min(edBCP * 1.0 / MaxBrakePress[0], 1.0), AnPos) * vhRamp;
|
||||||
|
eimv[eimv_Fzad] = -std::min(1.0, std::max(LocalBrakeRatio(), edBCP / MaxBrakePress[0]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tmp = 5;
|
tmp = 5;
|
||||||
}
|
}
|
||||||
@@ -7230,10 +7327,26 @@ void TMoverParameters::CheckEIMIC(double dt)
|
|||||||
{
|
{
|
||||||
double offset = EIMCtrlAdditionalZeros ? 1.0 : 0.0;
|
double offset = EIMCtrlAdditionalZeros ? 1.0 : 0.0;
|
||||||
double multiplier = (EIMCtrlEmergency ? 1.0 : 0.0) + offset;
|
double multiplier = (EIMCtrlEmergency ? 1.0 : 0.0) + offset;
|
||||||
|
// gdy SplitEDPneumaticBrake jest wlaczone, sterowanie ujemne (hamowanie ED) bierzemy
|
||||||
|
// z osobnego nastawnika DynamicBrakeCtrl, a nie z hamulca pomocniczego (LocalBrake).
|
||||||
|
// Dodatkowo zapotrzebowanie ED jest ograniczone przez strefe Vh0..Vh1: powyzej Vh1 - pelny ED,
|
||||||
|
// pomiedzy Vh1 a Vh0 - liniowe zanikanie, ponizej Vh0 - zerowe (brak hamowania pneumatycznego
|
||||||
|
// jako uzupelnienia, poniewaz LocalBrake jest oddzielny i operuje wylacznie pneumatyka).
|
||||||
|
double brakeDemand = SplitEDPneumaticBrake ? DynamicBrakeRatio() : LocalBrakeRatio();
|
||||||
|
if (SplitEDPneumaticBrake)
|
||||||
|
{
|
||||||
|
double const vh0 = eimc[eimc_p_Vh0];
|
||||||
|
double const vh1 = eimc[eimc_p_Vh1];
|
||||||
|
if (vh1 > vh0 + 0.001)
|
||||||
|
{
|
||||||
|
double const vhRamp = clamp((Vel - vh0) / (vh1 - vh0), 0.0, 1.0);
|
||||||
|
brakeDemand *= vhRamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
switch (EIMCtrlType)
|
switch (EIMCtrlType)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
eimic = (LocalBrakeRatio() > 0.01 ? -LocalBrakeRatio() : eimic_analog > 0.01 ? eimic_analog : (double)MainCtrlPos / (double)MainCtrlPosNo);
|
eimic = (brakeDemand > 0.01 ? -brakeDemand : eimic_analog > 0.01 ? eimic_analog : (double)MainCtrlPos / (double)MainCtrlPosNo);
|
||||||
if (EIMCtrlAdditionalZeros || EIMCtrlEmergency)
|
if (EIMCtrlAdditionalZeros || EIMCtrlEmergency)
|
||||||
{
|
{
|
||||||
if (eimic > 0.001)
|
if (eimic > 0.001)
|
||||||
@@ -7347,7 +7460,9 @@ void TMoverParameters::CheckEIMIC(double dt)
|
|||||||
eimic = 0; // shut off retarder
|
eimic = 0; // shut off retarder
|
||||||
if ((UniCtrlIntegratedBrakeCtrl == false) && (UniCtrlIntegratedLocalBrakeCtrl == false))
|
if ((UniCtrlIntegratedBrakeCtrl == false) && (UniCtrlIntegratedLocalBrakeCtrl == false))
|
||||||
{
|
{
|
||||||
eimic = (LocalBrakeRatio() > 0.01 ? -LocalBrakeRatio() : eimic);
|
// w trybie SplitEDPneumaticBrake hamowanie ED przychodzi z osobnego nastawnika,
|
||||||
|
// LocalBrake operuje wylacznie pneumatycznym hamulcem lokomotywy
|
||||||
|
eimic = (brakeDemand > 0.01 ? -brakeDemand : eimic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (LocHandleTimeTraxx)
|
if (LocHandleTimeTraxx)
|
||||||
@@ -10707,6 +10822,18 @@ void TMoverParameters::LoadFIZ_Cntrl(std::string const &line)
|
|||||||
extract_value(DynamicBrakeAmpmeters, "DBAM", line, "");
|
extract_value(DynamicBrakeAmpmeters, "DBAM", line, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// split ED/pneumatic brake control: when true the local brake operates only on the
|
||||||
|
// pneumatic locomotive cylinder while electrodynamic braking is commanded by a
|
||||||
|
// separate "dynamicbrakectrl" lever (or the negative range of jointctrl).
|
||||||
|
extract_value(SplitEDPneumaticBrake, "SplitEDPneumaticBrake", line, "");
|
||||||
|
// number of stepped positions for the dedicated ED brake controller (default 10)
|
||||||
|
DynamicBrakeCtrlPosNo = 10;
|
||||||
|
extract_value(DynamicBrakeCtrlPosNo, "DBPN", line, "");
|
||||||
|
if (DynamicBrakeCtrlPosNo < 1)
|
||||||
|
{
|
||||||
|
DynamicBrakeCtrlPosNo = 10;
|
||||||
|
}
|
||||||
|
|
||||||
extract_value(MainCtrlPosNo, "MCPN", line, "");
|
extract_value(MainCtrlPosNo, "MCPN", line, "");
|
||||||
extract_value(ScndCtrlPosNo, "SCPN", line, "");
|
extract_value(ScndCtrlPosNo, "SCPN", line, "");
|
||||||
extract_value(ScndInMain, "SCIM", line, "");
|
extract_value(ScndInMain, "SCIM", line, "");
|
||||||
|
|||||||
@@ -319,6 +319,12 @@ int eu07_application::init(int Argc, char *Argv[])
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// configure the OS console according to Globals.ShowSystemConsole.
|
||||||
|
// must run AFTER init_settings (so the ini-loaded value is honoured) and
|
||||||
|
// BEFORE the first WriteLog below (so colored \033[...] sequences emitted
|
||||||
|
// by utilities/Logs.cpp land in a console with VT processing enabled).
|
||||||
|
init_console();
|
||||||
|
|
||||||
WriteLog("Starting MaSzyna rail vehicle simulator (release: " + Global.asVersion + ")");
|
WriteLog("Starting MaSzyna rail vehicle simulator (release: " + Global.asVersion + ")");
|
||||||
WriteLog("For online documentation and additional files refer to: http://eu07.pl");
|
WriteLog("For online documentation and additional files refer to: http://eu07.pl");
|
||||||
WriteLog("Authors: Marcin_EU, McZapkie, ABu, Winger, Tolaris, nbmx, OLO_EU, Bart, Quark-t, "
|
WriteLog("Authors: Marcin_EU, McZapkie, ABu, Winger, Tolaris, nbmx, OLO_EU, Bart, Quark-t, "
|
||||||
@@ -978,6 +984,102 @@ void eu07_application::init_debug()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Honours Globals.ShowSystemConsole (default: true).
|
||||||
|
//
|
||||||
|
// Windows: if the toggle is on, ensure a console is attached (allocate one when
|
||||||
|
// the binary was linked as the WINDOWS subsystem and none is inherited), then
|
||||||
|
// reopen the C stdio streams onto it and turn on ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||||
|
// so the ANSI colour escapes used by utilities/Logs.cpp render correctly.
|
||||||
|
// If the toggle is off, hide the console window (or free an allocated one) so
|
||||||
|
// the GUI launches without a stray cmd window.
|
||||||
|
//
|
||||||
|
// Other platforms: no-op. stdout is the launching terminal (or already detached);
|
||||||
|
// hiding it on Linux/macOS would mean redirecting to /dev/null and is left to the
|
||||||
|
// user's shell (e.g. "./eu07 >/dev/null 2>&1").
|
||||||
|
void eu07_application::init_console()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
HWND consoleWnd = ::GetConsoleWindow();
|
||||||
|
const bool hadConsole = (consoleWnd != nullptr);
|
||||||
|
|
||||||
|
if (Global.ShowSystemConsole)
|
||||||
|
{
|
||||||
|
if (!hadConsole)
|
||||||
|
{
|
||||||
|
// no console inherited (e.g. WINDOWS subsystem build, or launched
|
||||||
|
// detached) -- create one and wire stdio to it so printf in
|
||||||
|
// utilities/Logs.cpp actually reaches the user
|
||||||
|
if (::AllocConsole())
|
||||||
|
{
|
||||||
|
FILE *fp = nullptr;
|
||||||
|
freopen_s(&fp, "CONOUT$", "w", stdout);
|
||||||
|
freopen_s(&fp, "CONOUT$", "w", stderr);
|
||||||
|
freopen_s(&fp, "CONIN$", "r", stdin);
|
||||||
|
// keep C++ streams in sync with the redirected C streams
|
||||||
|
std::ios::sync_with_stdio(true);
|
||||||
|
std::cout.clear();
|
||||||
|
std::cerr.clear();
|
||||||
|
std::clog.clear();
|
||||||
|
std::cin.clear();
|
||||||
|
consoleWnd = ::GetConsoleWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable ANSI virtual-terminal processing so the colour escapes in
|
||||||
|
// utilities/Logs.cpp ("\033[1;37;41m...", "\033[32m...") render as
|
||||||
|
// colours instead of literal garbage on the conhost.
|
||||||
|
//
|
||||||
|
// IMPORTANT: do NOT rely on GetStdHandle(STD_OUTPUT_HANDLE). After
|
||||||
|
// AllocConsole + freopen_s the CRT may have rewired things, and on a
|
||||||
|
// console-subsystem build the std handle can also point to a redirected
|
||||||
|
// pipe/file rather than the actual console screen buffer -- in either
|
||||||
|
// case SetConsoleMode silently fails and the escape bytes leak through
|
||||||
|
// as text ("←[32m" etc). Open CONOUT$ directly to get the real screen
|
||||||
|
// buffer handle, then flip VT on it.
|
||||||
|
auto enable_vt = [](const char *devName) {
|
||||||
|
HANDLE h = ::CreateFileA(
|
||||||
|
devName,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
nullptr,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
0,
|
||||||
|
nullptr);
|
||||||
|
if (h == INVALID_HANDLE_VALUE)
|
||||||
|
return;
|
||||||
|
DWORD mode = 0;
|
||||||
|
if (::GetConsoleMode(h, &mode))
|
||||||
|
{
|
||||||
|
::SetConsoleMode(h, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT);
|
||||||
|
}
|
||||||
|
::CloseHandle(h);
|
||||||
|
};
|
||||||
|
// CONOUT$ is the console's active screen buffer; enabling VT on it
|
||||||
|
// affects everything that ends up being written there, regardless of
|
||||||
|
// which FILE* / std handle the writer used
|
||||||
|
enable_vt("CONOUT$");
|
||||||
|
|
||||||
|
if (consoleWnd)
|
||||||
|
{
|
||||||
|
::ShowWindow(consoleWnd, SW_SHOW);
|
||||||
|
// give the console a recognisable title
|
||||||
|
::SetConsoleTitleA("MaSzyna log");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// user wants no console window -- hide whatever we have
|
||||||
|
if (consoleWnd)
|
||||||
|
{
|
||||||
|
::ShowWindow(consoleWnd, SW_HIDE);
|
||||||
|
}
|
||||||
|
// if we'd allocated one ourselves on a previous run path we'd FreeConsole here,
|
||||||
|
// but on first init the console (if any) was inherited from the launcher and
|
||||||
|
// belongs to it -- just hiding the window is the least-surprising behaviour
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void eu07_application::init_files()
|
void eu07_application::init_files()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ private:
|
|||||||
// methods
|
// methods
|
||||||
bool needs_ogl() const;
|
bool needs_ogl() const;
|
||||||
void init_debug();
|
void init_debug();
|
||||||
|
void init_console();
|
||||||
void init_files();
|
void init_files();
|
||||||
int init_settings( int Argc, char *Argv[] );
|
int init_settings( int Argc, char *Argv[] );
|
||||||
int init_locale();
|
int init_locale();
|
||||||
|
|||||||
@@ -17,11 +17,16 @@ gl::cubemap::~cubemap()
|
|||||||
|
|
||||||
void gl::cubemap::alloc(GLint format, int width, int height, GLenum components, GLenum type)
|
void gl::cubemap::alloc(GLint format, int width, int height, GLenum components, GLenum type)
|
||||||
{
|
{
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, *this);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, *this);
|
||||||
for (GLuint tgt = GL_TEXTURE_CUBE_MAP_POSITIVE_X; tgt <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; tgt++)
|
for (GLuint tgt = GL_TEXTURE_CUBE_MAP_POSITIVE_X; tgt <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; tgt++)
|
||||||
glTexImage2D(tgt, 0, format, width, height, 0, components, type, nullptr);
|
glTexImage2D(tgt, 0, format, width, height, 0, components, type, nullptr);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
// make the cubemap sample-complete with no mipmaps required.
|
||||||
|
// generate_mipmaps() will later override MIN_FILTER once mips actually exist.
|
||||||
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl::cubemap::bind(int unit)
|
void gl::cubemap::bind(int unit)
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ commanddescription_sequence Commands_descriptions = {
|
|||||||
{"mastercontrollerdecrease", command_target::vehicle, command_mode::oneoff},
|
{"mastercontrollerdecrease", command_target::vehicle, command_mode::oneoff},
|
||||||
{"mastercontrollerdecreasefast", command_target::vehicle, command_mode::oneoff},
|
{"mastercontrollerdecreasefast", command_target::vehicle, command_mode::oneoff},
|
||||||
{"mastercontrollerset", command_target::vehicle, command_mode::oneoff},
|
{"mastercontrollerset", command_target::vehicle, command_mode::oneoff},
|
||||||
|
|
||||||
|
{"dynamicbrakecontrollerincrease", command_target::vehicle, command_mode::oneoff},
|
||||||
|
{"dynamicbrakecontrollerdecrease", command_target::vehicle, command_mode::oneoff},
|
||||||
|
{"dynamicbrakecontrollerset", command_target::vehicle, command_mode::oneoff},
|
||||||
|
{"dynamicbrakecontrollerincreasefast", command_target::vehicle, command_mode::oneoff},
|
||||||
|
{"dynamicbrakecontrollerdecreasefast", command_target::vehicle, command_mode::oneoff},
|
||||||
|
|
||||||
{"secondcontrollerincrease", command_target::vehicle, command_mode::oneoff},
|
{"secondcontrollerincrease", command_target::vehicle, command_mode::oneoff},
|
||||||
{"secondcontrollerincreasefast", command_target::vehicle, command_mode::oneoff},
|
{"secondcontrollerincreasefast", command_target::vehicle, command_mode::oneoff},
|
||||||
{"secondcontrollerdecrease", command_target::vehicle, command_mode::oneoff},
|
{"secondcontrollerdecrease", command_target::vehicle, command_mode::oneoff},
|
||||||
@@ -409,6 +416,11 @@ std::unordered_map<std::string, user_command> commandMap = {
|
|||||||
{"mastercontrollerdecrease", user_command::mastercontrollerdecrease},
|
{"mastercontrollerdecrease", user_command::mastercontrollerdecrease},
|
||||||
{"mastercontrollerdecreasefast", user_command::mastercontrollerdecreasefast},
|
{"mastercontrollerdecreasefast", user_command::mastercontrollerdecreasefast},
|
||||||
{"mastercontrollerset", user_command::mastercontrollerset},
|
{"mastercontrollerset", user_command::mastercontrollerset},
|
||||||
|
{"dynamicbrakecontrollerincrease", user_command::dynamicbrakecontrollerincrease},
|
||||||
|
{"dynamicbrakecontrollerdecrease", user_command::dynamicbrakecontrollerdecrease},
|
||||||
|
{"dynamicbrakecontrollerset", user_command::dynamicbrakecontrollerset},
|
||||||
|
{"dynamicbrakecontrollerincreasefast", user_command::dynamicbrakecontrollerincreasefast},
|
||||||
|
{"dynamicbrakecontrollerdecreasefast", user_command::dynamicbrakecontrollerdecreasefast},
|
||||||
{"secondcontrollerincrease", user_command::secondcontrollerincrease},
|
{"secondcontrollerincrease", user_command::secondcontrollerincrease},
|
||||||
{"secondcontrollerincreasefast", user_command::secondcontrollerincreasefast},
|
{"secondcontrollerincreasefast", user_command::secondcontrollerincreasefast},
|
||||||
{"secondcontrollerdecrease", user_command::secondcontrollerdecrease},
|
{"secondcontrollerdecrease", user_command::secondcontrollerdecrease},
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ enum class user_command
|
|||||||
mastercontrollerdecrease,
|
mastercontrollerdecrease,
|
||||||
mastercontrollerdecreasefast,
|
mastercontrollerdecreasefast,
|
||||||
mastercontrollerset,
|
mastercontrollerset,
|
||||||
|
dynamicbrakecontrollerincrease,
|
||||||
|
dynamicbrakecontrollerdecrease,
|
||||||
|
dynamicbrakecontrollerset,
|
||||||
|
dynamicbrakecontrollerincreasefast,
|
||||||
|
dynamicbrakecontrollerdecreasefast,
|
||||||
secondcontrollerincrease,
|
secondcontrollerincrease,
|
||||||
secondcontrollerincreasefast,
|
secondcontrollerincreasefast,
|
||||||
secondcontrollerdecrease,
|
secondcontrollerdecrease,
|
||||||
|
|||||||
@@ -32,6 +32,13 @@ driverkeyboard_input::default_bindings() {
|
|||||||
{ user_command::mastercontrollerdecrease, {GLFW_KEY_KP_SUBTRACT, ""} },
|
{ user_command::mastercontrollerdecrease, {GLFW_KEY_KP_SUBTRACT, ""} },
|
||||||
{ user_command::mastercontrollerdecreasefast, {GLFW_KEY_KP_SUBTRACT | keymodifier::shift, ""} },
|
{ user_command::mastercontrollerdecreasefast, {GLFW_KEY_KP_SUBTRACT | keymodifier::shift, ""} },
|
||||||
// mastercontrollerset,
|
// mastercontrollerset,
|
||||||
|
|
||||||
|
{ user_command::dynamicbrakecontrollerincrease, {GLFW_KEY_KP_3 | keymodifier::control, ""} },
|
||||||
|
{ user_command::dynamicbrakecontrollerdecrease, {GLFW_KEY_KP_9 | keymodifier::control, ""} },
|
||||||
|
// mastercontrollerset,
|
||||||
|
{ user_command::dynamicbrakecontrollerincreasefast, {GLFW_KEY_KP_3 | keymodifier::control | keymodifier::shift, ""} },
|
||||||
|
{ user_command::dynamicbrakecontrollerdecreasefast, {GLFW_KEY_KP_9 | keymodifier::control | keymodifier::shift, ""} },
|
||||||
|
|
||||||
{ user_command::secondcontrollerincrease, {GLFW_KEY_KP_DIVIDE, ""} },
|
{ user_command::secondcontrollerincrease, {GLFW_KEY_KP_DIVIDE, ""} },
|
||||||
{ user_command::secondcontrollerincreasefast, {GLFW_KEY_KP_DIVIDE | keymodifier::shift, ""} },
|
{ user_command::secondcontrollerincreasefast, {GLFW_KEY_KP_DIVIDE | keymodifier::shift, ""} },
|
||||||
{ user_command::secondcontrollerdecrease, {GLFW_KEY_KP_MULTIPLY, ""} },
|
{ user_command::secondcontrollerdecrease, {GLFW_KEY_KP_MULTIPLY, ""} },
|
||||||
|
|||||||
@@ -533,6 +533,9 @@ drivermouse_input::default_bindings() {
|
|||||||
{ "mainctrl:", {
|
{ "mainctrl:", {
|
||||||
user_command::mastercontrollerset,
|
user_command::mastercontrollerset,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
|
{ "dynamicbrakectrl:", {
|
||||||
|
user_command::dynamicbrakecontrollerset,
|
||||||
|
user_command::none } },
|
||||||
{ "scndctrl:", {
|
{ "scndctrl:", {
|
||||||
user_command::secondcontrollerset,
|
user_command::secondcontrollerset,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
|
|||||||
@@ -312,15 +312,37 @@ void python_taskqueue::exit()
|
|||||||
m_condition.notify_all();
|
m_condition.notify_all();
|
||||||
// let them free up their shit before we proceed
|
// let them free up their shit before we proceed
|
||||||
m_workers = {};
|
m_workers = {};
|
||||||
// get rid of the leftover tasks
|
// drop any pending render/upload tasks. the workers are joined at this
|
||||||
// with the workers dead we don't have to worry about concurrent access anymore
|
// point so the locks are strictly defensive, but they cost nothing and
|
||||||
for (auto task : m_tasks.data)
|
// document intent. clearing the deque also actually releases the tasks,
|
||||||
|
// which the previous code did not do (cancel() is a no-op stub).
|
||||||
{
|
{
|
||||||
task->cancel();
|
std::lock_guard<std::mutex> lock(m_tasks.mutex);
|
||||||
|
for (auto &task : m_tasks.data)
|
||||||
|
{
|
||||||
|
task->cancel();
|
||||||
|
}
|
||||||
|
m_tasks.data.clear();
|
||||||
}
|
}
|
||||||
// take a bow
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_uploadtasks.mutex);
|
||||||
|
m_uploadtasks.data.clear();
|
||||||
|
}
|
||||||
|
// reclaim cached python objects while the interpreter is still alive,
|
||||||
|
// so no Py_DECREF lands on a finalized interpreter during later teardown
|
||||||
acquire_lock();
|
acquire_lock();
|
||||||
|
for (auto &entry : m_renderers)
|
||||||
|
{
|
||||||
|
Py_XDECREF(entry.second);
|
||||||
|
}
|
||||||
|
m_renderers.clear();
|
||||||
|
Py_XDECREF(m_stderr);
|
||||||
|
m_stderr = nullptr;
|
||||||
|
Py_XDECREF(m_main);
|
||||||
|
m_main = nullptr;
|
||||||
|
// take a bow
|
||||||
Py_Finalize();
|
Py_Finalize();
|
||||||
|
m_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// adds specified task along with provided collection of data to the work queue. returns true on success
|
// adds specified task along with provided collection of data to the work queue. returns true on success
|
||||||
@@ -518,8 +540,10 @@ void python_taskqueue::run(GLFWwindow *Context, rendertask_sequence &Tasks, uplo
|
|||||||
// TBD, TODO: add some idle time between tasks in case we're on a single thread cpu?
|
// TBD, TODO: add some idle time between tasks in case we're on a single thread cpu?
|
||||||
} while (task != nullptr);
|
} while (task != nullptr);
|
||||||
// if there's nothing left to do wait until there is
|
// if there's nothing left to do wait until there is
|
||||||
// but check every now and then on your own to minimize potential deadlock situations
|
// short timeout: notify_all() in exit() can race with the worker's
|
||||||
Condition.wait_for(std::chrono::seconds(5));
|
// transition into the wait, and the run loop also drives prompt
|
||||||
|
// shutdown checks
|
||||||
|
Condition.wait_for(std::chrono::milliseconds(250));
|
||||||
}
|
}
|
||||||
// clean up thread state data
|
// clean up thread state data
|
||||||
PyEval_AcquireLock();
|
PyEval_AcquireLock();
|
||||||
@@ -527,6 +551,12 @@ void python_taskqueue::run(GLFWwindow *Context, rendertask_sequence &Tasks, uplo
|
|||||||
PyThreadState_Clear(threadstate);
|
PyThreadState_Clear(threadstate);
|
||||||
PyThreadState_Delete(threadstate);
|
PyThreadState_Delete(threadstate);
|
||||||
PyEval_ReleaseLock();
|
PyEval_ReleaseLock();
|
||||||
|
|
||||||
|
// detach the GL context before the worker terminates; some drivers
|
||||||
|
// (NVIDIA on X11, certain Mesa/Wayland configs) hang in process teardown
|
||||||
|
// if a context is still current on a dying thread
|
||||||
|
if (Context)
|
||||||
|
glfwMakeContextCurrent(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void python_taskqueue::update()
|
void python_taskqueue::update()
|
||||||
|
|||||||
@@ -8,6 +8,14 @@ vec3 envmap_color( vec3 normal )
|
|||||||
vec3 refvec = reflect(f_pos.xyz, normal); // view space
|
vec3 refvec = reflect(f_pos.xyz, normal); // view space
|
||||||
refvec = vec3(inv_view * vec4(refvec, 0.0)); // world space
|
refvec = vec3(inv_view * vec4(refvec, 0.0)); // world space
|
||||||
vec3 envcolor = texture(envmap, refvec).rgb;
|
vec3 envcolor = texture(envmap, refvec).rgb;
|
||||||
|
// Sanitize. The env cubemap can briefly contain NaN/Inf after a
|
||||||
|
// reflection-pass regeneration (m_empty_cubemap was bound during the
|
||||||
|
// face render and on NVIDIA can sample as undefined). Without this
|
||||||
|
// guard, a single bad texel propagates through env_reflection in
|
||||||
|
// apply_lights() and produces one-frame black flashes on glossy
|
||||||
|
// (esp. specgloss) surfaces.
|
||||||
|
if (any(isnan(envcolor)) || any(isinf(envcolor))) envcolor = vec3(0.0);
|
||||||
|
envcolor = max(envcolor, vec3(0.0));
|
||||||
#else
|
#else
|
||||||
vec3 envcolor = vec3(0.5);
|
vec3 envcolor = vec3(0.5);
|
||||||
#endif
|
#endif
|
||||||
@@ -21,7 +29,12 @@ vec3 envmap_color_lod(vec3 fragnormal, float lod)
|
|||||||
#if ENVMAP_ENABLED
|
#if ENVMAP_ENABLED
|
||||||
vec3 refvec = reflect(f_pos.xyz, fragnormal); // view space — matches envmap_color exactly
|
vec3 refvec = reflect(f_pos.xyz, fragnormal); // view space — matches envmap_color exactly
|
||||||
refvec = vec3(inv_view * vec4(refvec, 0.0)); // world space — was missing
|
refvec = vec3(inv_view * vec4(refvec, 0.0)); // world space — was missing
|
||||||
return textureLod(envmap, refvec, lod).rgb;
|
vec3 envcolor = textureLod(envmap, refvec, lod).rgb;
|
||||||
|
// See envmap_color() above — same NaN/Inf sanitize, also needed here
|
||||||
|
// because mipmap generation propagates a single NaN texel across the
|
||||||
|
// whole mip chain.
|
||||||
|
if (any(isnan(envcolor)) || any(isinf(envcolor))) envcolor = vec3(0.0);
|
||||||
|
return max(envcolor, vec3(0.0));
|
||||||
#else
|
#else
|
||||||
return vec3(0.5); // was vec3(0.0), match the non-LOD fallback
|
return vec3(0.5); // was vec3(0.0), match the non-LOD fallback
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -46,6 +46,17 @@ vec4 tonemap(vec4 x)
|
|||||||
// with pureWhite=1.0 it collapses to identity (L*(1+L)/(1+L) = L) and
|
// with pureWhite=1.0 it collapses to identity (L*(1+L)/(1+L) = L) and
|
||||||
// just clips HDR>1.0 at the framebuffer -> washed-out / burnt look.
|
// just clips HDR>1.0 at the framebuffer -> washed-out / burnt look.
|
||||||
// ACES gives a smooth highlight shoulder + slight toe contrast.
|
// ACES gives a smooth highlight shoulder + slight toe contrast.
|
||||||
return FBOUT(vec4(ACESFilm(x.rgb), x.a));
|
|
||||||
|
// Last-line-of-defense sanitize. ACESFilm has the form
|
||||||
|
// (x*(a*x+b)) / (x*(c*x+d)+e)
|
||||||
|
// which maps NaN -> NaN and +Inf -> NaN (Inf/Inf). Either turns the
|
||||||
|
// pixel black after framebuffer clamp. A negative HDR input feeds a
|
||||||
|
// negative numerator/denominator and can produce non-physical output
|
||||||
|
// that also looks like a black flash. Clamp to a sensible range
|
||||||
|
// before the curve so a single bad upstream pixel can't escape.
|
||||||
|
vec3 hdr = x.rgb;
|
||||||
|
hdr = mix(hdr, vec3(0.0), vec3(any(isnan(hdr)) || any(isinf(hdr))));
|
||||||
|
hdr = max(hdr, vec3(0.0));
|
||||||
|
return FBOUT(vec4(ACESFilm(hdr), x.a));
|
||||||
//return FBOUT(vec4(reinhard(x.rgb), x.a));
|
//return FBOUT(vec4(reinhard(x.rgb), x.a));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1086,6 +1086,12 @@ bool global_settings::ConfigParseDebug(cParser& Parser, const std::string& token
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (token == "showsystemconsole")
|
||||||
|
{
|
||||||
|
ParseOne(Parser, ShowSystemConsole);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (token == "shakefactor")
|
if (token == "shakefactor")
|
||||||
{
|
{
|
||||||
ParseOne(Parser, ShakingMultiplierBF);
|
ParseOne(Parser, ShakingMultiplierBF);
|
||||||
@@ -1516,6 +1522,7 @@ global_settings::export_as_text( std::ostream &Output ) const {
|
|||||||
export_as_text( Output, "fullphysics", FullPhysics );
|
export_as_text( Output, "fullphysics", FullPhysics );
|
||||||
export_as_text( Output, "debuglog", iWriteLogEnabled );
|
export_as_text( Output, "debuglog", iWriteLogEnabled );
|
||||||
export_as_text( Output, "multiplelogs", MultipleLogs );
|
export_as_text( Output, "multiplelogs", MultipleLogs );
|
||||||
|
export_as_text( Output, "showsystemconsole", ShowSystemConsole );
|
||||||
export_as_text( Output, "logs.filter", DisabledLogTypes );
|
export_as_text( Output, "logs.filter", DisabledLogTypes );
|
||||||
Output
|
Output
|
||||||
<< "mousescale "
|
<< "mousescale "
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ struct global_settings {
|
|||||||
bool priorityLoadText3D{false}; // ladowanie T3D priorytetowo
|
bool priorityLoadText3D{false}; // ladowanie T3D priorytetowo
|
||||||
int iWriteLogEnabled{ 3 }; // maska bitowa: 1-zapis do pliku, 2-okienko, 4-nazwy torów
|
int iWriteLogEnabled{ 3 }; // maska bitowa: 1-zapis do pliku, 2-okienko, 4-nazwy torów
|
||||||
bool MultipleLogs{ false };
|
bool MultipleLogs{ false };
|
||||||
|
bool ShowSystemConsole{ false }; // toggle visibility of the OS console window with log output
|
||||||
unsigned int DisabledLogTypes{ 0 };
|
unsigned int DisabledLogTypes{ 0 };
|
||||||
bool ParserLogIncludes{ true };
|
bool ParserLogIncludes{ true };
|
||||||
// simulation
|
// simulation
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ material_data::assign( std::string const &Replacableskin ) {
|
|||||||
// check for the pipe method first
|
// check for the pipe method first
|
||||||
if( contains( Replacableskin, '|' ) ) {
|
if( contains( Replacableskin, '|' ) ) {
|
||||||
cParser nameparser( Replacableskin );
|
cParser nameparser( Replacableskin );
|
||||||
nameparser.getTokens( 4, true, "|" );
|
nameparser.getTokens( 4, false, "|" );
|
||||||
int skinindex = 0;
|
int skinindex = 0;
|
||||||
std::string texturename; nameparser >> texturename;
|
std::string texturename; nameparser >> texturename;
|
||||||
while( ( texturename != "" ) && ( skinindex < 4 ) ) {
|
while( ( texturename != "" ) && ( skinindex < 4 ) ) {
|
||||||
|
|||||||
19427
vehicle/Train.cpp
19427
vehicle/Train.cpp
File diff suppressed because it is too large
Load Diff
@@ -236,11 +236,19 @@ class TTrain {
|
|||||||
static void OnCommand_aidriverenable( TTrain *Train, command_data const &Command );
|
static void OnCommand_aidriverenable( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_aidriverdisable( TTrain *Train, command_data const &Command );
|
static void OnCommand_aidriverdisable( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_jointcontrollerset( TTrain *Train, command_data const &Command );
|
static void OnCommand_jointcontrollerset( TTrain *Train, command_data const &Command );
|
||||||
|
|
||||||
static void OnCommand_mastercontrollerincrease( TTrain *Train, command_data const &Command );
|
static void OnCommand_mastercontrollerincrease( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_mastercontrollerincreasefast( TTrain *Train, command_data const &Command );
|
static void OnCommand_mastercontrollerincreasefast( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_mastercontrollerdecrease( TTrain *Train, command_data const &Command );
|
static void OnCommand_mastercontrollerdecrease( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data const &Command );
|
static void OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_mastercontrollerset( TTrain *Train, command_data const &Command );
|
static void OnCommand_mastercontrollerset( TTrain *Train, command_data const &Command );
|
||||||
|
|
||||||
|
static void OnCommand_DynamicBrakeControllerIncrease( TTrain *Train, command_data const &Command );
|
||||||
|
static void OnCommand_DynamicBrakeControllerIncreaseFast( TTrain *Train, command_data const &Command );
|
||||||
|
static void OnCommand_DynamicBrakeControllerDecrease( TTrain *Train, command_data const &Command );
|
||||||
|
static void OnCommand_DynamicBrakeControllerDecreaseFast( TTrain *Train, command_data const &Command );
|
||||||
|
static void OnCommand_DynamicBrakeControllerSet( TTrain *Train, command_data const &Command );
|
||||||
|
|
||||||
static void OnCommand_secondcontrollerincrease( TTrain *Train, command_data const &Command );
|
static void OnCommand_secondcontrollerincrease( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_secondcontrollerincreasefast( TTrain *Train, command_data const &Command );
|
static void OnCommand_secondcontrollerincreasefast( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_secondcontrollerdecrease( TTrain *Train, command_data const &Command );
|
static void OnCommand_secondcontrollerdecrease( TTrain *Train, command_data const &Command );
|
||||||
|
|||||||
Reference in New Issue
Block a user