tmj merge

This commit is contained in:
milek7
2018-01-15 14:08:43 +01:00
32 changed files with 1564 additions and 2294 deletions

View File

@@ -31,28 +31,29 @@ void TCamera::Init(vector3 NPos, vector3 NAngle)
Type = (Global::bFreeFly ? tp_Free : tp_Follow);
};
void TCamera::OnCursorMove(double x, double y)
{
// McZapkie-170402: zeby mysz dzialala zawsze if (Type==tp_Follow)
void TCamera::OnCursorMove(double x, double y) {
Yaw -= x;
Pitch -= y;
if (Yaw > M_PI)
while( Yaw > M_PI ) {
Yaw -= 2 * M_PI;
else if (Yaw < -M_PI)
}
while( Yaw < -M_PI ) {
Yaw += 2 * M_PI;
if (Type == tp_Follow) // jeżeli jazda z pojazdem
{
clamp(Pitch, -M_PI_4, M_PI_4); // ograniczenie kąta spoglądania w dół i w górę
}
Pitch -= y;
if (Type == tp_Follow) {
// jeżeli jazda z pojazdem ograniczenie kąta spoglądania w dół i w górę
Pitch = clamp( Pitch, -M_PI_4, M_PI_4 );
}
}
void
bool
TCamera::OnCommand( command_data const &Command ) {
double const walkspeed = 1.0;
double const runspeed = ( DebugModeFlag ? 50.0 : 7.5 );
double const speedmultiplier = ( DebugModeFlag ? 7.5 : 1.0 );
auto const walkspeed { 1.0 };
auto const runspeed { 10.0 };
bool iscameracommand { true };
switch( Command.command ) {
case user_command::viewturn: {
@@ -63,232 +64,75 @@ TCamera::OnCommand( command_data const &Command ) {
break;
}
case user_command::movevector: {
case user_command::movehorizontal:
case user_command::movehorizontalfast: {
auto const movespeed =
( Type == tp_Free ?
runspeed * speedmultiplier :
walkspeed );
auto const movespeed = (
Type == tp_Free ? runspeed :
Type == tp_Follow ? walkspeed :
0.0 );
auto const speedmultiplier = (
( ( Type == tp_Free ) && ( Command.command == user_command::movehorizontalfast ) ) ?
30.0 :
1.0 );
// left-right
double const movex = reinterpret_cast<double const &>( Command.param1 );
if( movex > 0.0 ) {
m_keys.right = true;
m_keys.left = false;
}
else if( movex < 0.0 ) {
m_keys.right = false;
m_keys.left = true;
}
else {
m_keys.right = false;
m_keys.left = false;
}
auto const movexparam { reinterpret_cast<double const &>( Command.param1 ) };
// 2/3rd of the stick range enables walk speed, past that we lerp between walk and run speed
m_moverate.x =
walkspeed
+ ( std::max( 0.0, std::abs( movex ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed );
auto const movex { walkspeed + ( std::max( 0.0, std::abs( movexparam ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed ) };
m_moverate.x = (
movexparam > 0.0 ? movex * speedmultiplier :
movexparam < 0.0 ? -movex * speedmultiplier :
0.0 );
// forward-back
double const movez = reinterpret_cast<double const &>( Command.param2 );
if( movez > 0.0 ) {
m_keys.forward = true;
m_keys.back = false;
}
else if( movez < 0.0 ) {
m_keys.forward = false;
m_keys.back = true;
}
else {
m_keys.forward = false;
m_keys.back = false;
}
m_moverate.z =
walkspeed
+ ( std::max( 0.0, std::abs( movez ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed );
double const movezparam { reinterpret_cast<double const &>( Command.param2 ) };
auto const movez { walkspeed + ( std::max( 0.0, std::abs( movezparam ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed ) };
// NOTE: z-axis is flipped given world coordinate system
m_moverate.z = (
movezparam > 0.0 ? -movez * speedmultiplier :
movezparam < 0.0 ? movez * speedmultiplier :
0.0 );
break;
}
case user_command::moveforward: {
case user_command::movevertical:
case user_command::moveverticalfast: {
auto const movespeed = (
Type == tp_Free ? runspeed * 0.5 :
Type == tp_Follow ? walkspeed :
0.0 );
auto const speedmultiplier = (
( ( Type == tp_Free ) && ( Command.command == user_command::moveverticalfast ) ) ?
10.0 :
1.0 );
// up-down
auto const moveyparam { reinterpret_cast<double const &>( Command.param1 ) };
// 2/3rd of the stick range enables walk speed, past that we lerp between walk and run speed
auto const movey { walkspeed + ( std::max( 0.0, std::abs( moveyparam ) - 0.65 ) / 0.35 ) * ( movespeed - walkspeed ) };
m_moverate.y = (
moveyparam > 0.0 ? movey * speedmultiplier :
moveyparam < 0.0 ? -movey * speedmultiplier :
0.0 );
if( Command.action != GLFW_RELEASE ) {
m_keys.forward = true;
m_moverate.z =
( Type == tp_Free ?
walkspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.forward = false;
}
break;
}
case user_command::moveback: {
default: {
if( Command.action != GLFW_RELEASE ) {
m_keys.back = true;
m_moverate.z =
( Type == tp_Free ?
walkspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.back = false;
}
iscameracommand = false;
break;
}
} // switch
case user_command::moveleft: {
if( Command.action != GLFW_RELEASE ) {
m_keys.left = true;
m_moverate.x =
( Type == tp_Free ?
walkspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.left = false;
}
break;
}
case user_command::moveright: {
if( Command.action != GLFW_RELEASE ) {
m_keys.right = true;
m_moverate.x =
( Type == tp_Free ?
walkspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.right = false;
}
break;
}
case user_command::moveup: {
if( Command.action != GLFW_RELEASE ) {
m_keys.up = true;
m_moverate.y =
( Type == tp_Free ?
walkspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.up = false;
}
break;
}
case user_command::movedown: {
if( Command.action != GLFW_RELEASE ) {
m_keys.down = true;
m_moverate.y =
( Type == tp_Free ?
walkspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.down = false;
}
break;
}
case user_command::moveforwardfast: {
if( Command.action != GLFW_RELEASE ) {
m_keys.forward = true;
m_moverate.z =
( Type == tp_Free ?
runspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.forward = false;
}
break;
}
case user_command::movebackfast: {
if( Command.action != GLFW_RELEASE ) {
m_keys.back = true;
m_moverate.z =
( Type == tp_Free ?
runspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.back = false;
}
break;
}
case user_command::moveleftfast: {
if( Command.action != GLFW_RELEASE ) {
m_keys.left = true;
m_moverate.x =
( Type == tp_Free ?
runspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.left = false;
}
break;
}
case user_command::moverightfast: {
if( Command.action != GLFW_RELEASE ) {
m_keys.right = true;
m_moverate.x =
( Type == tp_Free ?
runspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.right = false;
}
break;
}
case user_command::moveupfast: {
if( Command.action != GLFW_RELEASE ) {
m_keys.up = true;
m_moverate.y =
( Type == tp_Free ?
runspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.up = false;
}
break;
}
case user_command::movedownfast: {
if( Command.action != GLFW_RELEASE ) {
m_keys.down = true;
m_moverate.y =
( Type == tp_Free ?
runspeed * speedmultiplier :
walkspeed );
}
else {
m_keys.down = false;
}
break;
}
}
return iscameracommand;
}
void TCamera::Update()
@@ -309,61 +153,15 @@ void TCamera::Update()
auto const deltatime = Timer::GetDeltaRenderTime(); // czas bez pauzy
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
double a = 0.8; // default (walk) movement speed
if( Type == tp_Free ) {
// when not in the cab the speed modifiers are active
if( Global::shiftState ) { a = 2.5; }
if( Global::ctrlState ) { a *= 10.0; }
}
if( ( Type == tp_Free )
|| ( false == Global::ctrlState ) ) {
// ctrl is used for mirror view, so we ignore the controls when in vehicle if ctrl is pressed
if( Console::Pressed( Global::Keys[ k_MechUp ] ) )
Velocity.y = clamp( Velocity.y + a * 10.0 * deltatime, -a, a );
if( Console::Pressed( Global::Keys[ k_MechDown ] ) )
Velocity.y = clamp( Velocity.y - a * 10.0 * deltatime, -a, a );
// McZapkie-170402: poruszanie i rozgladanie we free takie samo jak w follow
if( Console::Pressed( Global::Keys[ k_MechRight ] ) )
Velocity.x = clamp( Velocity.x + a * 10.0 * deltatime, -a, a );
if( Console::Pressed( Global::Keys[ k_MechLeft ] ) )
Velocity.x = clamp( Velocity.x - a * 10.0 * deltatime, -a, a );
if( Console::Pressed( Global::Keys[ k_MechForward ] ) )
Velocity.z = clamp( Velocity.z - a * 10.0 * deltatime, -a, a );
if( Console::Pressed( Global::Keys[ k_MechBackward ] ) )
Velocity.z = clamp( Velocity.z + a * 10.0 * deltatime, -a, a );
}
#else
/*
m_moverate = 0.8; // default (walk) movement speed
if( Type == tp_Free ) {
// when not in the cab the speed modifiers are active
if( Global::shiftState ) { m_moverate = 2.5; }
if( Global::ctrlState ) { m_moverate *= 10.0; }
}
*/
if( ( Type == tp_Free )
|| ( false == Global::ctrlState )
|| ( true == DebugCameraFlag) ) {
|| ( true == DebugCameraFlag ) ) {
// ctrl is used for mirror view, so we ignore the controls when in vehicle if ctrl is pressed
if( m_keys.up )
Velocity.y = clamp( Velocity.y + m_moverate.y * 10.0 * deltatime, -m_moverate.y, m_moverate.y );
if( m_keys.down )
Velocity.y = clamp( Velocity.y - m_moverate.y * 10.0 * deltatime, -m_moverate.y, m_moverate.y );
// McZapkie-170402: poruszanie i rozgladanie we free takie samo jak w follow
if( m_keys.right )
Velocity.x = clamp( Velocity.x + m_moverate.x * 10.0 * deltatime, -m_moverate.x, m_moverate.x );
if( m_keys.left )
Velocity.x = clamp( Velocity.x - m_moverate.x * 10.0 * deltatime, -m_moverate.x, m_moverate.x );
if( m_keys.forward )
Velocity.z = clamp( Velocity.z - m_moverate.z * 10.0 * deltatime, -m_moverate.z, m_moverate.z );
if( m_keys.back )
Velocity.z = clamp( Velocity.z + m_moverate.z * 10.0 * deltatime, -m_moverate.z, m_moverate.z );
Velocity.x = clamp( Velocity.x + m_moverate.x * 10.0 * deltatime, -std::abs( m_moverate.x ), std::abs( m_moverate.x ) );
Velocity.z = clamp( Velocity.z + m_moverate.z * 10.0 * deltatime, -std::abs( m_moverate.z ), std::abs( m_moverate.z ) );
Velocity.y = clamp( Velocity.y + m_moverate.y * 10.0 * deltatime, -std::abs( m_moverate.y ), std::abs( m_moverate.y ) );
}
#endif
if( ( Type == tp_Free )
|| ( true == DebugCameraFlag ) ) {

View File

@@ -26,15 +26,6 @@ enum TCameraType
class TCamera
{
private:
struct keys {
bool forward{ false };
bool back{ false };
bool left{ false };
bool right{ false };
bool up{ false };
bool down{ false };
bool run{ false };
} m_keys;
glm::dvec3 m_moverate;
public: // McZapkie: potrzebuje do kiwania na boki
@@ -51,7 +42,7 @@ class TCamera
void Reset() {
Pitch = Yaw = Roll = 0; };
void OnCursorMove(double const x, double const y);
void OnCommand( command_data const &Command );
bool OnCommand( command_data const &Command );
void Update();
vector3 GetDirection();
bool SetMatrix(glm::dmat4 &Matrix);

View File

@@ -4527,7 +4527,6 @@ TController::UpdateSituation(double dt) {
AbsAccS /= fMass;
}
AbsAccS_pub = AbsAccS;
AbsAccS_avg = interpolate( AbsAccS_avg, mvOccupied->AccS * iDirection, 0.25 );
#if LOGVELOCITY
// WriteLog("VelDesired="+AnsiString(VelDesired)+",

View File

@@ -209,7 +209,6 @@ public:
double BrakeAccFactor();
double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h)
double fAccThreshold = 0.0; // próg opóźnienia dla zadziałania hamulca
double AbsAccS_avg = 0.0; // averaged out directional acceleration
double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca
double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca
double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca

View File

@@ -1751,10 +1751,11 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
// McZapkie: TypeName musi byc nazwą CHK/MMD pojazdu
if (!MoverParameters->LoadFIZ(asBaseDir))
{ // jak wczytanie CHK się nie uda, to błąd
if (ConversionError == -8)
ErrorLog("Missed file: " + BaseDir + "\\" + Type_Name + ".fiz");
Error("Cannot load dynamic object " + asName + " from:\r\n" + BaseDir + "\\" + Type_Name +
".fiz\r\nError " + to_string(ConversionError));
if (ConversionError == 666)
ErrorLog( "Bad vehicle: failed do locate definition file \"" + BaseDir + "\\" + Type_Name + ".fiz" + "\"" );
else {
ErrorLog( "Bad vehicle: failed to load definition from file \"" + BaseDir + "\\" + Type_Name + ".fiz\" (error " + to_string( ConversionError ) + ")" );
}
return 0.0; // zerowa długość to brak pojazdu
}
bool driveractive = (fVel != 0.0); // jeśli prędkość niezerowa, to aktywujemy ruch
@@ -2966,27 +2967,26 @@ bool TDynamicObject::Update(double dt, double dt1)
}
}
auto axleindex { 0 };
for( auto &axle : m_axlesounds ) {
axle.distance -= dDOMoveLen * Sign( dDOMoveLen );
if( axle.distance < 0 ) {
axle.distance += dRailLength;
/*
// McZapkie-040302
if( i == iAxles - 1 ) {
rsStukot[ 0 ].stop();
MoverParameters->AccV += 0.5 * GetVelocity() / ( 1 + MoverParameters->Vmax );
}
else {
rsStukot[ i + 1 ].stop();
}
if( i == 1 ) {
MoverParameters->AccV -= 0.5 * GetVelocity() / ( 1 + MoverParameters->Vmax );
}
*/
if( MoverParameters->Vel > 2.5 ) {
axle.clatter.gain( volume ).play();
// crude bump simulation, drop down on even axles, move back up on the odd ones
MoverParameters->AccVert +=
interpolate(
0.25, 0.50,
clamp(
GetVelocity() / ( 1 + MoverParameters->Vmax ),
0.0, 1.0 ) )
* ( ( axleindex % 2 ) != 0 ?
1 :
-1 );
}
}
++axleindex;
}
}
}
@@ -3495,7 +3495,7 @@ void TDynamicObject::RenderSounds() {
if( MoverParameters->ConverterFlag ) {
frequency = (
MoverParameters->EngineType == ElectricSeriesMotor ?
MoverParameters->Voltage / ( MoverParameters->NominalVoltage * MoverParameters->RList[ MoverParameters->RlistSize ].Mn ) :
( MoverParameters->RunningTraction.TractionVoltage / MoverParameters->NominalVoltage ) * MoverParameters->RList[ MoverParameters->RlistSize ].Mn :
1.0 );
frequency = sConverter.m_frequencyoffset + sConverter.m_frequencyfactor * frequency;
sConverter
@@ -3610,21 +3610,22 @@ void TDynamicObject::RenderSounds() {
}
// McZapkie-280302 - pisk mocno zacisnietych hamulcow
if( //( false == MoverParameters->SlippingWheels ) &&
( MoverParameters->UnitBrakeForce > rsPisk.m_amplitudefactor )
&& ( MoverParameters->Vel > 2.5 ) ) {
if( MoverParameters->Vel > 2.5 ) {
rsPisk
.gain( MoverParameters->UnitBrakeForce / ( rsPisk.m_amplitudefactor + 1 ) + rsPisk.m_amplitudeoffset )
.play( sound_flags::exclusive | sound_flags::looping );
volume = rsPisk.m_amplitudeoffset + interpolate( -1.0, 1.0, brakeforceratio ) * rsPisk.m_amplitudefactor;
if( volume > 0.075 ) {
rsPisk
.gain( volume )
.play( sound_flags::exclusive | sound_flags::looping );
}
}
else {
// don't stop the sound too abruptly
volume = std::max( 0.0, rsPisk.gain() - ( rsPisk.gain() * 2.5 * dt ) );
rsPisk.gain( volume );
if( volume < 0.05 ) {
rsPisk.stop();
}
}
if( volume < 0.05 ) {
rsPisk.stop();
}
// other sounds
@@ -3771,24 +3772,6 @@ void TDynamicObject::RenderSounds() {
// McZapkie! - to wazne - SoundFlag wystawiane jest przez moje moduly
// gdy zachodza pewne wydarzenia komentowane dzwiekiem.
if( TestFlag( MoverParameters->SoundFlag, sound::relay ) ) {
// przekaznik - gdy bezpiecznik, automatyczny rozruch itp
if( true == TestFlag( MoverParameters->SoundFlag, sound::parallel ) ) {
if( TestFlag( MoverParameters->SoundFlag, sound::loud ) )
m_powertrainsounds.dsbWejscie_na_bezoporow.play();
else
m_powertrainsounds.motor_parallel.play();
}
else {
m_powertrainsounds.motor_relay
.gain(
true == TestFlag( MoverParameters->SoundFlag, sound::loud ) ?
1.0f :
0.8f )
.play();
}
}
if( TestFlag( MoverParameters->SoundFlag, sound::pneumatic ) ) {
// pneumatic relay
dsbPneumaticRelay
@@ -3798,7 +3781,6 @@ void TDynamicObject::RenderSounds() {
0.8f )
.play();
}
// couplers
int couplerindex { 0 };
for( auto &couplersounds : m_couplersounds ) {
@@ -4581,6 +4563,12 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
m_powertrainsounds.engine.m_amplitudefactor /= amplitudedivisor;
}
else if( token == "dieselinc:" ) {
// dzwiek przy wlazeniu na obroty woodwarda
m_powertrainsounds.engine_revving.deserialize( parser, sound_type::single, sound_parameters::range );
m_powertrainsounds.engine_revving.owner( this );
}
else if( ( token == "tractionmotor:" )
&& ( MoverParameters->Power > 0 ) ) {
// plik z dzwiekiem silnika, mnozniki i ofsety amp. i czest.
@@ -4620,6 +4608,11 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
rsPisk.deserialize( parser, sound_type::single, sound_parameters::range | sound_parameters::amplitude );
rsPisk.owner( this );
if( rsPisk.m_amplitudefactor > 10.f ) {
// HACK: convert old style activation point threshold to the new, regular amplitude adjustment system
rsPisk.m_amplitudefactor = 1.f;
rsPisk.m_amplitudeoffset = 0.f;
}
rsPisk.m_amplitudeoffset *= ( 105.f - Random( 10.f ) ) / 100.f;
}
@@ -4643,12 +4636,6 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
rsDerailment.owner( this );
}
else if( token == "dieselinc:" ) {
// dzwiek przy wlazeniu na obroty woodwarda
m_powertrainsounds.engine_revving.deserialize( parser, sound_type::single, sound_parameters::range );
m_powertrainsounds.engine_revving.owner( this );
}
else if( token == "curve:" ) {
rscurve.deserialize( parser, sound_type::single, sound_parameters::range );
rscurve.owner( this );
@@ -4805,10 +4792,10 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
m_powertrainsounds.motor_relay.deserialize( parser, sound_type::single );
m_powertrainsounds.motor_relay.owner( this );
}
else if( token == "pneumaticrelay:" ) {
// wylaczniki pneumatyczne:
dsbPneumaticRelay.deserialize( parser, sound_type::single );
dsbPneumaticRelay.owner( this );
else if( token == "shuntfield:" ) {
// styczniki itp:
m_powertrainsounds.motor_shuntfield.deserialize( parser, sound_type::single );
m_powertrainsounds.motor_shuntfield.owner( this );
}
else if( token == "wejscie_na_bezoporow:" ) {
// hunter-111211: wydzielenie wejscia na bezoporowa i na drugi uklad do pliku
@@ -4819,6 +4806,11 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
m_powertrainsounds.motor_parallel.deserialize( parser, sound_type::single );
m_powertrainsounds.motor_parallel.owner( this );
}
else if( token == "pneumaticrelay:" ) {
// wylaczniki pneumatyczne:
dsbPneumaticRelay.deserialize( parser, sound_type::single );
dsbPneumaticRelay.owner( this );
}
// braking sounds
else if( token == "brakesound:" ) {
// hamowanie zwykle:
@@ -5580,8 +5572,14 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
}
engine_revs_last = Vehicle.enrot * 60;
if( false == engine_revving.is_combined() ) {
// if the sound comes with multiple samples we reuse rpm-based calculation from the engine
frequency = engine_revving.m_frequencyoffset + engine_revving.m_frequencyfactor * 1.0;
}
if( enginerevvolume > 0.02 ) {
engine_revving
.pitch( frequency )
.gain( enginerevvolume )
.play( sound_flags::exclusive | sound_flags::looping );
}
@@ -5757,6 +5755,50 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
motor.stop();
}
auto const soundflags { Vehicle.SoundFlag };
if( TestFlag( soundflags, sound::relay ) ) {
// przekaznik - gdy bezpiecznik, automatyczny rozruch itp
if( true == TestFlag( soundflags, sound::shuntfield ) ) {
// shunt field
motor_shuntfield
.pitch(
true == motor_shuntfield.is_combined() ?
Vehicle.ScndCtrlActualPos * 0.01f :
motor_shuntfield.m_frequencyoffset + 1.f * motor_shuntfield.m_frequencyfactor )
.gain(
motor_shuntfield.m_amplitudeoffset + (
true == TestFlag( soundflags, sound::loud ) ?
1.0f :
0.8f )
* motor_shuntfield.m_amplitudefactor )
.play();
}
else if( true == TestFlag( soundflags, sound::parallel ) ) {
// parallel mode
if( TestFlag( soundflags, sound::loud ) ) {
dsbWejscie_na_bezoporow.play();
}
else {
motor_parallel.play();
}
}
else {
// series mode
motor_relay
.pitch(
true == motor_relay.is_combined() ?
Vehicle.MainCtrlActualPos * 0.01f :
motor_relay.m_frequencyoffset + 1.f * motor_relay.m_frequencyfactor )
.gain(
motor_relay.m_amplitudeoffset + (
true == TestFlag( soundflags, sound::loud ) ?
1.0f :
0.8f )
* motor_relay.m_amplitudefactor )
.play();
}
}
if( ( Vehicle.EngineType == ElectricSeriesMotor )
|| ( Vehicle.EngineType == ElectricInductionMotor ) ) {
@@ -5778,7 +5820,6 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
}
}
if( Vehicle.TrainType == dt_ET40 ) {
if( Vehicle.Vel > 0.1 ) {
transmission

View File

@@ -290,6 +290,7 @@ private:
sound_source motor_relay { sound_placement::engine };
sound_source dsbWejscie_na_bezoporow { sound_placement::engine }; // moved from cab
sound_source motor_parallel { sound_placement::engine }; // moved from cab
sound_source motor_shuntfield { sound_placement::engine };
sound_source rsWentylator { sound_placement::engine }; // McZapkie-030302
sound_source engine { sound_placement::engine }; // generally diesel engine
sound_source engine_ignition { sound_placement::engine }; // moved from cab

View File

@@ -1034,12 +1034,12 @@ event_manager::CheckQuery() {
static_cast<int>( m_workevent->Params[ 1 ].asdouble ) );
}
else {
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive );
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive | sound_flags::event );
}
break;
}
case -1: {
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive | sound_flags::looping );
m_workevent->Params[ 9 ].tsTextSound->play( sound_flags::exclusive | sound_flags::looping | sound_flags::event );
break;
}
default: {

View File

@@ -1013,28 +1013,11 @@ void TTranscripts::AddLine(std::string const &txt, float show, float hide, bool
}
*/
};
void TTranscripts::Add(std::string const &txt, float len, bool backgorund)
void TTranscripts::Add(std::string const &txt, bool backgorund)
{ // dodanie tekstów, długość dźwięku, czy istotne
if (true == txt.empty())
return; // pusty tekst
/*
int i = 0, j = int(0.5 + 10.0 * len); //[0.1s]
if (*txt == '[')
{ // powinny być dwa nawiasy
while (*++txt ? *txt != ']' : false)
if ((*txt >= '0') && (*txt <= '9'))
i = 10 * i + int(*txt - '0'); // pierwsza liczba aż do ]
if (*txt ? *++txt == '[' : false)
{
j = 0; // drugi nawias określa czas zakończenia wyświetlania
while (*++txt ? *txt != ']' : false)
if ((*txt >= '0') && (*txt <= '9'))
j = 10 * j + int(*txt - '0'); // druga liczba aż do ]
if (*txt)
++txt; // pominięcie drugiego ]
}
}
*/
std::string asciitext{ txt }; win1250_to_ascii( asciitext ); // TODO: launch relevant conversion table based on language
cParser parser( asciitext );
while( true == parser.getTokens( 3, false, "[]\n" ) ) {
@@ -1051,7 +1034,7 @@ void TTranscripts::Add(std::string const &txt, float len, bool backgorund)
std::string transcript; parser >> transcript;
while( false == transcript.empty() ) {
WriteLog( "Transcript text with no display/hide times: \"" + transcript + "\"" );
// WriteLog( "Transcript text with no display/hide times: \"" + transcript + "\"" );
AddLine( transcript, 0.0, 0.12 * transcript.size(), false );
transcript = ""; parser >> transcript;
}

View File

@@ -133,7 +133,7 @@ private:
~TTranscripts();
void AddLine(std::string const &txt, float show, float hide, bool it);
// dodanie tekstów, długość dźwięku, czy istotne
void Add(std::string const &txt, float len, bool background = false);
void Add(std::string const &txt, bool background = false);
// usuwanie niepotrzebnych (ok. 10 razy na sekundę)
void Update();
};

View File

@@ -204,7 +204,8 @@ enum sound {
bufferclash = 0x4,
relay = 0x10,
parallel = 0x20,
pneumatic = 0x40
shuntfield = 0x40,
pneumatic = 0x80
};
//szczególne typy pojazdów (inna obsługa) dla zmiennej TrainType
@@ -769,6 +770,31 @@ public:
double dizel_minVelfullengage = 0.0; /*najmniejsza predkosc przy jezdzie ze sprzeglem bez poslizgu*/
double dizel_AIM = 1.0; /*moment bezwladnosci walu itp*/
double dizel_engageDia = 0.5; double dizel_engageMaxForce = 6000.0; double dizel_engagefriction = 0.5; /*parametry sprzegla*/
double engagedownspeed = 0.9;
double engageupspeed = 0.5;
/*parametry przetwornika momentu*/
bool hydro_TC = false; /*obecnosc hydraulicznego przetwornika momentu*/
double hydro_TC_TMMax = 2.0; /*maksymalne wzmocnienie momentu*/
double hydro_TC_CouplingPoint = 0.85; /*wzgledna predkosc zasprzeglenia*/
double hydro_TC_LockupTorque = 3000.0; /*moment graniczny sprzegla blokujacego*/
double hydro_TC_LockupRate = 1.0; /*szybkosc zalaczania sprzegla blokujacego*/
double hydro_TC_UnlockRate = 1.0; /*szybkosc rozlaczania sprzegla blokujacego*/
double hydro_TC_FillRateInc = 1.0; /*szybkosc napelniania sprzegla*/
double hydro_TC_FillRateDec = 1.0; /*szybkosc oprozniania sprzegla*/
double hydro_TC_TorqueInIn = 4.5; /*stala momentu proporcjonalnego do kwadratu obrotow wejsciowych*/
double hydro_TC_TorqueInOut = 0.0; /*stala momentu proporcjonalnego do roznica obrotow wejsciowych i wyjsciowych*/
double hydro_TC_TorqueOutOut = 0.0; /*stala momentu proporcjonalnego do kwadratu obrotow wyjsciowych*/
double hydro_TC_LockupSpeed = 1.0; /*prog predkosci zalaczania sprzegla blokujacego*/
double hydro_TC_UnlockSpeed = 1.0; /*prog predkosci rozlaczania sprzegla blokujacego*/
/*parametry retardera*/
bool hydro_R = false; /*obecnosc retardera*/
int hydro_R_Placement = 0; /*umiejscowienie retardera: 0 - za skrzynia biegow, 1 - miedzy przetwornikiem a biegami, 2 - przed skrzynia biegow */
double hydro_R_TorqueInIn = 1.0; /*stala momentu proporcjonalnego do kwadratu obrotow wejsciowych*/
double hydro_R_MaxTorque = 1.0; /*maksymalny moment retardera*/
double hydro_R_MaxPower = 1.0; /*maksymalna moc retardera - ogranicza moment*/
double hydro_R_FillRateInc = 1.0; /*szybkosc napelniania sprzegla*/
double hydro_R_FillRateDec = 1.0; /*szybkosc oprozniania sprzegla*/
double hydro_R_MinVel = 1.0; /*minimalna predkosc, przy ktorej retarder dziala*/
/*- dla lokomotyw spalinowo-elektrycznych -*/
double AnPos = 0.0; // pozycja sterowania dokladnego (analogowego)
bool AnalogCtrl = false; //
@@ -824,8 +850,9 @@ public:
double V = 0.0; //predkosc w [m/s] względem sprzęgów (dodania gdy jedzie w stronę 0)
double Vel = 0.0; //moduł prędkości w [km/h], używany przez AI
double AccS = 0.0; //efektywne przyspieszenie styczne w [m/s^2] (wszystkie siły)
double AccN = 0.0; //przyspieszenie normalne w [m/s^2]
double AccV = 0.0;
double AccSVBased {}; // tangential acceleration calculated from velocity change
double AccN = 0.0; // przyspieszenie normalne w [m/s^2]
double AccVert = 0.0; // vertical acceleration
double nrot = 0.0;
double WheelFlat = 0.0;
/*! rotacja kol [obr/s]*/
@@ -957,6 +984,24 @@ public:
double dizel_automaticgearstatus = 0.0; /*0 - bez zmiany, -1 zmiana na nizszy +1 zmiana na wyzszy*/
bool dizel_enginestart = false; /*czy trwa rozruch silnika*/
double dizel_engagedeltaomega = 0.0; /*roznica predkosci katowych tarcz sprzegla*/
double dizel_n_old = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
double dizel_Torque = 0.0; /*poredkosc na potrzeby obliczen sprzegiel*/
/* - zmienne dla przetowrnika momentu */
double hydro_TC_Fill = 0.0; /*napelnienie*/
bool hydro_TC_Lockup = false; /*zapiecie sprzegla*/
double hydro_TC_TorqueIn = 0.0; /*moment*/
double hydro_TC_TorqueOut = 0.0; /*moment*/
double hydro_TC_TMRatio = 1.0; /*aktualne przelozenie momentu*/
double hydro_TC_Request = 0.0; /*zadanie sily*/
double hydro_TC_nIn = 0.0; /*predkosc obrotowa walu wejsciowego*/
double hydro_TC_nOut = 0.0; /*predkosc obrotowa walu wyjsciowego*/
/* - zmienne dla przetowrnika momentu */
double hydro_R_Fill = 0.0; /*napelnienie*/
double hydro_R_Torque = 0.0; /*moment*/
double hydro_R_Request = 0.0; /*zadanie sily hamowania*/
double hydro_R_n = 0.0; /*predkosc obrotowa retardera*/
/*- zmienne dla lokomotyw z silnikami indukcyjnymi -*/
double eimv[21];

View File

@@ -1115,7 +1115,6 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
{
const double Vepsilon = 1e-5;
const double Aepsilon = 1e-3; // ASBSpeed=0.8;
double Vprev, AccSprev, d;
// T_MoverParameters::ComputeMovement(dt, dt1, Shape, Track, ElectricTraction, NewLoc, NewRot);
// // najpierw kawalek z funkcji w pliku mover.pas
@@ -1259,12 +1258,13 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
if (dL == 0) // oblicz przesuniecie}
{
Vprev = V;
AccSprev = AccS;
// dt:=ActualTime-LastUpdatedTime; //przyrost czasu
auto const AccSprev { AccS };
// przyspieszenie styczne
AccS = (FTotal / TotalMass + AccSprev) /
2.0; // prawo Newtona ale z wygladzaniem (średnia z poprzednim)
AccS = interpolate(
AccSprev,
FTotal / TotalMass,
0.5 );
// clamp( dt * 3.0, 0.0, 1.0 ) ); // prawo Newtona ale z wygladzaniem (średnia z poprzednim)
if (TestFlag(DamageFlag, dtrain_out))
AccS = -Sign(V) * g * 1; // random(0.0, 0.1)
@@ -1275,7 +1275,29 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
else
AccN = g * Shape.dHrail / TrackW;
// velocity change
auto const Vprev { V };
V += ( 3.0 * AccS - AccSprev ) * dt / 2.0; // przyrost predkosci
if( ( V * Vprev <= 0 )
&& ( std::abs( FStand ) > std::abs( FTrain ) ) ) {
// tlumienie predkosci przy hamowaniu
// zahamowany
V = 0;
}
// tangential acceleration, from velocity change
AccSVBased = interpolate(
AccSVBased,
( V - Vprev ) / dt,
clamp( dt * 3.0, 0.0, 1.0 ) );
// vertical acceleration
AccVert = (
std::abs( AccVert ) < 0.01 ?
0.0 :
AccVert * 0.5 );
// szarpanie
/*
#ifdef EU07_USE_FUZZYLOGIC
if( FuzzyLogic( ( 10.0 + Track.DamageFlag ) * Mass * Vel / Vmax, 500000.0, p_accn ) ) {
// Ra: czemu tu masa bez ładunku?
@@ -1287,7 +1309,7 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
if (AccV > 1.0)
AccN += (7.0 - Random(5)) * (100.0 + Track.DamageFlag / 2.0) * AccV / 2000.0;
*/
// wykolejanie na luku oraz z braku szyn
if (TestFlag(CategoryFlag, 1))
{
@@ -1322,22 +1344,14 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
Mains = false;
DerailReason = 4; // Ra: powód wykolejenia: nieodpowiednia trajektoria
}
V += (3.0 * AccS - AccSprev) * dt / 2.0; // przyrost predkosci
if (TestFlag(DamageFlag, dtrain_out))
if (Vel < 1)
{
V = 0;
AccS = 0;
}
if ((V * Vprev <= 0) && (abs(FStand) > abs(FTrain))) // tlumienie predkosci przy hamowaniu
{ // zahamowany
V = 0;
// AccS:=0; //Ra 2014-03: ale siła grawitacji działa, więc nie może być zerowe
if( ( true == TestFlag( DamageFlag, dtrain_out ) )
&& ( Vel < 1.0 ) ) {
V = 0.0;
AccS = 0.0;
}
// { dL:=(V+AccS*dt/2)*dt; //przyrost dlugosci czyli
// przesuniecie
// dL:=(V+AccS*dt/2)*dt;
// przyrost dlugosci czyli przesuniecie
dL = (3.0 * V - Vprev) * dt / 2.0; // metoda Adamsa-Bashfortha}
// ale jesli jest kolizja (zas. zach. pedu) to...}
for (int b = 0; b < 2; b++)
@@ -1349,10 +1363,11 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
if (Power > 1.0) // w rozrządczym nie (jest błąd w FIZ!) - Ra 2014-07: teraz we wszystkich
UpdatePantVolume(dt); // Ra 2014-07: obsługa zbiornika rozrządu oraz pantografów
if (EngineType == WheelsDriven)
d = (double)CabNo * dL; // na chwile dla testu
else
d = dL;
auto const d { (
EngineType == WheelsDriven ?
dL * CabNo : // na chwile dla testu
dL ) };
DistCounter += fabs(dL) / 1000.0;
dL = 0;
@@ -1413,6 +1428,7 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
// if (Vel>10) and (not DebugmodeFlag) then
if (!DebugModeFlag)
SecuritySystemCheck(dt1);
return d;
};
@@ -1424,7 +1440,6 @@ double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape
TTrackParam &Track, const TLocation &NewLoc,
TRotation &NewRot)
{
double Vprev, AccSprev, d;
int b;
// T_MoverParameters::FastComputeMovement(dt, Shape, Track, NewLoc, NewRot);
@@ -1436,76 +1451,40 @@ double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape
if (dL == 0) // oblicz przesuniecie
{
Vprev = V;
AccSprev = AccS;
// dt =ActualTime-LastUpdatedTime; //przyrost czasu
auto const AccSprev { AccS };
// przyspieszenie styczne
AccS = (FTotal / TotalMass + AccSprev) /
2.0; // prawo Newtona ale z wygladzaniem (średnia z poprzednim)
AccS = interpolate(
AccSprev,
FTotal / TotalMass,
0.5 );
// clamp( dt * 3.0, 0.0, 1.0 ) ); // prawo Newtona ale z wygladzaniem (średnia z poprzednim)
if (TestFlag(DamageFlag, dtrain_out))
AccS = -Sign(V) * g * 1; // * random(0.0, 0.1)
// przyspieszenie normalne}
// if Abs(Shape.R)>0.01 then
// AccN:=SQR(V)/Shape.R+g*Shape.dHrail/TrackW
// else AccN:=g*Shape.dHrail/TrackW;
// szarpanie}
#ifdef EU07_USE_FUZZYLOGIC
if( FuzzyLogic( ( 10.0 + Track.DamageFlag ) * Mass * Vel / Vmax, 500000.0, p_accn ) ) {
// Ra: czemu tu masa bez ładunku?
AccV /= ( 2.0 * 0.95 + 2.0 * Random() * 0.1 ); // 95-105% of base modifier (2.0)
}
else
#endif
AccV = AccV / 2.0;
// simple mode skips calculation of normal acceleration
if (AccV > 1.0)
AccN += (7.0 - Random(5)) * (100.0 + Track.DamageFlag / 2.0) * AccV / 2000.0;
// {wykolejanie na luku oraz z braku szyn}
// if TestFlag(CategoryFlag,1) then
// begin
// if FuzzyLogic((AccN/g)*(1+0.1*(Track.DamageFlag and
// dtrack_freerail)),TrackW/Dim.H,1)
// or TestFlag(Track.DamageFlag,dtrack_norail) then
// if SetFlag(DamageFlag,dtrain_out) then
// begin
// EventFlag:=true;
// MainS:=false;
// RunningShape.R:=0;
// end;
// {wykolejanie na poszerzeniu toru}
// if FuzzyLogic(Abs(Track.Width-TrackW),TrackW/10,1) then
// if SetFlag(DamageFlag,dtrain_out) then
// begin
// EventFlag:=true;
// MainS:=false;
// RunningShape.R:=0;
// end;
// end;
// {wykolejanie wkutek niezgodnosci kategorii toru i pojazdu}
// if not TestFlag(RunningTrack.CategoryFlag,CategoryFlag) then
// if SetFlag(DamageFlag,dtrain_out) then
// begin
// EventFlag:=true;
// MainS:=false;
// end;
V += (3.0 * AccS - AccSprev) * dt / 2.0; // przyrost predkosci
if (TestFlag(DamageFlag, dtrain_out))
if (Vel < 1)
{
V = 0;
AccS = 0; // Ra 2014-03: ale siła grawitacji działa, więc nie może być zerowe
}
if ((V * Vprev <= 0) && (abs(FStand) > abs(FTrain))) // tlumienie predkosci przy hamowaniu
{ // zahamowany}
// velocity change
auto const Vprev { V };
V += ( 3.0 * AccS - AccSprev ) * dt / 2.0; // przyrost predkosci
if( ( V * Vprev <= 0 )
&& ( std::abs( FStand ) > std::abs( FTrain ) ) ) {
// tlumienie predkosci przy hamowaniu
// zahamowany
V = 0;
AccS = 0;
}
// simple mode skips calculation of tangential acceleration
// simple mode skips calculation of vertical acceleration
AccVert = 0.0;
if( ( true == TestFlag( DamageFlag, dtrain_out ) )
&& ( Vel < 1.0 ) ) {
V = 0.0;
AccS = 0.0;
}
dL = (3.0 * V - Vprev) * dt / 2.0; // metoda Adamsa-Bashfortha
// ale jesli jest kolizja (zas. zach. pedu) to...
for (b = 0; b < 2; b++)
@@ -1515,10 +1494,12 @@ double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape
// QQQ
if (Power > 1.0) // w rozrządczym nie (jest błąd w FIZ!)
UpdatePantVolume(dt); // Ra 2014-07: obsługa zbiornika rozrządu oraz pantografów
if (EngineType == WheelsDriven)
d = (double)CabNo * dL; // na chwile dla testu
else
d = dL;
auto const d { (
EngineType == WheelsDriven ?
dL * CabNo : // na chwile dla testu
dL ) };
DistCounter += fabs(dL) / 1000.0;
dL = 0;
@@ -1552,6 +1533,7 @@ double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape
if ((BrakeSlippingTimer > 0.8) && (ASBType != 128)) // ASBSpeed=0.8
Hamulec->ASB(0);
BrakeSlippingTimer += dt;
return d;
};
@@ -3743,12 +3725,12 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
|| ( ( Couplers[ side::rear ].CouplingFlag & ctrain_power ) == ctrain_power ) ) ) {
// potem ulepszyc! pantogtrafy!
Voltage =
std::max(
RunningTraction.TractionVoltage,
std::max(
RunningTraction.TractionVoltage,
#ifdef EU07_USE_OLD_HVCOUPLERS
std::max( HVCouplers[side::front][hvcoupler::voltage], HVCouplers[side::rear][hvcoupler::voltage] ) );
std::max( HVCouplers[side::front][hvcoupler::voltage], HVCouplers[side::rear][hvcoupler::voltage] ) );
#else
std::max( Couplers[ side::front ].power_high.voltage, Couplers[ side::rear ].power_high.voltage ) );
std::max( Couplers[ side::front ].power_high.voltage, Couplers[ side::rear ].power_high.voltage ) );
#endif
}
else {
@@ -4190,43 +4172,59 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt)
// *************************************************************************************************
double TMoverParameters::TractionForce(double dt)
{
double PosRatio, dmoment, dtrans, tmp;// , tmpV;
int i;
double PosRatio, dmoment, dtrans, tmp;
Ft = 0;
dtrans = 0;
dmoment = 0;
// tmpV =Abs(nrot * WheelDiameter / 2);
// youBy
if (EngineType == DieselElectric)
{
tmp = DElist[MainCtrlPos].RPM / 60.0;
if ((Heating) && (HeatingPower > 0) && (MainCtrlPosNo > MainCtrlPos))
{
i = MainCtrlPosNo;
while (DElist[i - 2].RPM / 60.0 > tmp)
i--;
tmp = DElist[i].RPM / 60.0;
}
switch( EngineType ) {
case DieselElectric: {
if( true == ConverterFlag ) {
// NOTE: converter is currently a stand-in for a fuel pump
tmp = DElist[ MainCtrlPos ].RPM / 60.0;
if (enrot != tmp * int(ConverterFlag))
if (abs(tmp * int(ConverterFlag) - enrot) < 0.001)
enrot = tmp * int(ConverterFlag);
else if ((enrot < DElist[0].RPM * 0.01) && (ConverterFlag))
enrot += (tmp * int(ConverterFlag) - enrot) * dt / 5.0;
if( ( true == Heating )
&& ( HeatingPower > 0 )
&& ( MainCtrlPosNo > MainCtrlPos ) ) {
int i = MainCtrlPosNo;
while( DElist[ i - 2 ].RPM / 60.0 > tmp ) {
--i;
}
tmp = DElist[ i ].RPM / 60.0;
}
}
else {
tmp = 0.0;
}
if( enrot != tmp ) {
enrot = clamp(
enrot + ( dt / 1.25 ) * ( // TODO: equivalent of dizel_aim instead of fixed inertia
enrot < tmp ?
1.0 :
-2.0 ), // NOTE: revolutions drop faster than they rise, maybe? TBD: maybe not
0.0, std::max( tmp, enrot ) );
if( std::abs( tmp - enrot ) < 0.001 ) {
enrot = tmp;
}
}
break;
}
case DieselEngine: {
if( ShuntMode ) // dodatkowa przekładnia np. dla 2Ls150
dtrans = AnPos * Transmision.Ratio * MotorParam[ ScndCtrlActualPos ].mIsat;
else
enrot += (tmp * int(ConverterFlag) - enrot) * 1.5 * dt;
}
else if (EngineType != DieselEngine)
enrot = Transmision.Ratio * nrot;
else // dla DieselEngine
{
if (ShuntMode) // dodatkowa przekładnia np. dla 2Ls150
dtrans = AnPos * Transmision.Ratio * MotorParam[ScndCtrlActualPos].mIsat;
else
dtrans = Transmision.Ratio * MotorParam[ScndCtrlActualPos].mIsat;
dmoment = dizel_Momentum(dizel_fill, dtrans * nrot * ActiveDir, dt); // oblicza tez
// enrot
dtrans = Transmision.Ratio * MotorParam[ ScndCtrlActualPos ].mIsat;
dmoment = dizel_Momentum( dizel_fill, dtrans * nrot * ActiveDir, dt ); // oblicza tez enrot
break;
}
default: {
enrot = Transmision.Ratio * nrot;
break;
}
}
eAngle += enrot * dt;
@@ -4251,7 +4249,7 @@ double TMoverParameters::TractionForce(double dt)
&& ( ( std::abs( eimv[ eimv_If ] ) > 1.0 )
|| ( tmpV > 0.1 ) ) ) {
i = 0;
int i = 0;
while( ( i < RlistSize - 1 )
&& ( DElist[ i + 1 ].RPM < tmpV ) ) {
++i;
@@ -4423,7 +4421,7 @@ double TMoverParameters::TractionForce(double dt)
if (MainCtrlPos > 1)
dmoment -=
dizel_Mstand * (0.2 * enrot / dizel_nmax); // dodatkowe opory z powodu sprezarki}
Mm = dizel_engage * dmoment;
Mm = dmoment; //bylo * dizel_engage
Mw = Mm * dtrans; // dmoment i dtrans policzone przy okazji enginerotation
Fw = Mw * 2.0 / WheelDiameter / NPoweredAxles;
Ft = Fw * NPoweredAxles; // sila trakcyjna
@@ -4604,25 +4602,20 @@ double TMoverParameters::TractionForce(double dt)
case 45:
{
if( ( ScndCtrlPos < ScndCtrlPosNo )
&& ( MainCtrlPos >= 10 ) ) {
if( ScndCtrlPos == 0 ) {
if( Im < MPTRelay[ ScndCtrlPos ].Iup ) {
++ScndCtrlPos;
}
&& ( MainCtrlPos >= 11 ) ) {
if( Im < MPTRelay[ ScndCtrlPos ].Iup ) {
++ScndCtrlPos;
}
else {
if( Vel > MPTRelay[ ScndCtrlPos ].Iup ) {
++ScndCtrlPos;
}
// check for cases where the speed drops below threshold for level 2 or 3
if( ( ScndCtrlPos > 1 )
&& ( Vel < MPTRelay[ ScndCtrlPos - 1 ].Idown ) ) {
--ScndCtrlPos;
}
// check for cases where the speed drops below threshold for level 2 or 3
if( ( ScndCtrlPos > 1 )
&& ( Vel < MPTRelay[ ScndCtrlPos - 1 ].Idown ) ) {
--ScndCtrlPos;
}
}
// malenie
if( ( ScndCtrlPos > 0 ) && ( MainCtrlPos < 10 ) ) {
if( ( ScndCtrlPos > 0 ) && ( MainCtrlPos < 11 ) ) {
if( ScndCtrlPos == 1 ) {
if( Im > MPTRelay[ ScndCtrlPos - 1 ].Idown ) {
--ScndCtrlPos;
@@ -4635,19 +4628,26 @@ double TMoverParameters::TractionForce(double dt)
}
}
// 3rd level drops with master controller at position lower than 10...
if( MainCtrlPos < 10 ) {
if( MainCtrlPos < 11 ) {
ScndCtrlPos = std::min( 2, ScndCtrlPos );
}
// ...and below position 7 field shunt drops altogether
if( MainCtrlPos < 7 ) {
if( MainCtrlPos < 8 ) {
ScndCtrlPos = 0;
}
/*
// crude woodward approximation; difference between rpm for consecutive positions is ~5%
// so we get full throttle until ~half way between desired and previous position, or zero on rpm reduction
auto const woodward { clamp(
( DElist[ MainCtrlPos ].RPM / ( enrot * 60.0 ) - 1.0 ) * 50.0,
0.0, 1.0 ) };
*/
break;
}
case 46:
{
// wzrastanie
if( ( MainCtrlPos >= 10 )
if( ( MainCtrlPos >= 12 )
&& ( ScndCtrlPos < ScndCtrlPosNo ) ) {
if( ( ScndCtrlPos ) % 2 == 0 ) {
if( ( MPTRelay[ ScndCtrlPos ].Iup > Im ) ) {
@@ -4662,24 +4662,27 @@ double TMoverParameters::TractionForce(double dt)
}
}
// malenie
if( ( MainCtrlPos < 10 )
if( ( MainCtrlPos < 12 )
&& ( ScndCtrlPos > 0 ) ) {
if( ( ScndCtrlPos ) % 2 == 0 ) {
if( ( MPTRelay[ ScndCtrlPos ].Idown < Im ) ) {
--ScndCtrlPos;
if( Vel < 50.0 ) {
// above 50 km/h already active shunt field can be maintained until lower controller setting
if( ( ScndCtrlPos ) % 2 == 0 ) {
if( ( MPTRelay[ ScndCtrlPos ].Idown < Im ) ) {
--ScndCtrlPos;
}
}
}
else {
if( ( MPTRelay[ ScndCtrlPos + 1 ].Idown < Im )
&& ( MPTRelay[ ScndCtrlPos ].Idown > Vel ) ) {
--ScndCtrlPos;
else {
if( ( MPTRelay[ ScndCtrlPos + 1 ].Idown < Im )
&& ( MPTRelay[ ScndCtrlPos ].Idown > Vel ) ) {
--ScndCtrlPos;
}
}
}
}
if( MainCtrlPos < 10 ) {
if( MainCtrlPos < 11 ) {
ScndCtrlPos = std::min( 2, ScndCtrlPos );
}
if( MainCtrlPos < 7 ) {
if( MainCtrlPos < 8 ) {
ScndCtrlPos = 0;
}
break;
@@ -4890,7 +4893,7 @@ double TMoverParameters::TractionForce(double dt)
dizel_fill = 0;
EnginePower = 0;
{
for (i = 0; i < 21; i++)
for (int i = 0; i < 21; ++i)
eimv[i] = 0;
}
Hamulec->SetED(0);
@@ -5207,7 +5210,8 @@ bool TMoverParameters::AutoRelayCheck(void)
{
if ((LastRelayTime > CtrlDelay) && (ARFASI2))
{
ScndCtrlActualPos++;
++ScndCtrlActualPos;
SetFlag( SoundFlag, sound::shuntfield );
OK = true;
}
}
@@ -5215,7 +5219,8 @@ bool TMoverParameters::AutoRelayCheck(void)
{
if ((LastRelayTime > CtrlDownDelay) && (TrainType != dt_EZT))
{
ScndCtrlActualPos--;
--ScndCtrlActualPos;
SetFlag( SoundFlag, sound::shuntfield );
OK = true;
}
}
@@ -5243,7 +5248,7 @@ bool TMoverParameters::AutoRelayCheck(void)
&& ( MainCtrlPos != MainCtrlPosNo )
&& ( FastSerialCircuit == 1 ) ) {
MainCtrlActualPos++;
++MainCtrlActualPos;
// MainCtrlActualPos:=MainCtrlPos; //hunter-111012:
// szybkie wchodzenie na bezoporowa (303E)
OK = true;
@@ -5258,7 +5263,7 @@ bool TMoverParameters::AutoRelayCheck(void)
(DelayCtrlFlag))) // et22 z walem grupowym
if (!DelayCtrlFlag) // najpierw przejscie
{
MainCtrlActualPos++;
++MainCtrlActualPos;
DelayCtrlFlag = true; // tryb przejscia
OK = true;
}
@@ -5272,7 +5277,7 @@ bool TMoverParameters::AutoRelayCheck(void)
;
else // nie ET22 z wałem grupowym
{
MainCtrlActualPos++;
++MainCtrlActualPos;
OK = true;
}
//---------
@@ -5296,7 +5301,7 @@ bool TMoverParameters::AutoRelayCheck(void)
if ((RList[MainCtrlPos].R == 0) && (MainCtrlPos > 0) &&
(!(MainCtrlPos == MainCtrlPosNo)) && (FastSerialCircuit == 1))
{
MainCtrlActualPos--;
--MainCtrlActualPos;
// MainCtrlActualPos:=MainCtrlPos; //hunter-111012:
// szybkie wchodzenie na bezoporowa (303E)
OK = true;
@@ -5306,13 +5311,12 @@ bool TMoverParameters::AutoRelayCheck(void)
{
if (TrainType != dt_EZT) // tutaj powinien być tryb sterowania wałem
{
MainCtrlActualPos--;
--MainCtrlActualPos;
OK = true;
}
if (MainCtrlActualPos > 0) // hunter-111211: poprawki
if (RList[MainCtrlActualPos].R ==
0) // dzwieki schodzenia z bezoporowej}
{
if (RList[MainCtrlActualPos].R == 0) {
// dzwieki schodzenia z bezoporowej}
SetFlag(SoundFlag, sound::parallel);
}
}
@@ -5321,7 +5325,8 @@ bool TMoverParameters::AutoRelayCheck(void)
{
if (LastRelayTime > CtrlDownDelay)
{
ScndCtrlActualPos--; // boczniki nie dzialaja na poz. oporowych
--ScndCtrlActualPos; // boczniki nie dzialaja na poz. oporowych
SetFlag( SoundFlag, sound::shuntfield );
OK = true;
}
}
@@ -5352,45 +5357,61 @@ bool TMoverParameters::AutoRelayCheck(void)
else
DelayCtrlFlag = false;
if ((!StLinFlag) && ((MainCtrlActualPos > 0) || (ScndCtrlActualPos > 0)))
if ((TrainType == dt_EZT) && (CoupledCtrl)) // EN57 wal jednokierunkowy calosciowy
{
if (MainCtrlActualPos == 1)
{
MainCtrlActualPos = 0;
OK = true;
}
else if (LastRelayTime > CtrlDownDelay)
{
if (MainCtrlActualPos < RlistSize)
MainCtrlActualPos++; // dojdz do konca
else if (ScndCtrlActualPos < ScndCtrlPosNo)
ScndCtrlActualPos++; // potem boki
else
{ // i sie przewroc na koniec
if( ( false == StLinFlag )
&& ( ( MainCtrlActualPos > 0 )
|| ( ScndCtrlActualPos > 0 ) ) ) {
if( true == CoupledCtrl ) {
if( TrainType == dt_EZT ) {
// EN57 wal jednokierunkowy calosciowy
if( MainCtrlActualPos == 1 ) {
MainCtrlActualPos = 0;
ScndCtrlActualPos = 0;
OK = true;
}
else {
if( LastRelayTime > CtrlDownDelay ) {
if( MainCtrlActualPos < RlistSize ) {
// dojdz do konca
++MainCtrlActualPos;
}
else if( ScndCtrlActualPos < ScndCtrlPosNo ) {
// potem boki
++ScndCtrlActualPos;
SetFlag( SoundFlag, sound::shuntfield );
}
else {
// i sie przewroc na koniec
MainCtrlActualPos = 0;
ScndCtrlActualPos = 0;
}
OK = true;
}
}
}
else {
// wal kulakowy dwukierunkowy
if( LastRelayTime > CtrlDownDelay ) {
if( ScndCtrlActualPos > 0 ) {
--ScndCtrlActualPos;
SetFlag( SoundFlag, sound::shuntfield );
}
else {
--MainCtrlActualPos;
}
OK = true;
}
OK = true;
}
}
else if (CoupledCtrl) // wal kulakowy dwukierunkowy
{
if (LastRelayTime > CtrlDownDelay)
{
if (ScndCtrlActualPos > 0)
ScndCtrlActualPos--;
else
MainCtrlActualPos--;
OK = true;
}
}
else
{
else {
MainCtrlActualPos = 0;
ScndCtrlActualPos = 0;
OK = true;
}
}
}
if (OK)
LastRelayTime = 0;
@@ -5527,8 +5548,6 @@ bool TMoverParameters::dizel_EngageSwitch(double state)
// *************************************************************************************************
bool TMoverParameters::dizel_EngageChange(double dt)
{
const double engagedownspeed = 0.9;
const double engageupspeed = 0.5;
double engagespeed = 0; // OK:boolean;
bool DEC;
@@ -5568,7 +5587,7 @@ bool TMoverParameters::dizel_AutoGearCheck(void)
OK = false;
if (MotorParam[ScndCtrlActualPos].AutoSwitch && Mains)
{
if (RList[MainCtrlPos].Mn == 0)
if ((RList[MainCtrlPos].Mn == 0)&&(!hydro_TC))
{
if (dizel_engagestate > 0)
dizel_EngageSwitch(0);
@@ -5617,7 +5636,10 @@ bool TMoverParameters::dizel_AutoGearCheck(void)
dizel_EngageSwitch(1.0);
break;
default:
dizel_EngageSwitch(0.0);
if (hydro_TC && hydro_TC_Fill>0.01)
dizel_EngageSwitch(1.0);
else
dizel_EngageSwitch(0.0);
}
else
dizel_EngageSwitch(0.0);
@@ -5646,7 +5668,7 @@ bool TMoverParameters::dizel_Update(double dt)
enrot = std::max(
enrot,
0.1 * ( // TODO: dac zaleznie od temperatury i baterii
0.35 * ( // TODO: dac zaleznie od temperatury i baterii
EngineType == DieselEngine ?
dizel_nmin :
DElist[ 0 ].RPM / 60.0 ) );
@@ -5673,9 +5695,9 @@ double TMoverParameters::dizel_fillcheck(int mcp)
nreg = 0;
if (Mains && (MainCtrlPosNo > 0))
{
if (dizel_enginestart &&
(LastSwitchingTime >= 0.9 * InitialCtrlDelay)) // wzbogacenie przy rozruchu
realfill = 1;
if (dizel_enginestart &&
(LastSwitchingTime >= 0.9 * InitialCtrlDelay)) // wzbogacenie przy rozruchu
realfill = 1;
else
realfill = RList[mcp].R; // napelnienie zalezne od MainCtrlPos
if (dizel_nmax_cutoff > 0)
@@ -5687,7 +5709,7 @@ double TMoverParameters::dizel_fillcheck(int mcp)
nreg = dizel_nmin;
break;
case 2:
if (dizel_automaticgearstatus == 0)
if ((dizel_automaticgearstatus == 0)&&(true/*(!hydro_TC) || (dizel_engage>dizel_fill)*/))
nreg = dizel_nmax;
else
nreg = dizel_nmin;
@@ -5695,12 +5717,18 @@ double TMoverParameters::dizel_fillcheck(int mcp)
default:
realfill = 0; // sluczaj
}
if (enrot > nreg)
/*if (enrot > nreg)
realfill = realfill * (3.9 - 3.0 * abs(enrot) / nreg);
if (enrot > dizel_nmax_cutoff)
realfill = realfill * (9.8 - 9.0 * abs(enrot) / dizel_nmax_cutoff);
if (enrot < dizel_nmin)
realfill = realfill * (1.0 + (dizel_nmin - abs(enrot)) / dizel_nmin);
realfill = realfill * (1.0 + (dizel_nmin - abs(enrot)) / dizel_nmin);*/
if (enrot > nreg) //nad predkoscia regulatora zeruj dawke
realfill = 0;
if (enrot < nreg) //pod predkoscia regulatora dawka zadana
realfill = realfill;
if ((enrot < dizel_nmin * 0.98)&&(RList[mcp].R>0.001)) //jesli ponizej biegu jalowego i niezerowa dawka, to dawaj pelna
realfill = 1;
}
}
if (realfill < 0)
@@ -5716,11 +5744,17 @@ double TMoverParameters::dizel_fillcheck(int mcp)
// *************************************************************************************************
double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
{ // liczy moment sily wytwarzany przez silnik spalinowy}
double Moment = 0, enMoment = 0, eps = 0, newn = 0, friction = 0;
double Moment = 0, enMoment = 0, gearMoment = 0, eps = 0, newn = 0, friction = 0, neps = 0;
double TorqueH = 0, TorqueL = 0, TorqueC = 0;
n = n * CabNo;
if (MotorParam[ScndCtrlActualPos].mIsat < 0.001)
n = enrot;
friction = dizel_engagefriction;
hydro_TC_nIn = enrot; //wal wejsciowy przetwornika momentu
hydro_TC_nOut = dizel_n_old; //wal wyjsciowy przetwornika momentu
neps = (n - dizel_n_old) / dt; //przyspieszenie katowe walu wejsciowego skrzyni biegow
if( enrot > 0 ) {
// Moment = dizel_Mmax * dizel_fill - ( dizel_Mmax - dizel_Mnmax * dizel_fill ) * sqr( enrot / ( dizel_nmax - dizel_nMmax * dizel_fill ) ) - dizel_Mstand; // Q: zamieniam SQR() na sqr()
Moment = ( dizel_Mmax - ( dizel_Mmax - dizel_Mnmax ) * square( ( enrot - dizel_nMmax ) / ( dizel_nMmax - dizel_nmax ) ) ) * dizel_fill - dizel_Mstand;
}
else {
@@ -5731,43 +5765,126 @@ double TMoverParameters::dizel_Momentum(double dizel_fill, double n, double dt)
// wstrzymywanie przy malych obrotach
Moment -= dizel_Mstand;
}
//!! abs
if (abs(abs(n) - enrot) < 0.1)
{
if ((Moment) > (dizel_engageMaxForce * dizel_engage * dizel_engageDia * friction *
2)) // zerwanie przyczepnosci sprzegla
enrot += dt * Moment / dizel_AIM;
else
{
dizel_engagedeltaomega = 0;
enrot = abs(n); // jest przyczepnosc tarcz
}
}
else
{
if ((enrot == 0) && (Moment < 0))
newn = 0;
else
{
//!! abs
dizel_engagedeltaomega = enrot - n; // sliganie tarcz
enMoment = Moment -
Sign(dizel_engagedeltaomega) * dizel_engageMaxForce * dizel_engage *
dizel_engageDia * friction;
Moment = Sign(dizel_engagedeltaomega) * dizel_engageMaxForce * dizel_engage *
dizel_engageDia * friction;
dizel_engagedeltaomega = abs(enrot - abs(n));
eps = enMoment / dizel_AIM;
newn = enrot + eps * dt;
if ((newn * enrot <= 0) && (eps * enrot < 0))
newn = 0;
}
enrot = newn;
}
if ((enrot == 0) && (!dizel_enginestart))
Mains = false;
if (true == dizel_enginestart)
Moment += dizel_Mstand / (0.3 + std::max(0.0, enrot/dizel_nmin)); //rozrusznik
return Moment;
dizel_Torque = Moment;
if (hydro_TC) //jesli przetwornik momentu
{
//napelnianie przetwornika
if ((MainCtrlPos > 0) && (Mains) && (enrot>dizel_nmin*0.9))
hydro_TC_Fill += hydro_TC_FillRateInc * dt;
//oproznianie przetwornika
if (((MainCtrlPos == 0) && (Vel<3))
|| (!Mains)
|| (enrot<dizel_nmin*0.8))
hydro_TC_Fill -= hydro_TC_FillRateDec * dt;
//obcinanie zakresu
hydro_TC_Fill = clamp(hydro_TC_Fill, 0.0, 1.0);
//blokowanie sprzegla blokującego
if ((Vel > hydro_TC_LockupSpeed) && (Mains) && (enrot > 0.9 * dizel_nmin) && (MainCtrlPos>0))
hydro_TC_LockupRate += hydro_TC_FillRateInc*dt;
//luzowanie sprzegla blokujacego
if ((Vel < (MainCtrlPos>0 ? hydro_TC_LockupSpeed : hydro_TC_UnlockSpeed)) || (!Mains) || (enrot < 0.8 * dizel_nmin))
hydro_TC_LockupRate -= hydro_TC_FillRateDec*dt;
//obcinanie zakresu
hydro_TC_LockupRate = clamp(hydro_TC_LockupRate, 0.0, 1.0);
}
else
{
hydro_TC_Fill = 0.0;
hydro_TC_LockupRate = 0.0;
}
//obliczanie momentow poszczegolnych sprzegiel
//sprzeglo glowne (skrzynia biegow)
TorqueC = dizel_engageMaxForce * dizel_engage * dizel_engageDia * friction;
if (hydro_TC) //jesli hydro
{
double HydroTorque = 0;
HydroTorque += hydro_TC_nIn * hydro_TC_nIn * hydro_TC_TorqueInIn;
HydroTorque += (hydro_TC_nIn - hydro_TC_nOut) * hydro_TC_TorqueInOut;
HydroTorque += hydro_TC_nOut * hydro_TC_nOut * hydro_TC_TorqueOutOut;
double nOut2In = hydro_TC_nOut / std::max(0.01, hydro_TC_nIn);
if (nOut2In < hydro_TC_CouplingPoint)
{
hydro_TC_TMRatio = 1 + (hydro_TC_TMMax - 1) * square(1 - nOut2In / hydro_TC_CouplingPoint);
hydro_TC_TorqueIn = HydroTorque * hydro_TC_Fill;
hydro_TC_TorqueOut = HydroTorque * hydro_TC_Fill * hydro_TC_TMRatio;
}
else
{
hydro_TC_TMRatio = (1 - nOut2In) / (1 - hydro_TC_CouplingPoint);
hydro_TC_TorqueIn = HydroTorque * hydro_TC_Fill * hydro_TC_TMRatio;
hydro_TC_TorqueOut = HydroTorque * hydro_TC_Fill * hydro_TC_TMRatio;
}
TorqueH = hydro_TC_TorqueOut;
TorqueL = hydro_TC_LockupTorque * hydro_TC_LockupRate;
}
else
{
TorqueH = 0; //brak przetwornika oznacza brak momentu
TorqueL = 1 + TorqueC * 2; //zabezpieczenie, polaczenie trwale
}
//sprawdzanie dociskow poszczegolnych sprzegiel
if (abs(Moment) > Min0R(TorqueC, TorqueL + abs(hydro_TC_TorqueIn)) || (abs(dizel_n_old - enrot) > 0.1)) //slizga sie z powodu roznic predkosci albo przekroczenia momentu
{
dizel_engagedeltaomega = enrot - dizel_n_old;
if (TorqueC > TorqueL)
{
if (TorqueC > TorqueL + abs(TorqueH))
{
hydro_TC_nOut = n;
gearMoment = TorqueL + abs(TorqueH) * sign(dizel_engagedeltaomega);
enMoment = Moment - (TorqueL + abs(hydro_TC_TorqueIn))* sign(dizel_engagedeltaomega);
}
else
{
hydro_TC_nOut = enrot - (n - enrot)*(TorqueC - TorqueL) / TorqueH; //slizganie proporcjonalne, zeby przetwornik nadrabial
gearMoment = TorqueC * sign(dizel_engagedeltaomega);
enMoment = Moment - gearMoment;
}
}
else
{
hydro_TC_nOut = enrot;
gearMoment = (TorqueC) * sign(dizel_engagedeltaomega);
enMoment = Moment - gearMoment;
}
eps = enMoment / dizel_AIM;
newn = enrot + eps * dt;
if ((newn - n)*(enrot - dizel_n_old) < 0) //przejscie przez zero - slizgalo sie i przestało
newn = n;
if ((newn * enrot <= 0) && (eps * enrot < 0)) //przejscie przez zero obrotow
newn = 0;
enrot = newn;
}
else //nie slizga sie (jeszcze)
{
dizel_engagedeltaomega = 0;
gearMoment = Moment;
enMoment = 0;
double enrot_min = enrot - (Min0R(TorqueC, TorqueL + abs(hydro_TC_TorqueIn)) - Moment) / dizel_AIM * dt;
double enrot_max = enrot + (Min0R(TorqueC, TorqueL + abs(hydro_TC_TorqueIn)) + Moment) / dizel_AIM * dt;
enrot = clamp(n,enrot_min,enrot_max);
}
if ((enrot <= 0) && (!dizel_enginestart))
{
Mains = false;
enrot = 0;
}
dizel_n_old = n; //obecna predkosc katowa na potrzeby kolejnej klatki
return gearMoment;
}
// *************************************************************************************************
@@ -7439,6 +7556,9 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
extract_value( dizel_nmax_cutoff, "nmax_cutoff", Input, "0.0" );
dizel_nmax_cutoff /= 60.0;
extract_value( dizel_AIM, "AIM", Input, "1.0" );
extract_value(engageupspeed, "EUS", Input, "0.5");
extract_value(engagedownspeed, "EDS", Input, "0.9");
if( true == extract_value( AnPos, "ShuntMode", Input, "" ) ) {
//dodatkowa przekładnia dla SM03 (2Ls150)
@@ -7448,7 +7568,34 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
//"rozruch wysoki" ma dawać większą siłę
AnPos = 1.0 / AnPos; //im większa liczba, tym wolniej jedzie
}
}
hydro_TC = (extract_value("IsTC", Input) == "Yes");
if (true == hydro_TC) {
extract_value(hydro_TC_TMMax, "TC_TMMax", Input, "");
extract_value(hydro_TC_CouplingPoint, "TC_CP", Input, "");
extract_value(hydro_TC_LockupTorque, "TC_LT", Input, "");
extract_value(hydro_TC_LockupRate, "TC_LR", Input, "");
extract_value(hydro_TC_UnlockRate, "TC_ULR", Input, "");
extract_value(hydro_TC_FillRateInc, "TC_FRI", Input, "");
extract_value(hydro_TC_FillRateDec, "TC_FRD", Input, "");
extract_value(hydro_TC_TorqueInIn, "TC_TII", Input, "");
extract_value(hydro_TC_TorqueInOut, "TC_TIO", Input, "");
extract_value(hydro_TC_TorqueOutOut, "TC_TOO", Input, "");
extract_value(hydro_TC_LockupSpeed, "TC_LS", Input, "");
extract_value(hydro_TC_UnlockSpeed, "TC_ULS", Input, "");
hydro_R = (extract_value("IsRetarder", Input) == "Yes");
if (true == hydro_R) {
extract_value(hydro_R_Placement, "R_Place", Input, "");
extract_value(hydro_R_TorqueInIn, "R_TII", Input, "");
extract_value(hydro_R_MaxTorque, "R_MT", Input, "");
extract_value(hydro_R_MaxPower, "R_MP", Input, "");
extract_value(hydro_R_FillRateInc, "R_FRI", Input, "");
extract_value(hydro_R_FillRateDec, "R_FRD", Input, "");
extract_value(hydro_R_MinVel, "R_MinVel", Input, "");
}
}
break;
}
case DieselElectric: { //youBy
@@ -7582,6 +7729,11 @@ void TMoverParameters::LoadFIZ_DList( std::string const &Input ) {
extract_value( dizel_nmax, "nmax", Input, "" );
extract_value( dizel_nominalfill, "nominalfill", Input, "" );
extract_value( dizel_Mstand, "Mstand", Input, "" );
if( dizel_nMmax == dizel_nmax ) {
// HACK: guard against cases where nMmax == nmax, leading to division by 0 in momentum calculation
dizel_nMmax = dizel_nmax - 1.0 / 60.0;
}
}
void TMoverParameters::LoadFIZ_FFList( std::string const &Input ) {

View File

@@ -648,13 +648,14 @@ void TSubModel::InitialRotate(bool doit)
if (fMatrix->IdentityIs())
iFlags &= ~0x8000; // jednak jednostkowa po obróceniu
}
if (Child)
Child->InitialRotate(false); // potomnych nie obracamy już, tylko
// ewentualnie optymalizujemy
else if (Global::iConvertModels & 2) // optymalizacja jest opcjonalna
if( Child ) {
// potomnych nie obracamy już, tylko ewentualnie optymalizujemy
Child->InitialRotate( false );
}
else if (Global::iConvertModels & 2) {
// optymalizacja jest opcjonalna
if ((iFlags & 0xC000) == 0x8000) // o ile nie ma animacji
{ // jak nie ma potomnych, można wymnożyć przez transform i wyjedynkować
// go
{ // jak nie ma potomnych, można wymnożyć przez transform i wyjedynkować go
float4x4 *mat = GetMatrix(); // transform submodelu
if( false == Vertices.empty() ) {
for( auto &vertex : Vertices ) {
@@ -675,6 +676,7 @@ void TSubModel::InitialRotate(bool doit)
mat->Identity(); // jedynkowanie transformu po przeliczeniu wierzchołków
iFlags &= ~0x8000; // transform jedynkowy
}
}
}
else // jak jest jednostkowy i nie ma animacji
if (doit)
@@ -1166,11 +1168,11 @@ TSubModel::offset( float const Geometrytestoffsetthreshold ) const {
auto offset { glm::vec3 { glm::make_mat4( parentmatrix.readArray() ) * glm::vec4 { 0, 0, 0, 1 } } };
if( glm::length2( offset ) < Geometrytestoffsetthreshold ) {
// offset of zero generally means the submodel has optimized identity matrix
// for such cases we resort to an estimate from submodel geometry
// TODO: do proper bounding area calculation for submodel when loading mesh and grab the centre point from it here
// offset of zero generally means the submodel has optimized identity matrix
// for such cases we resort to an estimate from submodel geometry
// TODO: do proper bounding area calculation for submodel when loading mesh and grab the centre point from it here
if( m_geometry != null_handle ) {
auto const &vertices{ GfxRenderer.Vertices( m_geometry ) };
auto const &vertices { GfxRenderer.Vertices( m_geometry ) };
if( false == vertices.empty() ) {
// transformation matrix for the submodel can still contain rotation and/or scaling,
// so we pass the vertex positions through it rather than just grab them directly
@@ -1184,6 +1186,16 @@ TSubModel::offset( float const Geometrytestoffsetthreshold ) const {
}
}
if( true == TestFlag( iFlags, 0x0200 ) ) {
// flip coordinates for t3d file which wasn't yet initialized
if( std::abs( offset.y ) > offset.z ) {
// NOTE, HACK: results require flipping if the model wasn't yet initialized, so we're using crude method to detect possible cases
// TODO: sort out this mess, either unify offset lookups to take place before (or after) initialization,
// or provide way to determine on submodel level whether the initialization took place
offset = { -offset.x, offset.z, offset.y };
}
}
return offset;
}

View File

@@ -489,8 +489,18 @@ void TTrack::Load(cParser *parser, vector3 pOrigin)
}
if( fRadius != 0 ) // gdy podany promień
segsize = clamp( std::fabs( fRadius ) * ( 0.02 / Global::SplineFidelity ), 2.0 / Global::SplineFidelity, 10.0 );
else
segsize = 10.0; // for straights, 10m per segment works good enough
else {
// HACK: crude check whether claimed straight is an actual straight piece
// NOTE: won't detect cases where control points are placed on the straight line formed by the ends, but, eh
if( ( cp1 == Math3D::vector3() )
&& ( cp1 == Math3D::vector3() ) ) {
segsize = 10.0; // for straights, 10m per segment works good enough
}
else {
// HACK: divide roughly in 10 segments.
segsize = clamp( fTrackLength * ( 0.1 / Global::SplineFidelity ), 2.0 / Global::SplineFidelity, 10.0 );
}
}
if ((((p1 + p1 + p2) / 3.0 - p1 - cp1).Length() < 0.02) ||
(((p1 + p2 + p2) / 3.0 - p2 + cp1).Length() < 0.02))

1641
Train.cpp

File diff suppressed because it is too large Load Diff

22
Train.h
View File

@@ -83,7 +83,6 @@ class TTrain
~TTrain();
// McZapkie-010302
bool Init(TDynamicObject *NewDynamicObject, bool e3d = false);
void OnKeyDown(int cKey);
inline vector3 GetDirection() { return DynamicObject->VectorFront(); };
inline vector3 GetUp() { return DynamicObject->VectorUp(); };
@@ -114,9 +113,14 @@ class TTrain
bool initialize_button(cParser &Parser, std::string const &Label, int const Cabindex);
// helper, returns true for EMU with oerlikon brake
bool is_eztoer() const;
// locates nearest vehicle belonging to the consist
TDynamicObject *find_nearest_consist_vehicle() const;
// command handlers
// NOTE: we're currently using universal handlers and static handler map but it may be beneficial to have these implemented on individual class instance basis
// TBD, TODO: consider this approach if we ever want to have customized consist behaviour to received commands, based on the consist/vehicle type or whatever
static void OnCommand_aidriverenable( TTrain *Train, command_data const &Command );
static void OnCommand_aidriverdisable( 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_mastercontrollerdecrease( TTrain *Train, command_data const &Command );
@@ -139,7 +143,12 @@ class TTrain
static void OnCommand_trainbrakefirstservice( TTrain *Train, command_data const &Command );
static void OnCommand_trainbrakeservice( TTrain *Train, command_data const &Command );
static void OnCommand_trainbrakefullservice( TTrain *Train, command_data const &Command );
static void OnCommand_trainbrakehandleoff( TTrain *Train, command_data const &Command );
static void OnCommand_trainbrakeemergency( TTrain *Train, command_data const &Command );
static void OnCommand_trainbrakebasepressureincrease( TTrain *Train, command_data const &Command );
static void OnCommand_trainbrakebasepressuredecrease( TTrain *Train, command_data const &Command );
static void OnCommand_trainbrakebasepressurereset( TTrain *Train, command_data const &Command );
static void OnCommand_trainbrakeoperationtoggle( TTrain *Train, command_data const &Command );
static void OnCommand_manualbrakeincrease( TTrain *Train, command_data const &Command );
static void OnCommand_manualbrakedecrease( TTrain *Train, command_data const &Command );
static void OnCommand_alarmchaintoggle( TTrain *Train, command_data const &Command );
@@ -148,6 +157,8 @@ class TTrain
static void OnCommand_epbrakecontroltoggle( TTrain *Train, command_data const &Command );
static void OnCommand_brakeactingspeedincrease( TTrain *Train, command_data const &Command );
static void OnCommand_brakeactingspeeddecrease( TTrain *Train, command_data const &Command );
static void OnCommand_brakeloadcompensationincrease( TTrain *Train, command_data const &Command );
static void OnCommand_brakeloadcompensationdecrease( TTrain *Train, command_data const &Command );
static void OnCommand_mubrakingindicatortoggle( TTrain *Train, command_data const &Command );
static void OnCommand_reverserincrease( TTrain *Train, command_data const &Command );
static void OnCommand_reverserdecrease( TTrain *Train, command_data const &Command );
@@ -181,6 +192,8 @@ class TTrain
static void OnCommand_headlighttogglerearupper( TTrain *Train, command_data const &Command );
static void OnCommand_redmarkertogglerearleft( TTrain *Train, command_data const &Command );
static void OnCommand_redmarkertogglerearright( TTrain *Train, command_data const &Command );
static void OnCommand_redmarkerstoggle( TTrain *Train, command_data const &Command );
static void OnCommand_endsignalstoggle( TTrain *Train, command_data const &Command );
static void OnCommand_headlightsdimtoggle( TTrain *Train, command_data const &Command );
static void OnCommand_interiorlighttoggle( TTrain *Train, command_data const &Command );
static void OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const &Command );
@@ -188,11 +201,17 @@ class TTrain
static void OnCommand_doorlocktoggle( TTrain *Train, command_data const &Command );
static void OnCommand_doortoggleleft( TTrain *Train, command_data const &Command );
static void OnCommand_doortoggleright( TTrain *Train, command_data const &Command );
static void OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command );
static void OnCommand_carcouplingdisconnect( TTrain *Train, command_data const &Command );
static void OnCommand_departureannounce( TTrain *Train, command_data const &Command );
static void OnCommand_hornlowactivate( TTrain *Train, command_data const &Command );
static void OnCommand_hornhighactivate( TTrain *Train, command_data const &Command );
static void OnCommand_radiotoggle( TTrain *Train, command_data const &Command );
static void OnCommand_radiochannelincrease( TTrain *Train, command_data const &Command );
static void OnCommand_radiochanneldecrease( TTrain *Train, command_data const &Command );
static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command );
static void OnCommand_cabchangeforward( TTrain *Train, command_data const &Command );
static void OnCommand_cabchangebackward( TTrain *Train, command_data const &Command );
static void OnCommand_generictoggle( TTrain *Train, command_data const &Command );
// members
@@ -495,7 +514,6 @@ private:
inline TMoverParameters *Occupied() { return mvOccupied; };
inline TMoverParameters const *Occupied() const { return mvOccupied; };
void DynamicSet(TDynamicObject *d);
void Silence();
float get_tacho();
float get_tank_pressure();

228
World.cpp
View File

@@ -345,8 +345,7 @@ bool TWorld::Init( GLFWwindow *Window ) {
return true;
};
void TWorld::OnKeyDown(int cKey)
{
void TWorld::OnKeyDown(int cKey) {
// dump keypress info in the log
if( !Global::iPause ) {
// podczas pauzy klawisze nie działają
@@ -519,9 +518,7 @@ void TWorld::OnKeyDown(int cKey)
// works always in debug mode, or for stopped/slow moving vehicles otherwise
Controlled = tmp; // przejmujemy nowy
mvControlled = Controlled->ControlledFind()->MoverParameters;
if( Train )
Train->Silence(); // wyciszenie dźwięków opuszczanego pojazdu
else
if( Train == nullptr )
Train = new TTrain(); // jeśli niczym jeszcze nie jeździlismy
if( Train->Init( Controlled ) ) { // przejmujemy sterowanie
if( !DebugModeFlag ) // w DebugMode nadal prowadzi AI
@@ -654,107 +651,55 @@ void TWorld::OnKeyDown(int cKey)
if( Controlled->MoverParameters->Radio )
simulation::Region->RadioStop( Camera.Pos );
}
else if (!Global::iPause) //||(cKey==VK_F4)) //podczas pauzy sterownaie nie działa, F4 tak
if (Train)
if (Controlled)
if ((Controlled->Controller == Humandriver) ? true : DebugModeFlag || (cKey == GLFW_KEY_Q))
Train->OnKeyDown(cKey); // przekazanie klawisza do kabiny
if (FreeFlyModeFlag) // aby nie odluźniało wagonu za lokomotywą
{ // operacje wykonywane na dowolnym pojeździe, przeniesione tu z kabiny
/*
// NOTE: disabled so it doesn't interfere with new system controls in outside view
// TODO: implement as part of the new system
if (cKey == Global::Keys[k_Releaser]) // odluźniacz
{ // działa globalnie, sprawdzić zasięg
TDynamicObject *temp = Global::DynamicNearest();
if (temp)
{
if (Global::ctrlState) // z ctrl odcinanie
{
temp->MoverParameters->Hamulec->SetBrakeStatus( temp->MoverParameters->Hamulec->GetBrakeStatus() ^ 128 );
}
else if (temp->MoverParameters->BrakeReleaser(1))
{
// temp->sBrakeAcc->
// dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX);
// dsbPneumaticRelay->Play(0,0,0); //temp->Position()-Camera.Pos //???
}
}
}
else
*/
if (cKey == Global::Keys[k_Heating]) // Ra: klawisz nie jest najszczęśliwszy
{ // zmiana próżny/ładowny; Ra: zabrane z kabiny
auto *vehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 10, false, false ) ) };
if (vehicle)
{
if (Global::shiftState ? vehicle->MoverParameters->IncBrakeMult() :
vehicle->MoverParameters->DecBrakeMult())
if (Train)
{ // dźwięk oczywiście jest w kabinie
Train->dsbSwitch.play();
else {
if( ( true == DebugModeFlag )
&& ( false == Global::shiftState )
&& ( true == Global::ctrlState )
&& ( Controlled != nullptr )
&& ( Controlled->Controller == Humandriver ) ) {
if( DebugModeFlag ) {
// przesuwanie składu o 100m
TDynamicObject *d = Controlled;
if( cKey == GLFW_KEY_LEFT_BRACKET ) {
while( d ) {
d->Move( 100.0 * d->DirectionGet() );
d = d->Next(); // pozostałe też
}
}
}
else if (cKey == Global::Keys[k_EndSign])
{ // Ra 2014-07: zabrane z kabiny
auto *vehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 10, false, true ) ) };
if (vehicle)
{
int CouplNr = (LengthSquared3(vehicle->HeadPosition() - Camera.Pos) >
LengthSquared3(vehicle->RearPosition() - Camera.Pos) ?
1 :
-1) *
vehicle->DirectionGet();
if (CouplNr < 0)
CouplNr = 0; // z [-1,1] zrobić [0,1]
int mask, set = 0; // Ra: [Shift]+[Ctrl]+[T] odpala mi jakąś idiotyczną zmianę tapety pulpitu :/
if (Global::shiftState) // z [Shift] zapalanie
set = mask = light::rearendsignals; // bez [Ctrl] założyć tabliczki
else if (Global::ctrlState)
set = mask = ( light::redmarker_left | light::redmarker_right ); // z [Ctrl] zapalić światła czerwone
else
mask = 2 + 32 + 64; // wyłączanie ściąga wszystko
if (((vehicle->iLights[CouplNr]) & mask) != set)
{
vehicle->iLights[CouplNr] = (vehicle->iLights[CouplNr] & ~mask) | set;
if (Train)
{ // Ra: ten dźwięk z kabiny to przegięcie, ale na razie zostawiam
Train->dsbSwitch.play();
d = Controlled->Prev();
while( d ) {
d->Move( 100.0 * d->DirectionGet() );
d = d->Prev(); // w drugą stronę też
}
}
else if( cKey == GLFW_KEY_RIGHT_BRACKET ) {
while( d ) {
d->Move( -100.0 * d->DirectionGet() );
d = d->Next(); // pozostałe też
}
d = Controlled->Prev();
while( d ) {
d->Move( -100.0 * d->DirectionGet() );
d = d->Prev(); // w drugą stronę też
}
}
else if( cKey == GLFW_KEY_TAB ) {
while( d ) {
d->MoverParameters->V += d->DirectionGet()*2.78;
d = d->Next(); // pozostałe też
}
d = Controlled->Prev();
while( d ) {
d->MoverParameters->V += d->DirectionGet()*2.78;
d = d->Prev(); // w drugą stronę też
}
}
}
}
else if (cKey == Global::Keys[k_IncLocalBrakeLevel])
{ // zahamowanie dowolnego pojazdu
auto *vehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 10, false, false ) ) };
if (vehicle)
{
if (Global::ctrlState)
if ((vehicle->MoverParameters->LocalBrake == ManualBrake) ||
(vehicle->MoverParameters->MBrake == true))
vehicle->MoverParameters->IncManualBrakeLevel(1);
}
}
else if (cKey == Global::Keys[k_DecLocalBrakeLevel])
{ // odhamowanie dowolnego pojazdu
auto *vehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global::pCameraPosition, 10, false, false ) ) };
if (vehicle)
{
if (Global::ctrlState)
if ((vehicle->MoverParameters->LocalBrake == ManualBrake) ||
(vehicle->MoverParameters->MBrake == true))
vehicle->MoverParameters->DecManualBrakeLevel(1);
}
}
}
}
void TWorld::OnMouseMove(double x, double y)
{ // McZapkie:060503-definicja obracania myszy
Camera.OnCursorMove(x * Global::fMouseXScale / Global::ZoomFactor, -y * Global::fMouseYScale / Global::ZoomFactor);
}
void TWorld::InOutKey( bool const Near )
{ // przełączenie widoku z kabiny na zewnętrzny i odwrotnie
FreeFlyModeFlag = !FreeFlyModeFlag; // zmiana widoku
@@ -763,8 +708,6 @@ void TWorld::InOutKey( bool const Near )
if (Train) {
// cache current cab position so there's no need to set it all over again after each out-in switch
Train->pMechSittingPosition = Train->pMechOffset;
// wyłączenie dźwięków kabiny
Train->Silence();
Train->Dynamic()->bDisplayCab = false;
DistantView( Near );
}
@@ -1244,6 +1187,15 @@ TWorld::Update_UI() {
uitextline3 = "Brakes:" + to_string( mover->fBrakeCtrlPos, 1, 5 ) + "+" + std::to_string( mover->LocalBrakePos ) + ( mover->SlippingWheels ? " !" : " " );
uitextline4 = (
true == TestFlag( mover->SecuritySystem.Status, s_aware ) ?
"!ALERTER! " :
" " );
uitextline4 += (
true == TestFlag( mover->SecuritySystem.Status, s_active ) ?
"!SHP! " :
" " );
if( Global::iScreenMode[ Global::iTextMode - GLFW_KEY_F1 ] == 1 ) {
// detail mode on second key press
uitextline2 +=
@@ -1257,7 +1209,7 @@ TWorld::Update_UI() {
auto const trackblockdistance{ std::abs( Controlled->Mechanik->TrackBlock() ) };
if( trackblockdistance <= 75.0 ) {
uitextline4 = " Another vehicle ahead (distance: " + to_string( trackblockdistance, 1 ) + " m)";
uitextline4 += " Another vehicle ahead (distance: " + to_string( trackblockdistance, 1 ) + " m)";
}
}
}
@@ -1458,6 +1410,7 @@ TWorld::Update_UI() {
uitextline3 +=
"; LcB: " + to_string( vehicle->MoverParameters->LocBrakePress, 2 )
+ "; hat: " + to_string( vehicle->MoverParameters->BrakeCtrlPos2, 2 )
+ "; pipes: " + to_string( vehicle->MoverParameters->PipePress, 2 )
+ "/" + to_string( vehicle->MoverParameters->ScndPipePress, 2 )
+ "/" + to_string( vehicle->MoverParameters->EqvtPipePress, 2 )
@@ -1743,6 +1696,40 @@ TWorld::Update_UI() {
UITable->text_lines.emplace_back( parameters, Global::UITextColor );
}
}
if (vehicle->MoverParameters->EngineType == DieselEngine) {
std::string parameters = "param value";
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "efill: " + to_string(vehicle->MoverParameters->dizel_fill, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "etorq: " + to_string(vehicle->MoverParameters->dizel_Torque, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "creal: " + to_string(vehicle->MoverParameters->dizel_engage, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "cdesi: " + to_string(vehicle->MoverParameters->dizel_engagestate, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "cdelt: " + to_string(vehicle->MoverParameters->dizel_engagedeltaomega, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "gears: " + to_string(vehicle->MoverParameters->dizel_automaticgearstatus, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "hydro value";
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "hTCnI: " + to_string(vehicle->MoverParameters->hydro_TC_nIn, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "hTCnO: " + to_string(vehicle->MoverParameters->hydro_TC_nOut, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "hTCTM: " + to_string(vehicle->MoverParameters->hydro_TC_TMRatio, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "hTCTI: " + to_string(vehicle->MoverParameters->hydro_TC_TorqueIn, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "hTCTO: " + to_string(vehicle->MoverParameters->hydro_TC_TorqueOut, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "hTCfl: " + to_string(vehicle->MoverParameters->hydro_TC_Fill, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
parameters = "hTCLR: " + to_string(vehicle->MoverParameters->hydro_TC_LockupRate, 2, 9);
UITable->text_lines.emplace_back(parameters, Global::UITextColor);
//parameters = "hTCXX: " + to_string(vehicle->MoverParameters->hydro_TC_nIn, 2, 9);
//UITable->text_lines.emplace_back(parameters, Global::UITextColor);
}
} // if( DebugModeFlag && Controlled )
@@ -2082,26 +2069,28 @@ void TWorld::CabChange(TDynamicObject *old, TDynamicObject *now)
void TWorld::ChangeDynamic() {
// Ra: to nie może być tak robione, to zbytnia proteza jest
Train->Silence(); // wyłączenie dźwięków opuszczanej kabiny
if( Train->Dynamic()->Mechanik ) // AI może sobie samo pójść
if( !Train->Dynamic()->Mechanik->AIControllFlag ) // tylko jeśli ręcznie prowadzony
{ // jeśli prowadzi AI, to mu nie robimy dywersji!
if( Train->Dynamic()->Mechanik ) {
// AI może sobie samo pójść
if( false == Train->Dynamic()->Mechanik->AIControllFlag ) {
// tylko jeśli ręcznie prowadzony
// jeśli prowadzi AI, to mu nie robimy dywersji!
Train->Dynamic()->MoverParameters->CabDeactivisation();
Train->Dynamic()->Controller = AIdriver;
// Train->Dynamic()->MoverParameters->SecuritySystem.Status=0; //rozwala CA w EZT
Train->Dynamic()->MoverParameters->ActiveCab = 0;
Train->Dynamic()->MoverParameters->BrakeLevelSet(
Train->Dynamic()->MoverParameters->Handle->GetPos(
bh_NP ) ); //rozwala sterowanie hamulcem GF 04-2016
Train->Dynamic()->MoverParameters->BrakeLevelSet( Train->Dynamic()->MoverParameters->Handle->GetPos( bh_NP ) ); //rozwala sterowanie hamulcem GF 04-2016
Train->Dynamic()->MechInside = false;
}
}
TDynamicObject *temp = Global::changeDynObj;
Train->Dynamic()->bDisplayCab = false;
Train->Dynamic()->ABuSetModelShake( vector3( 0, 0, 0 ) );
Train->Dynamic()->ABuSetModelShake( {} );
if( Train->Dynamic()->Mechanik ) // AI może sobie samo pójść
if( !Train->Dynamic()->Mechanik->AIControllFlag ) // tylko jeśli ręcznie prowadzony
Train->Dynamic()->Mechanik->MoveTo( temp ); // przsunięcie obiektu zarządzającego
if( false == Train->Dynamic()->Mechanik->AIControllFlag ) {
// tylko jeśli ręcznie prowadzony
// przsunięcie obiektu zarządzającego
Train->Dynamic()->Mechanik->MoveTo( temp );
}
Train->DynamicSet( temp );
Controlled = temp;
@@ -2110,20 +2099,17 @@ void TWorld::ChangeDynamic() {
if( Train->Dynamic()->Mechanik ) // AI może sobie samo pójść
if( !Train->Dynamic()->Mechanik->AIControllFlag ) // tylko jeśli ręcznie prowadzony
{
Train->Dynamic()->MoverParameters->LimPipePress =
Controlled->MoverParameters->PipePress;
Train->Dynamic()
->MoverParameters->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
Train->Dynamic()->MoverParameters->LimPipePress = Controlled->MoverParameters->PipePress;
Train->Dynamic()->MoverParameters->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
Train->Dynamic()->Controller = Humandriver;
Train->Dynamic()->MechInside = true;
}
Train->InitializeCab( Train->Dynamic()->MoverParameters->CabNo,
Train->Dynamic()->asBaseDir +
Train->Dynamic()->MoverParameters->TypeName + ".mmd" );
Train->InitializeCab(
Train->Dynamic()->MoverParameters->CabNo,
Train->Dynamic()->asBaseDir + Train->Dynamic()->MoverParameters->TypeName + ".mmd" );
if( !FreeFlyModeFlag ) {
Train->Dynamic()->bDisplayCab = true;
Train->Dynamic()->ABuSetModelShake(
vector3( 0, 0, 0 ) ); // zerowanie przesunięcia przed powrotem?
Train->Dynamic()->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem?
Train->MechStop();
FollowView(); // na pozycję mecha
}

View File

@@ -102,7 +102,6 @@ TWorld();
bool InitPerformed() { return m_init; }
bool Update();
void OnKeyDown( int cKey );
void OnMouseMove( double x, double y );
void OnCommandGet( multiplayer::DaneRozkaz *pRozkaz );
// passes specified sound to all vehicles within range as a radio message broadcasted on specified channel
void radio_message( sound_source *Message, int const Channel );

View File

@@ -64,6 +64,22 @@ openal_buffer::openal_buffer( std::string const &Filename ) :
if (si.channels != 1)
delete[] buf;
delete[] fbuf;
fetch_caption();
}
// retrieves sound caption in currently set language
void
openal_buffer::fetch_caption() {
std::string captionfilename{ name };
captionfilename.erase(captionfilename.rfind('.')); // obcięcie rozszerzenia
captionfilename += "-" + Global::asLang + ".txt"; // już może być w różnych językach
if (true == FileExists(captionfilename)) {
// wczytanie
std::ifstream inputfile(captionfilename);
caption.assign(std::istreambuf_iterator<char>(inputfile), std::istreambuf_iterator<char>());
}
}
buffer_manager::~buffer_manager() {

View File

@@ -20,11 +20,17 @@ ALuint const null_resource{ ~( ALuint { 0 } ) };
struct openal_buffer {
// members
ALuint id { null_resource }; // associated AL resource
unsigned int rate { 0 }; // sample rate of the data
unsigned int rate {}; // sample rate of the data
std::string name;
std::string caption;
// constructors
openal_buffer() = default;
explicit openal_buffer( std::string const &Filename );
// methods
// retrieves sound caption in currently set language
void
fetch_caption();
};
using buffer_handle = std::size_t;

View File

@@ -165,8 +165,11 @@ openal_source::bind( sound_source *Controller, uint32_sequence Sounds, Iterator_
std::vector<ALuint> buffers;
std::for_each(
First, Last,
[&]( audio::buffer_handle const &buffer ) {
buffers.emplace_back( audio::renderer.buffer( buffer ).id ); } );
[&]( audio::buffer_handle const &bufferhandle ) {
auto const &buffer { audio::renderer.buffer( bufferhandle ) };
buffers.emplace_back( buffer.id );
if( false == buffer.caption.empty() ) {
Global::tranTexts.Add( buffer.caption ); } } );
if( id != audio::null_resource ) {
::alSourceQueueBuffers( id, static_cast<ALsizei>( buffers.size() ), buffers.data() );

View File

@@ -19,128 +19,123 @@ namespace simulation {
command_queue Commands;
commanddescription_sequence Commands_descriptions = {
{ "mastercontrollerincrease", command_target::vehicle, command_mode::oneoff },
{ "mastercontrollerincreasefast", command_target::vehicle, command_mode::oneoff },
{ "mastercontrollerdecrease", command_target::vehicle, command_mode::oneoff },
{ "mastercontrollerdecreasefast", command_target::vehicle, command_mode::oneoff },
{ "secondcontrollerincrease", command_target::vehicle, command_mode::oneoff },
{ "secondcontrollerincreasefast", command_target::vehicle, command_mode::oneoff },
{ "secondcontrollerdecrease", command_target::vehicle, command_mode::oneoff },
{ "secondcontrollerdecreasefast", command_target::vehicle, command_mode::oneoff },
{ "mucurrentindicatorothersourceactivate", command_target::vehicle, command_mode::oneoff },
{ "independentbrakeincrease", command_target::vehicle, command_mode::oneoff },
{ "independentbrakeincreasefast", command_target::vehicle, command_mode::oneoff },
{ "independentbrakedecrease", command_target::vehicle, command_mode::oneoff },
{ "independentbrakedecreasefast", command_target::vehicle, command_mode::oneoff },
{ "independentbrakebailoff", command_target::vehicle, command_mode::oneoff },
{ "aidriverenable", command_target::vehicle },
{ "aidriverdisable", command_target::vehicle },
{ "mastercontrollerincrease", command_target::vehicle },
{ "mastercontrollerincreasefast", command_target::vehicle },
{ "mastercontrollerdecrease", command_target::vehicle },
{ "mastercontrollerdecreasefast", command_target::vehicle },
{ "secondcontrollerincrease", command_target::vehicle },
{ "secondcontrollerincreasefast", command_target::vehicle },
{ "secondcontrollerdecrease", command_target::vehicle },
{ "secondcontrollerdecreasefast", command_target::vehicle },
{ "mucurrentindicatorothersourceactivate", command_target::vehicle },
{ "independentbrakeincrease", command_target::vehicle },
{ "independentbrakeincreasefast", command_target::vehicle },
{ "independentbrakedecrease", command_target::vehicle },
{ "independentbrakedecreasefast", command_target::vehicle },
{ "independentbrakebailoff", command_target::vehicle },
{ "trainbrakeincrease", command_target::vehicle, command_mode::continuous },
{ "trainbrakedecrease", command_target::vehicle, command_mode::continuous },
{ "trainbrakecharging", command_target::vehicle, command_mode::oneoff },
{ "trainbrakerelease", command_target::vehicle, command_mode::oneoff },
{ "trainbrakefirstservice", command_target::vehicle, command_mode::oneoff },
{ "trainbrakeservice", command_target::vehicle, command_mode::oneoff },
{ "trainbrakefullservice", command_target::vehicle, command_mode::oneoff },
{ "trainbrakeemergency", command_target::vehicle, command_mode::oneoff },
{ "manualbrakeincrease", command_target::vehicle, command_mode::oneoff },
{ "manualbrakedecrease", command_target::vehicle, command_mode::oneoff },
{ "alarmchaintoggle", command_target::vehicle, command_mode::oneoff },
{ "wheelspinbrakeactivate", command_target::vehicle, command_mode::oneoff },
{ "sandboxactivate", command_target::vehicle, command_mode::oneoff },
{ "reverserincrease", command_target::vehicle, command_mode::oneoff },
{ "reverserdecrease", command_target::vehicle, command_mode::oneoff },
{ "linebreakertoggle", command_target::vehicle, command_mode::oneoff },
{ "convertertoggle", command_target::vehicle, command_mode::oneoff },
{ "convertertogglelocal", command_target::vehicle, command_mode::oneoff },
{ "converteroverloadrelayreset", command_target::vehicle, command_mode::oneoff },
{ "compressortoggle", command_target::vehicle, command_mode::oneoff },
{ "compressortogglelocal", command_target::vehicle, command_mode::oneoff },
{ "motoroverloadrelaythresholdtoggle", command_target::vehicle, command_mode::oneoff },
{ "motoroverloadrelayreset", command_target::vehicle, command_mode::oneoff },
{ "notchingrelaytoggle", command_target::vehicle, command_mode::oneoff },
{ "epbrakecontroltoggle", command_target::vehicle, command_mode::oneoff },
{ "brakeactingspeedincrease", command_target::vehicle, command_mode::oneoff },
{ "brakeactingspeeddecrease", command_target::vehicle, command_mode::oneoff },
{ "mubrakingindicatortoggle", command_target::vehicle, command_mode::oneoff },
{ "alerteracknowledge", command_target::vehicle, command_mode::oneoff },
{ "hornlowactivate", command_target::vehicle, command_mode::oneoff },
{ "hornhighactivate", command_target::vehicle, command_mode::oneoff },
{ "radiotoggle", command_target::vehicle, command_mode::oneoff },
{ "radiostoptest", command_target::vehicle, command_mode::oneoff },
/*
const int k_FailedEngineCutOff = 35;
*/
{ "viewturn", command_target::entity, command_mode::oneoff },
{ "movevector", command_target::entity, command_mode::oneoff },
{ "moveleft", command_target::entity, command_mode::oneoff },
{ "moveright", command_target::entity, command_mode::oneoff },
{ "moveforward", command_target::entity, command_mode::oneoff },
{ "moveback", command_target::entity, command_mode::oneoff },
{ "moveup", command_target::entity, command_mode::oneoff },
{ "movedown", command_target::entity, command_mode::oneoff },
{ "moveleftfast", command_target::entity, command_mode::oneoff },
{ "moverightfast", command_target::entity, command_mode::oneoff },
{ "moveforwardfast", command_target::entity, command_mode::oneoff },
{ "movebackfast", command_target::entity, command_mode::oneoff },
{ "moveupfast", command_target::entity, command_mode::oneoff },
{ "movedownfast", command_target::entity, command_mode::oneoff },
/*
const int k_CabForward = 42;
const int k_CabBackward = 43;
const int k_Couple = 44;
const int k_DeCouple = 45;
const int k_ProgramQuit = 46;
// const int k_ProgramPause= 47;
const int k_ProgramHelp = 48;
*/
{ "doortoggleleft", command_target::vehicle, command_mode::oneoff },
{ "doortoggleright", command_target::vehicle, command_mode::oneoff },
{ "departureannounce", command_target::vehicle, command_mode::oneoff },
{ "doorlocktoggle", command_target::vehicle, command_mode::oneoff },
{ "pantographcompressorvalvetoggle", command_target::vehicle, command_mode::oneoff },
{ "pantographcompressoractivate", command_target::vehicle, command_mode::oneoff },
{ "pantographtogglefront", command_target::vehicle, command_mode::oneoff },
{ "pantographtogglerear", command_target::vehicle, command_mode::oneoff },
{ "pantographlowerall", command_target::vehicle, command_mode::oneoff },
{ "heatingtoggle", command_target::vehicle, command_mode::oneoff },
/*
// const int k_FreeFlyMode= 59;
*/
{ "lightspresetactivatenext", command_target::vehicle, command_mode::oneoff },
{ "lightspresetactivateprevious", command_target::vehicle, command_mode::oneoff },
{ "headlighttoggleleft", command_target::vehicle, command_mode::oneoff },
{ "headlighttoggleright", command_target::vehicle, command_mode::oneoff },
{ "headlighttoggleupper", command_target::vehicle, command_mode::oneoff },
{ "redmarkertoggleleft", command_target::vehicle, command_mode::oneoff },
{ "redmarkertoggleright", command_target::vehicle, command_mode::oneoff },
{ "headlighttogglerearleft", command_target::vehicle, command_mode::oneoff },
{ "headlighttogglerearright", command_target::vehicle, command_mode::oneoff },
{ "headlighttogglerearupper", command_target::vehicle, command_mode::oneoff },
{ "redmarkertogglerearleft", command_target::vehicle, command_mode::oneoff },
{ "redmarkertogglerearright", command_target::vehicle, command_mode::oneoff },
{ "headlightsdimtoggle", command_target::vehicle, command_mode::oneoff },
{ "motorconnectorsopen", command_target::vehicle, command_mode::oneoff },
{ "motordisconnect", command_target::vehicle, command_mode::oneoff },
{ "interiorlighttoggle", command_target::vehicle, command_mode::oneoff },
{ "interiorlightdimtoggle", command_target::vehicle, command_mode::oneoff },
{ "instrumentlighttoggle", command_target::vehicle, command_mode::oneoff },
/*
const int k_EndSign = 70;
const int k_Active = 71;
*/
{ "generictoggle0", command_target::vehicle, command_mode::oneoff },
{ "generictoggle1", command_target::vehicle, command_mode::oneoff },
{ "generictoggle2", command_target::vehicle, command_mode::oneoff },
{ "generictoggle3", command_target::vehicle, command_mode::oneoff },
{ "generictoggle4", command_target::vehicle, command_mode::oneoff },
{ "generictoggle5", command_target::vehicle, command_mode::oneoff },
{ "generictoggle6", command_target::vehicle, command_mode::oneoff },
{ "generictoggle7", command_target::vehicle, command_mode::oneoff },
{ "generictoggle8", command_target::vehicle, command_mode::oneoff },
{ "generictoggle9", command_target::vehicle, command_mode::oneoff },
{ "trainbrakecharging", command_target::vehicle },
{ "trainbrakerelease", command_target::vehicle },
{ "trainbrakefirstservice", command_target::vehicle },
{ "trainbrakeservice", command_target::vehicle },
{ "trainbrakefullservice", command_target::vehicle },
{ "trainbrakehandleoff", command_target::vehicle },
{ "trainbrakeemergency", command_target::vehicle },
{ "trainbrakebasepressureincrease", command_target::vehicle },
{ "trainbrakebasepressuredecrease", command_target::vehicle },
{ "trainbrakebasepressurereset", command_target::vehicle },
{ "trainbrakeoperationtoggle", command_target::vehicle },
{ "manualbrakeincrease", command_target::vehicle },
{ "manualbrakedecrease", command_target::vehicle },
{ "alarmchaintoggle", command_target::vehicle },
{ "wheelspinbrakeactivate", command_target::vehicle },
{ "sandboxactivate", command_target::vehicle },
{ "reverserincrease", command_target::vehicle },
{ "reverserdecrease", command_target::vehicle },
{ "linebreakertoggle", command_target::vehicle },
{ "convertertoggle", command_target::vehicle },
{ "convertertogglelocal", command_target::vehicle },
{ "converteroverloadrelayreset", command_target::vehicle },
{ "compressortoggle", command_target::vehicle },
{ "compressortogglelocal", command_target::vehicle },
{ "motoroverloadrelaythresholdtoggle", command_target::vehicle },
{ "motoroverloadrelayreset", command_target::vehicle },
{ "notchingrelaytoggle", command_target::vehicle },
{ "epbrakecontroltoggle", command_target::vehicle },
{ "brakeactingspeedincrease", command_target::vehicle },
{ "brakeactingspeeddecrease", command_target::vehicle },
{ "brakeloadcompensationincrease", command_target::vehicle },
{ "brakeloadcompensationdecrease", command_target::vehicle },
{ "mubrakingindicatortoggle", command_target::vehicle },
{ "alerteracknowledge", command_target::vehicle },
{ "hornlowactivate", command_target::vehicle },
{ "hornhighactivate", command_target::vehicle },
{ "radiotoggle", command_target::vehicle },
{ "radiochannelincrease", command_target::vehicle },
{ "radiochanneldecrease", command_target::vehicle },
{ "radiostoptest", command_target::vehicle },
// TBD, TODO: make cab change controls entity-centric
{ "cabchangeforward", command_target::vehicle },
{ "cabchangebackward", command_target::vehicle },
{ "viewturn", command_target::entity },
{ "movehorizontal", command_target::entity },
{ "movehorizontalfast", command_target::entity },
{ "movevertical", command_target::entity },
{ "moveverticalfast", command_target::entity },
{ "moveleft", command_target::entity },
{ "moveright", command_target::entity },
{ "moveforward", command_target::entity },
{ "moveback", command_target::entity },
{ "moveup", command_target::entity },
{ "movedown", command_target::entity },
// TBD, TODO: make coupling controls entity-centric
{ "carcouplingincrease", command_target::vehicle },
{ "carcouplingdisconnect", command_target::vehicle },
{ "doortoggleleft", command_target::vehicle },
{ "doortoggleright", command_target::vehicle },
{ "departureannounce", command_target::vehicle },
{ "doorlocktoggle", command_target::vehicle },
{ "pantographcompressorvalvetoggle", command_target::vehicle },
{ "pantographcompressoractivate", command_target::vehicle },
{ "pantographtogglefront", command_target::vehicle },
{ "pantographtogglerear", command_target::vehicle },
{ "pantographlowerall", command_target::vehicle },
{ "heatingtoggle", command_target::vehicle },
{ "lightspresetactivatenext", command_target::vehicle },
{ "lightspresetactivateprevious", command_target::vehicle },
{ "headlighttoggleleft", command_target::vehicle },
{ "headlighttoggleright", command_target::vehicle },
{ "headlighttoggleupper", command_target::vehicle },
{ "redmarkertoggleleft", command_target::vehicle },
{ "redmarkertoggleright", command_target::vehicle },
{ "headlighttogglerearleft", command_target::vehicle },
{ "headlighttogglerearright", command_target::vehicle },
{ "headlighttogglerearupper", command_target::vehicle },
{ "redmarkertogglerearleft", command_target::vehicle },
{ "redmarkertogglerearright", command_target::vehicle },
{ "redmarkerstoggle", command_target::vehicle },
{ "endsignalstoggle", command_target::vehicle },
{ "headlightsdimtoggle", command_target::vehicle },
{ "motorconnectorsopen", command_target::vehicle },
{ "motordisconnect", command_target::vehicle },
{ "interiorlighttoggle", command_target::vehicle },
{ "interiorlightdimtoggle", command_target::vehicle },
{ "instrumentlighttoggle", command_target::vehicle },
{ "generictoggle0", command_target::vehicle },
{ "generictoggle1", command_target::vehicle },
{ "generictoggle2", command_target::vehicle },
{ "generictoggle3", command_target::vehicle },
{ "generictoggle4", command_target::vehicle },
{ "generictoggle5", command_target::vehicle },
{ "generictoggle6", command_target::vehicle },
{ "generictoggle7", command_target::vehicle },
{ "generictoggle8", command_target::vehicle },
{ "generictoggle9", command_target::vehicle },
{ "batterytoggle", command_target::vehicle }
/*
const int k_WalkMode = 73;
*/
};
}

View File

@@ -15,6 +15,8 @@ http://mozilla.org/MPL/2.0/.
enum class user_command {
aidriverenable,
aidriverdisable,
mastercontrollerincrease,
mastercontrollerincreasefast,
mastercontrollerdecrease,
@@ -36,7 +38,12 @@ enum class user_command {
trainbrakefirstservice,
trainbrakeservice,
trainbrakefullservice,
trainbrakehandleoff,
trainbrakeemergency,
trainbrakebasepressureincrease,
trainbrakebasepressuredecrease,
trainbrakebasepressurereset,
trainbrakeoperationtoggle,
manualbrakeincrease,
manualbrakedecrease,
alarmchaintoggle,
@@ -56,38 +63,33 @@ enum class user_command {
epbrakecontroltoggle,
brakeactingspeedincrease,
brakeactingspeeddecrease,
brakeloadcompensationincrease,
brakeloadcompensationdecrease,
mubrakingindicatortoggle,
alerteracknowledge,
hornlowactivate,
hornhighactivate,
radiotoggle,
radiochannelincrease,
radiochanneldecrease,
radiostoptest,
/*
const int k_FailedEngineCutOff = 35;
*/
cabchangeforward,
cabchangebackward,
viewturn,
movevector,
movehorizontal,
movehorizontalfast,
movevertical,
moveverticalfast,
moveleft,
moveright,
moveforward,
moveback,
moveup,
movedown,
moveleftfast,
moverightfast,
moveforwardfast,
movebackfast,
moveupfast,
movedownfast,
/*
const int k_CabForward = 42;
const int k_CabBackward = 43;
const int k_Couple = 44;
const int k_DeCouple = 45;
const int k_ProgramQuit = 46;
// const int k_ProgramPause= 47;
const int k_ProgramHelp = 48;
*/
carcouplingincrease,
carcouplingdisconnect,
doortoggleleft,
doortoggleright,
departureannounce,
@@ -98,9 +100,6 @@ const int k_ProgramHelp = 48;
pantographtogglerear,
pantographlowerall,
heatingtoggle,
/*
// const int k_FreeFlyMode= 59;
*/
lightspresetactivatenext,
lightspresetactivateprevious,
headlighttoggleleft,
@@ -113,16 +112,14 @@ const int k_ProgramHelp = 48;
headlighttogglerearupper,
redmarkertogglerearleft,
redmarkertogglerearright,
redmarkerstoggle,
endsignalstoggle,
headlightsdimtoggle,
motorconnectorsopen,
motordisconnect,
interiorlighttoggle,
interiorlightdimtoggle,
instrumentlighttoggle,
/*
const int k_EndSign = 70;
const int k_Active = 71;
*/
generictoggle0,
generictoggle1,
generictoggle2,
@@ -134,9 +131,7 @@ const int k_Active = 71;
generictoggle8,
generictoggle9,
batterytoggle,
/*
const int k_WalkMode = 73;
*/
none = -1
};
@@ -164,7 +159,7 @@ enum class command_mode {
struct command_description {
std::string name;
command_target target;
command_mode mode;
command_mode mode = command_mode::oneoff;
};
struct command_data {

View File

@@ -214,7 +214,7 @@ gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, g
double const movex = static_cast<double>( Leftstick.x );
double const movez = static_cast<double>( Leftstick.y );
m_relay.post(
user_command::movevector,
user_command::movehorizontal,
reinterpret_cast<std::uint64_t const &>( movex ),
reinterpret_cast<std::uint64_t const &>( movez ),
GLFW_PRESS,
@@ -231,42 +231,6 @@ gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, g
m_triggers = Triggers;
}
void
gamepad_input::process_axis( float const Value, float const Previousvalue, float const Multiplier, user_command Command, std::uint16_t const Recipient ) {
process_axis( Value, Previousvalue, Multiplier, Command, Command, Recipient );
}
void
gamepad_input::process_axis( float const Value, float const Previousvalue, float const Multiplier, user_command Command1, user_command Command2, std::uint16_t const Recipient ) {
user_command command{ Command1 };
if( Value * Multiplier > 0.9 ) {
command = Command2;
}
if( Value * Multiplier > 0.0f ) {
m_relay.post(
command,
0, 0,
GLFW_PRESS,
Recipient
);
}
else {
// if we had movement before but not now, report this as 'button' release
if( Previousvalue != 0.0f ) {
m_relay.post(
command, // doesn't matter which movement 'mode' we report
0, 0,
GLFW_RELEASE,
0
);
}
}
}
void
gamepad_input::process_mode( float const Value, std::uint16_t const Recipient ) {

View File

@@ -65,8 +65,6 @@ private:
// methods
void on_button( gamepad_button const Button, int const Action );
void process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, glm::vec2 const &Triggers );
void process_axis( float const Value, float const Previousvalue, float const Multiplier, user_command Command, std::uint16_t const Recipient );
void process_axis( float const Value, float const Previousvalue, float const Multiplier, user_command Command1, user_command Command2, /*user_command Command3,*/ std::uint16_t const Recipient );
void process_mode( float const Value, std::uint16_t const Recipient );
// members

View File

@@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/.
#include "stdafx.h"
#include "keyboardinput.h"
#include "Logs.h"
#include "Globals.h"
#include "parser.h"
#include "World.h"
@@ -30,6 +31,7 @@ keyboard_input::recall_bindings() {
std::unordered_map<std::string, int> nametokeymap = {
{ "0", GLFW_KEY_0 }, { "1", GLFW_KEY_1 }, { "2", GLFW_KEY_2 }, { "3", GLFW_KEY_3 }, { "4", GLFW_KEY_4 },
{ "5", GLFW_KEY_5 }, { "6", GLFW_KEY_6 }, { "7", GLFW_KEY_7 }, { "8", GLFW_KEY_8 }, { "9", GLFW_KEY_9 },
{ "-", GLFW_KEY_MINUS }, { "=", GLFW_KEY_EQUAL },
{ "a", GLFW_KEY_A }, { "b", GLFW_KEY_B }, { "c", GLFW_KEY_C }, { "d", GLFW_KEY_D }, { "e", GLFW_KEY_E },
{ "f", GLFW_KEY_F }, { "g", GLFW_KEY_G }, { "h", GLFW_KEY_H }, { "i", GLFW_KEY_I }, { "j", GLFW_KEY_J },
{ "k", GLFW_KEY_K }, { "l", GLFW_KEY_L }, { "m", GLFW_KEY_M }, { "n", GLFW_KEY_N }, { "o", GLFW_KEY_O },
@@ -40,6 +42,7 @@ keyboard_input::recall_bindings() {
{ ";", GLFW_KEY_SEMICOLON }, { "'", GLFW_KEY_APOSTROPHE }, { "enter", GLFW_KEY_ENTER },
{ ",", GLFW_KEY_COMMA }, { ".", GLFW_KEY_PERIOD }, { "/", GLFW_KEY_SLASH },
{ "space", GLFW_KEY_SPACE },
{ "insert", GLFW_KEY_INSERT },{ "delete", GLFW_KEY_DELETE }, { "home", GLFW_KEY_HOME }, { "end", GLFW_KEY_END },
// numpad block
{ "num_/", GLFW_KEY_KP_DIVIDE }, { "num_*", GLFW_KEY_KP_MULTIPLY }, { "num_-", GLFW_KEY_KP_SUBTRACT },
{ "num_7", GLFW_KEY_KP_7 }, { "num_8", GLFW_KEY_KP_8 }, { "num_9", GLFW_KEY_KP_9 }, { "num_+", GLFW_KEY_KP_ADD },
@@ -131,16 +134,16 @@ keyboard_input::key( int const Key, int const Action ) {
return false;
}
if( true == update_movement( Key, Action ) ) {
// if the received key was one of movement keys, it's been handled and we don't need to bother further
return true;
}
// store key state
if( Key != -1 ) {
m_keys[ Key ] = Action;
}
if( true == is_movement_key( Key ) ) {
// if the received key was one of movement keys, it's been handled and we don't need to bother further
return true;
}
// include active modifiers for currently pressed key, except if the key is a modifier itself
auto const key =
Key
@@ -164,6 +167,10 @@ void
keyboard_input::default_bindings() {
m_commands = {
// aidriverenable
{ GLFW_KEY_Q | keymodifier::shift },
// aidriverdisable
{ GLFW_KEY_Q },
// mastercontrollerincrease
{ GLFW_KEY_KP_ADD },
// mastercontrollerincreasefast
@@ -206,17 +213,27 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_KP_5 },
// trainbrakefullservice
{ GLFW_KEY_KP_2 },
// trainbrakehandleoff
{ GLFW_KEY_KP_5 | keymodifier::control },
// trainbrakeemergency
{ GLFW_KEY_KP_0 },
// trainbrakebasepressureincrease
{ GLFW_KEY_KP_3 | keymodifier::control },
// trainbrakebasepressuredecrease
{ GLFW_KEY_KP_9 | keymodifier::control },
// trainbrakebasepressurereset
{ GLFW_KEY_KP_6 | keymodifier::control },
// trainbrakeoperationtoggle
{ GLFW_KEY_KP_4 | keymodifier::control },
// manualbrakeincrease
{ GLFW_KEY_KP_1 | keymodifier::control },
// manualbrakedecrease
{ GLFW_KEY_KP_7 | keymodifier::control },
// alarm chain toggle
{ GLFW_KEY_B | keymodifier::shift | keymodifier::control },
// wheelspinbrakeactivate,
// wheelspinbrakeactivate
{ GLFW_KEY_KP_ENTER },
// sandboxactivate,
// sandboxactivate
{ GLFW_KEY_S },
// reverserincrease
{ GLFW_KEY_D },
@@ -246,6 +263,10 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_B | keymodifier::shift },
// brakeactingspeeddecrease
{ GLFW_KEY_B },
// brakeloadcompensationincrease
{ GLFW_KEY_H | keymodifier::shift | keymodifier::control },
// brakeloadcompensationdecrease
{ GLFW_KEY_H | keymodifier::control },
// mubrakingindicatortoggle
{ GLFW_KEY_L | keymodifier::shift },
// alerteracknowledge
@@ -256,11 +277,25 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_A | keymodifier::shift },
// radiotoggle
{ GLFW_KEY_R | keymodifier::control },
// radiochannelincrease
{ GLFW_KEY_R | keymodifier::shift },
// radiochanneldecrease
{ GLFW_KEY_R },
// radiostoptest
{ GLFW_KEY_R | keymodifier::shift | keymodifier::control },
// cabchangeforward
{ GLFW_KEY_HOME },
// cabchangebackward
{ GLFW_KEY_END },
// viewturn
{ -1 },
// movevector
// movehorizontal
{ -1 },
// movehorizontalfast
{ -1 },
// movevertical
{ -1 },
// moveverticalfast
{ -1 },
// moveleft
{ GLFW_KEY_LEFT },
@@ -274,23 +309,11 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_PAGE_UP },
// movedown
{ GLFW_KEY_PAGE_DOWN },
// moveleftfast
{ -1 },
// moverightfast
{ -1 },
// moveforwardfast
{ -1 },
// movebackfast
{ -1 },
// moveupfast
{ -1 },
// movedownfast
{ -1 },
// carcouplingincrease
{ GLFW_KEY_INSERT },
// carcouplingdisconnect
{ GLFW_KEY_DELETE },
/*
const int k_CabForward = 42;
const int k_CabBackward = 43;
const int k_Couple = 44;
const int k_DeCouple = 45;
const int k_ProgramQuit = 46;
// const int k_ProgramPause= 47;
const int k_ProgramHelp = 48;
@@ -342,12 +365,16 @@ const int k_ProgramHelp = 48;
{ GLFW_KEY_Y | keymodifier::control | keymodifier::shift },
// redmarkertogglerearright
{ GLFW_KEY_I | keymodifier::control | keymodifier::shift },
// redmarkerstoggle
{ GLFW_KEY_E | keymodifier::shift },
// endsignalstoggle
{ GLFW_KEY_E },
// headlightsdimtoggle
{ GLFW_KEY_L | keymodifier::control },
// motorconnectorsopen
{ GLFW_KEY_L },
// motordisconnect
{ GLFW_KEY_E | keymodifier::shift },
{ GLFW_KEY_E | keymodifier::control },
// interiorlighttoggle
{ GLFW_KEY_APOSTROPHE },
// interiorlightdimtoggle
@@ -355,11 +382,6 @@ const int k_ProgramHelp = 48;
// instrumentlighttoggle
{ GLFW_KEY_SEMICOLON },
/*
const int k_Univ1 = 66;
const int k_Univ2 = 67;
const int k_Univ3 = 68;
const int k_Univ4 = 69;
const int k_EndSign = 70;
const int k_Active = 71;
*/
// "generictoggle0"
@@ -408,8 +430,7 @@ keyboard_input::bind() {
}
++commandcode;
}
// cache movement key bindings, so we can test them faster in the input loop
// cache movement key bindings
m_bindingscache.forward = m_commands[ static_cast<std::size_t>( user_command::moveforward ) ].binding;
m_bindingscache.back = m_commands[ static_cast<std::size_t>( user_command::moveback ) ].binding;
m_bindingscache.left = m_commands[ static_cast<std::size_t>( user_command::moveleft ) ].binding;
@@ -418,14 +439,10 @@ keyboard_input::bind() {
m_bindingscache.down = m_commands[ static_cast<std::size_t>( user_command::movedown ) ].binding;
}
// NOTE: ugliest code ever, gg
bool
keyboard_input::update_movement( int const Key, int const Action ) {
keyboard_input::is_movement_key( int const Key ) const {
bool shift =
( ( Key == GLFW_KEY_LEFT_SHIFT )
|| ( Key == GLFW_KEY_RIGHT_SHIFT ) );
bool movementkey =
bool const ismovementkey =
( ( Key == m_bindingscache.forward )
|| ( Key == m_bindingscache.back )
|| ( Key == m_bindingscache.left )
@@ -433,93 +450,61 @@ keyboard_input::update_movement( int const Key, int const Action ) {
|| ( Key == m_bindingscache.up )
|| ( Key == m_bindingscache.down ) );
if( false == ( shift || movementkey ) ) { return false; }
return ismovementkey;
}
if( false == shift ) {
// TODO: pass correct entity id once the missing systems are in place
if( Key == m_bindingscache.forward ) {
m_keys[ Key ] = Action;
m_relay.post(
( m_shift ?
user_command::moveforwardfast :
user_command::moveforward ),
0, 0,
m_keys[ m_bindingscache.forward ],
0 );
return true;
}
else if( Key == m_bindingscache.back ) {
m_keys[ Key ] = Action;
m_relay.post(
( m_shift ?
user_command::movebackfast :
user_command::moveback ),
0, 0,
m_keys[ m_bindingscache.back ],
0 );
return true;
}
else if( Key == m_bindingscache.left ) {
m_keys[ Key ] = Action;
m_relay.post(
( m_shift ?
user_command::moveleftfast :
user_command::moveleft ),
0, 0,
m_keys[ m_bindingscache.left ],
0 );
return true;
}
else if( Key == m_bindingscache.right ) {
m_keys[ Key ] = Action;
m_relay.post(
( m_shift ?
user_command::moverightfast :
user_command::moveright ),
0, 0,
m_keys[ m_bindingscache.right ],
0 );
return true;
}
else if( Key == m_bindingscache.up ) {
m_keys[ Key ] = Action;
m_relay.post(
( m_shift ?
user_command::moveupfast :
user_command::moveup ),
0, 0,
m_keys[ m_bindingscache.up ],
0 );
return true;
}
else if( Key == m_bindingscache.down ) {
m_keys[ Key ] = Action;
m_relay.post(
( m_shift ?
user_command::movedownfast :
user_command::movedown ),
0, 0,
m_keys[ m_bindingscache.down ],
0 );
return true;
}
}
else {
// if it's not the movement keys but one of shift keys, we might potentially need to update movement state
if( m_keys[ Key ] == Action ) {
// but not if it's just repeat
return false;
}
// bit of recursion voodoo here, we fake relevant key presses so we don't have to duplicate the code from above
if( m_keys[ m_bindingscache.forward ] != GLFW_RELEASE ) { update_movement( m_bindingscache.forward, m_keys[ m_bindingscache.forward ] ); }
if( m_keys[ m_bindingscache.back ] != GLFW_RELEASE ) { update_movement( m_bindingscache.back, m_keys[ m_bindingscache.back ] ); }
if( m_keys[ m_bindingscache.left ] != GLFW_RELEASE ) { update_movement( m_bindingscache.left, m_keys[ m_bindingscache.left ] ); }
if( m_keys[ m_bindingscache.right ] != GLFW_RELEASE ) { update_movement( m_bindingscache.right, m_keys[ m_bindingscache.right ] ); }
if( m_keys[ m_bindingscache.up ] != GLFW_RELEASE ) { update_movement( m_bindingscache.up, m_keys[ m_bindingscache.up ] ); }
if( m_keys[ m_bindingscache.down ] != GLFW_RELEASE ) { update_movement( m_bindingscache.down, m_keys[ m_bindingscache.down ] ); }
void
keyboard_input::poll() {
glm::vec2 const movementhorizontal {
// x-axis
( Global::shiftState ? 1.f : 0.5f ) *
( m_keys[ m_bindingscache.left ] != GLFW_RELEASE ? -1.f :
m_keys[ m_bindingscache.right ] != GLFW_RELEASE ? 1.f :
0.f ),
// z-axis
( Global::shiftState ? 1.f : 0.5f ) *
( m_keys[ m_bindingscache.forward ] != GLFW_RELEASE ? 1.f :
m_keys[ m_bindingscache.back ] != GLFW_RELEASE ? -1.f :
0.f ) };
if( ( movementhorizontal.x != 0.f || movementhorizontal.y != 0.f )
|| ( m_movementhorizontal.x != 0.f || m_movementhorizontal.y != 0.f ) ) {
double const movexparam = static_cast<double>( movementhorizontal.x );
double const movezparam = static_cast<double>( movementhorizontal.y );
m_relay.post(
( true == Global::ctrlState ?
user_command::movehorizontalfast :
user_command::movehorizontal ),
reinterpret_cast<std::uint64_t const &>( movexparam ),
reinterpret_cast<std::uint64_t const &>( movezparam ),
GLFW_PRESS,
0 );
}
return false;
m_movementhorizontal = movementhorizontal;
float const movementvertical {
// y-axis
( Global::shiftState ? 1.f : 0.5f ) *
( m_keys[ m_bindingscache.up ] != GLFW_RELEASE ? 1.f :
m_keys[ m_bindingscache.down ] != GLFW_RELEASE ? -1.f :
0.f ) };
if( ( movementvertical != 0.f )
|| ( m_movementvertical != 0.f ) ) {
double const moveyparam = static_cast<double>( movementvertical );
m_relay.post(
( true == Global::ctrlState ?
user_command::moveverticalfast :
user_command::movevertical ),
reinterpret_cast<std::uint64_t const &>( moveyparam ),
0,
GLFW_PRESS,
0 );
}
m_movementvertical = movementvertical;
}
//---------------------------------------------------------------------------

View File

@@ -27,7 +27,7 @@ public:
bool
key( int const Key, int const Action );
void
poll() {}
poll();
private:
// types
@@ -61,7 +61,7 @@ private:
void
bind();
bool
update_movement( int const Key, int const Action );
is_movement_key( int const Key ) const;
// members
commandsetup_sequence m_commands;
@@ -70,6 +70,8 @@ private:
bool m_shift{ false };
bool m_ctrl{ false };
bindings_cache m_bindingscache;
glm::vec2 m_movementhorizontal;
float m_movementvertical;
std::array<char, GLFW_KEY_LAST + 1> m_keys;
};

View File

@@ -122,7 +122,7 @@ WyslijNamiary(TDynamicObject const *Vehicle)
r.fPar[7] = 0; // prędkość ruchu Z
r.fPar[8] = Vehicle->MoverParameters->AccS; // przyspieszenie X
r.fPar[9] = Vehicle->MoverParameters->AccN; // przyspieszenie Y //na razie nie
r.fPar[10] = Vehicle->MoverParameters->AccV; // przyspieszenie Z
r.fPar[10] = Vehicle->MoverParameters->AccVert; // przyspieszenie Z
r.fPar[11] = Vehicle->MoverParameters->DistCounter; // przejechana odległość w km
r.fPar[12] = Vehicle->MoverParameters->PipePress; // ciśnienie w PG
r.fPar[13] = Vehicle->MoverParameters->ScndPipePress; // ciśnienie w PZ

View File

@@ -58,11 +58,9 @@ void motiontelemetry::update()
if (!t)
return;
float speed = std::abs(t->Occupied()->V);
float forward = t->Occupied()->AccS;
float forward = t->Occupied()->AccSVBased;
float lateral = t->Occupied()->AccN;
float vertical = t->Occupied()->AccV;
float
float vertical = t->Occupied()->AccVert;
WriteLog("forward: " + std::to_string(forward) + ", lateral: " + std::to_string(lateral) + ", z: " + std::to_string(vertical));
WriteLog("forward: " + std::to_string(forward) + ", lateral: " + std::to_string(lateral) + ", vertical: " + std::to_string(vertical));
}

View File

@@ -121,6 +121,11 @@ basic_cell::update_events() {
// legacy method, updates sounds and polls event launchers within radius around specified point
void
basic_cell::update_sounds() {
auto const deltatime = Timer::GetDeltaRenderTime();
for( auto *sound : m_sounds ) {
sound->play_event();
}
// TBD, TODO: move to sound renderer
for( auto *path : m_paths ) {
// dźwięki pojazdów, również niewidocznych
@@ -1162,6 +1167,17 @@ basic_region::insert_instance( TAnimModel *Instance, scratch_data &Scratchpad )
// inserts provided sound in the region
void
basic_region::insert_sound( sound_source *Sound, scratch_data &Scratchpad ) {
// NOTE: bounding area isn't present/filled until track class and wrapper refactoring is done
auto location = Sound->location();
if( point_inside( location ) ) {
// NOTE: nodes placed outside of region boundaries are discarded
section( location ).insert( Sound );
}
else {
// tracks are guaranteed to hava a name so we can skip the check
ErrorLog( "Bad scenario: sound node \"" + Sound->name() + "\" placed in location outside region bounds (" + to_string( location ) + ")" );
}
}
// inserts provided event launcher in the region

View File

@@ -57,14 +57,30 @@ sound_source::deserialize( cParser &Input, sound_type const Legacytype, int cons
// on the far end the crossfade section extends to the threshold point of the next chunk...
for( std::size_t idx = 0; idx < m_soundchunks.size() - 1; ++idx ) {
m_soundchunks[ idx ].second.fadeout = m_soundchunks[ idx + 1 ].second.threshold;
/*
m_soundchunks[ idx ].second.fadeout =
interpolate<float>(
m_soundchunks[ idx ].second.threshold,
m_soundchunks[ idx + 1 ].second.threshold,
m_crossfaderange * 0.01f );
*/
}
// ...and on the other end from the threshold point back into the range of previous chunk
m_soundchunks.front().second.fadein = std::max( 0, m_soundchunks.front().second.threshold );
// m_soundchunks.front().second.fadein = m_soundchunks.front().second.threshold;
for( std::size_t idx = 1; idx < m_soundchunks.size(); ++idx ) {
auto const previouschunkwidth { m_soundchunks[ idx ].second.threshold - m_soundchunks[ idx - 1 ].second.threshold };
m_soundchunks[ idx ].second.fadein = m_soundchunks[ idx ].second.threshold - 0.01f * m_crossfaderange * previouschunkwidth;
/*
m_soundchunks[ idx ].second.fadein =
interpolate<float>(
m_soundchunks[ idx ].second.threshold,
m_soundchunks[ idx - 1 ].second.threshold,
m_crossfaderange * 0.01f );
*/
}
m_soundchunks.back().second.fadeout = std::max( 100, m_soundchunks.back().second.threshold );
// m_soundchunks.back().second.fadeout = m_soundchunks.back().second.threshold;
// test if the chunk table contains any actual samples while at it
for( auto &soundchunk : m_soundchunks ) {
if( soundchunk.first.buffer != null_handle ) {
@@ -290,6 +306,10 @@ sound_source::play( int const Flags ) {
// if the sound is disabled altogether or nothing can be emitted from this source, no point wasting time
return;
}
// NOTE: we cache the flags early, even if the sound is out of range, to mark activated event sounds
m_flags = Flags;
if( m_range > 0 ) {
auto const cutoffrange { m_range * 5 };
if( glm::length2( location() - glm::dvec3 { Global::pCameraPosition } ) > std::min( 2750.f * 2750.f, cutoffrange * cutoffrange ) ) {
@@ -305,8 +325,6 @@ sound_source::play( int const Flags ) {
m_pitchvariation = 0.01f * static_cast<float>( Random( 97.5, 102.5 ) );
}
m_flags = Flags;
if( sound( sound_id::main ).buffer != null_handle ) {
// basic variant: single main sound, with optional bookends
play_basic();
@@ -352,7 +370,7 @@ sound_source::play_combined() {
// a chunk covers range from fade in point, where it starts rising in volume over crossfade distance,
// lasts until fadeout - crossfade distance point, past which it grows quiet until fade out point where it ends
if( soundpoint < soundchunk.second.fadein ) { break; }
if( soundpoint > soundchunk.second.fadeout ) { continue; }
if( soundpoint >= soundchunk.second.fadeout ) { continue; }
if( ( soundchunk.first.playing > 0 )
|| ( soundchunk.first.buffer == null_handle ) ) {
@@ -402,12 +420,26 @@ sound_source::compute_combined_point() const {
) * 100.f;
}
// maintains playback of sounds started by event
void
sound_source::play_event() {
if( true == TestFlag( m_flags, ( sound_flags::event | sound_flags::looping ) ) ) {
// events can potentially start scenery sounds out of the sound's audible range
// such sounds are stopped on renderer side, but unless stopped by the simulation keep their activation flags
// we use this to discern event-started sounds which should be re-activated if the listener gets close enough
play( m_flags );
}
}
// stops currently active play commands controlled by this emitter
void
sound_source::stop( bool const Skipend ) {
// if the source was stopped on simulation side, we should play the opening bookend next time it's activated
m_playbeginning = true;
// clear the event flags to discern between manual stop and out-of-range/sound-end stop
m_flags = 0;
if( false == is_playing() ) { return; }
@@ -549,7 +581,7 @@ sound_source::update_combined( audio::openal_source &Source ) {
auto const soundpoint { compute_combined_point() };
auto const &soundchunk { m_soundchunks[ soundhandle ^ sound_id::chunk ] };
if( ( soundpoint < soundchunk.second.fadein )
|| ( soundpoint > soundchunk.second.fadeout ) ) {
|| ( soundpoint >= soundchunk.second.fadeout ) ) {
Source.stop();
update_counter( soundhandle, -1 );
return;
@@ -666,7 +698,6 @@ sound_source::update_crossfade( sound_handle const Chunk ) {
m_properties.pitch = 1.f;
}
}
// if there's no crossfade sections, our work is done
if( m_crossfaderange == 0 ) { return; }

12
sound.h
View File

@@ -30,7 +30,8 @@ enum sound_parameters {
enum sound_flags {
looping = 0x1, // the main sample will be looping; implied for multi-sounds
exclusive = 0x2 // the source won't dispatch more than one active instance of the sound; implied for multi-sounds
exclusive = 0x2, // the source won't dispatch more than one active instance of the sound; implied for multi-sounds
event = 0x80 // sound was activated by an event; we should keep note of the activation state for the update() calls it may receive
};
enum class sound_placement {
@@ -64,6 +65,9 @@ public:
// issues contextual play commands for the audio renderer
void
play( int const Flags = 0 );
// maintains playback of sounds started by event
void
play_event();
// stops currently active play commands controlled by this emitter
void
stop( bool const Skipend = false );
@@ -194,15 +198,15 @@ private:
sound_placement m_placement;
float m_range { 50.f }; // audible range of the emitted sounds
std::string m_name;
int m_flags { 0 }; // requested playback parameters
int m_flags {}; // requested playback parameters
sound_properties m_properties; // current properties of the emitted sounds
float m_pitchvariation { 0.f }; // emitter-specific shift in base pitch
float m_pitchvariation {}; // emitter-specific shift in base pitch
bool m_stop { false }; // indicates active sample instances should be terminated
bool m_playbeginning { true }; // indicates started sounds should be preceeded by opening bookend if there's one
std::array<sound_data, 3> m_sounds { {} }; // basic sounds emitted by the source, main and optional bookends
std::vector<soundchunk_pair> m_soundchunks; // table of samples activated when associated variable is within certain range
bool m_soundchunksempty { true }; // helper, cached check whether sample table is linked with any actual samples
int m_crossfaderange {}; // range of transition from one chunk to another
int m_crossfaderange {}; // range of transition from one chunk to another
};
// owner setter/getter

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 17
#define VERSION_MINOR 1231
#define VERSION_MAJOR 18
#define VERSION_MINOR 114
#define VERSION_REVISION 0