From 886f0dad0f93303f0b10c7fca5a570dc53f80572 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 1 Apr 2017 13:56:18 +0200 Subject: [PATCH 01/12] glfw key callback cleanup --- EU07.cpp | 39 --------------------------------------- McZapkie/MOVER.h | 2 +- World.cpp | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 40 deletions(-) diff --git a/EU07.cpp b/EU07.cpp index e869980d..09dacf5b 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -144,45 +144,6 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo break; } #endif - case GLFW_KEY_ESCAPE: { -/* - if( ( DebugModeFlag ) //[Esc] pauzuje tylko bez Debugmode - && ( Global::iPause == 0 ) ) { // but unpausing should work always - - break; - } -*/ - if( Global::iPause & 1 ) // jeśli pauza startowa - Global::iPause &= ~1; // odpauzowanie, gdy po wczytaniu miało nie startować - else if( !( Global::iMultiplayer & 2 ) ) // w multiplayerze pauza nie ma sensu - if( !Global::ctrlState ) // z [Ctrl] to radiostop jest - Global::iPause ^= 2; // zmiana stanu zapauzowania - if( Global::iPause ) {// jak pauza - Global::iTextMode = GLFW_KEY_F1; // to wyświetlić zegar i informację - } - break; - } - case GLFW_KEY_F7: - if( DebugModeFlag ) { - - if( Global::ctrlState ) { - // ctrl + f7 toggles static daylight - World.ToggleDaylight(); - break; - } - // f7: wireframe toggle - // siatki wyświetlane tyko w trybie testowym - Global::bWireFrame = !Global::bWireFrame; - if( true == Global::bWireFrame ) { - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - } - else { - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - } - ++Global::iReCompile; // odświeżyć siatki - // Ra: jeszcze usunąć siatki ze skompilowanych obiektów! - } - break; } } else if( action == GLFW_RELEASE ) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index aa11d20b..6d7d2c40 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -754,7 +754,7 @@ public: double DoorStayOpen = 0.0; /*jak dlugo otwarte w przypadku DoorCloseCtrl=2*/ bool DoorClosureWarning = false; /*czy jest ostrzeganie przed zamknieciem*/ double DoorOpenSpeed = 1.0; double DoorCloseSpeed = 1.0; /*predkosc otwierania i zamykania w j.u. */ - double DoorMaxShiftL = 0.5; double DoorMaxShiftR = 0.5; double DoorMaxPlugShift = 0.5;/*szerokosc otwarcia lub kat*/ + double DoorMaxShiftL = 0.5; double DoorMaxShiftR = 0.5; double DoorMaxPlugShift = 0.1;/*szerokosc otwarcia lub kat*/ int DoorOpenMethod = 2; /*sposob otwarcia - 1: przesuwne, 2: obrotowe, 3: trójelementowe*/ double PlatformSpeed = 0.25; /*szybkosc stopnia*/ double PlatformMaxShift = 0.5; /*wysuniecie stopnia*/ diff --git a/World.cpp b/World.cpp index 421acbc8..7feafa8c 100644 --- a/World.cpp +++ b/World.cpp @@ -604,6 +604,32 @@ void TWorld::OnKeyDown(int cKey) } break; } + case GLFW_KEY_F7: { + // debug mode functions + if( DebugModeFlag ) { + + if( Global::ctrlState ) { + // ctrl + f7 toggles static daylight + ToggleDaylight(); + break; + } + else { + // f7: wireframe toggle + Global::bWireFrame = !Global::bWireFrame; + if( true == Global::bWireFrame ) { + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + } + else { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } +/* + ++Global::iReCompile; // odświeżyć siatki + // Ra: jeszcze usunąć siatki ze skompilowanych obiektów! +*/ + } + } + break; + } case GLFW_KEY_F8: { Global::iTextMode = cKey; // FPS @@ -667,6 +693,16 @@ void TWorld::OnKeyDown(int cKey) // else if (cKey=='3') Global::iWriteLogEnabled^=4; //wypisywanie nazw torów } } + else if( cKey == GLFW_KEY_ESCAPE ) { + // toggle pause + if( Global::iPause & 1 ) // jeśli pauza startowa + Global::iPause &= ~1; // odpauzowanie, gdy po wczytaniu miało nie startować + else if( !( Global::iMultiplayer & 2 ) ) // w multiplayerze pauza nie ma sensu + Global::iPause ^= 2; // zmiana stanu zapauzowania + if( Global::iPause ) {// jak pauza + Global::iTextMode = GLFW_KEY_F1; // to wyświetlić zegar i informację + } + } else if( Global::ctrlState && cKey == GLFW_KEY_PAUSE ) //[Ctrl]+[Break] { // hamowanie wszystkich pojazdów w okolicy if (Controlled->MoverParameters->Radio) From e6f488ed6f9af316185e031d77c36c38b743b5ea Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Fri, 7 Apr 2017 00:36:07 +0200 Subject: [PATCH 02/12] control messaging system, keyboard and gamepad inputs --- Camera.cpp | 475 +++++++++++++++++++++++++++++++++---- Camera.h | 17 +- Driver.cpp | 14 +- EU07.cpp | 23 +- EvLaunch.cpp | 4 +- Ground.cpp | 2 +- Model3d.cpp | 14 +- Train.cpp | 512 +++++++++++++++++++++++++++++++++++++--- Train.h | 20 +- World.cpp | 55 +++-- World.h | 3 +- command.cpp | 300 +++++++++++++++++++++++ command.h | 196 +++++++++++++++ gamepadinput.cpp | 352 +++++++++++++++++++++++++++ gamepadinput.h | 86 +++++++ keyboardinput.cpp | 204 ++++++++++++++++ keyboardinput.h | 61 +++++ maszyna.vcxproj.filters | 38 ++- moon.cpp | 6 +- sun.cpp | 6 +- 20 files changed, 2237 insertions(+), 151 deletions(-) create mode 100644 command.cpp create mode 100644 command.h create mode 100644 gamepadinput.cpp create mode 100644 gamepadinput.h create mode 100644 keyboardinput.cpp create mode 100644 keyboardinput.h diff --git a/Camera.cpp b/Camera.cpp index cceed381..75297e4f 100644 --- a/Camera.cpp +++ b/Camera.cpp @@ -15,23 +15,19 @@ http://mozilla.org/MPL/2.0/. #include "Console.h" #include "Timer.h" #include "mover.h" + //--------------------------------------------------------------------------- // TViewPyramid TCamera::OrgViewPyramid; //={vector3(-1,1,1),vector3(1,1,1),vector3(-1,-1,1),vector3(1,-1,1),vector3(0,0,0)}; -const vector3 OrgCrossPos = vector3(0, -10, 0); - void TCamera::Init(vector3 NPos, vector3 NAngle) { - pOffset = vector3(-0.0, 0, 0); vUp = vector3(0, 1, 0); // pOffset= vector3(-0.8,0,0); - CrossPos = OrgCrossPos; CrossDist = 10; Velocity = vector3(0, 0, 0); - OldVelocity = vector3(0, 0, 0); Pitch = NAngle.x; Yaw = NAngle.y; Roll = NAngle.z; @@ -54,52 +50,445 @@ void TCamera::OnCursorMove(double x, double y) 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ę - // Fix(Yaw,-M_PI,M_PI); + } +} + +void +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 ); + + switch( Command.command ) { + + case user_command::viewturn: { + + OnCursorMove( + reinterpret_cast( Command.param1 ) * 0.005 * Global::fMouseXScale / Global::ZoomFactor, + reinterpret_cast( Command.param2 ) * -0.01 * Global::fMouseYScale / Global::ZoomFactor ); + break; + } + + case user_command::movevector: { + + auto const movespeed = + ( Type == tp_Free ? + runspeed * speedmultiplier : + walkspeed ); + + // left-right + double const movex = reinterpret_cast( 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; + } + // 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 ); + + // forward-back + double const movez = reinterpret_cast( 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 ); + break; + } + + case user_command::moveforward: { + + 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: { + + if( Command.action != GLFW_RELEASE ) { + m_keys.back = true; + m_moverate.z = + ( Type == tp_Free ? + walkspeed * speedmultiplier : + walkspeed ); + } + else { + m_keys.back = false; + } + break; + } + + 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; + } +/* + case user_command::moveforwardfastest: { + + if( Command.action != GLFW_RELEASE ) { + m_keys.forward = true; + m_moverate.z = + ( Type == tp_Free ? + 8.0 : + 0.8 ); + } + else { + m_keys.forward = false; + } + break; + } + + case user_command::movebackfastest: { + + if( Command.action != GLFW_RELEASE ) { + m_keys.back = true; + m_moverate.z = + ( Type == tp_Free ? + 8.0 : + 0.8 ); + } + else { + m_keys.back = false; + } + break; + } + + case user_command::moveleftfastest: { + + if( Command.action != GLFW_RELEASE ) { + m_keys.left = true; + m_moverate.x = + ( Type == tp_Free ? + 8.0 : + 0.8 ); + } + else { + m_keys.left = false; + } + break; + } + + case user_command::moverightfastest: { + + if( Command.action != GLFW_RELEASE ) { + m_keys.right = true; + m_moverate.x = + ( Type == tp_Free ? + 8.0 : + 0.8 ); + } + else { + m_keys.right = false; + } + break; + } + + case user_command::moveupfastest: { + + if( Command.action != GLFW_RELEASE ) { + m_keys.up = true; + m_moverate.y = + ( Type == tp_Free ? + 8.0 : + 0.8 ); + } + else { + m_keys.up = false; + } + break; + } + + case user_command::movedownfastest: { + + if( Command.action != GLFW_RELEASE ) { + m_keys.down = true; + m_moverate.y = + ( Type == tp_Free ? + 8.0 : + 0.8 ); + } + else { + m_keys.down = false; + } + break; + } +*/ } } void TCamera::Update() { - // ABu: zmiana i uniezaleznienie predkosci od FPS - double a = ( Global::shiftState ? 5.00 : 1.00); - if (Global::ctrlState) - a = a * 100; - // OldVelocity=Velocity; - if (FreeFlyModeFlag == true) - Type = tp_Free; - else - Type = tp_Follow; - if (Type == tp_Free) - { - if (Console::Pressed(Global::Keys[k_MechUp])) - Velocity.y += a; - if (Console::Pressed(Global::Keys[k_MechDown])) - Velocity.y -= a; + if( FreeFlyModeFlag == true ) { Type = tp_Free; } + else { Type = tp_Follow; } + + // check for sent user commands + // NOTE: this is a temporary arrangement, for the transition period from old command setup to the new one + // ultimately we'll need to track position of camera/driver for all human entities present in the scenario + command_data command; + // NOTE: currently we're only storing commands for local entity and there's no id system in place, + // so we're supplying 'default' entity id of 0 + while( simulation::Commands.pop( command, static_cast( command_target::entity ) | 0 ) ) { + + OnCommand( command ); + } + + 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 += a; - if (Console::Pressed(Global::Keys[k_MechLeft])) - Velocity.x -= a; - if (Console::Pressed(Global::Keys[k_MechForward])) - Velocity.z -= a; - if (Console::Pressed(Global::Keys[k_MechBackward])) - Velocity.z += a; - // gora-dol - // if (Console::Pressed(GLFW_KEY_KP_9)) Pos.y+=0.1; - // if (Console::Pressed(GLFW_KEY_KP_3)) Pos.y-=0.1; - - // McZapkie: zeby nie hustalo przy malym FPS: - // Velocity= (Velocity+OldVelocity)/2; - // matrix4x4 mat; - vector3 Vec = Velocity; - Vec.RotateY(Yaw); - Pos = Pos + Vec * Timer::GetDeltaRenderTime(); // czas bez pauzy - Velocity = Velocity / 2; // płynne hamowanie ruchu - // double tmp= 10*DeltaTime; - // Velocity+= -Velocity*10 * Timer::GetDeltaTime();//( tmp<1 ? tmp : 1 ); - // Type= tp_Free; + 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 ) ) { + // 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 ); + } +#endif + + if( Type == tp_Free ) { + vector3 Vec = Velocity; + Vec.RotateY( Yaw ); + Pos += Vec * 5.0 * deltatime; + } + else { + + } +/* + if( deltatime < 1.0 / 20.0 ) { + // płynne hamowanie ruchu + Velocity -= Velocity * 20.0 * deltatime; + } + else { + // instant stop + Velocity.Zero(); + } + if( std::abs( Velocity.x ) < 0.01 ) { Velocity.x = 0.0; } + if( std::abs( Velocity.y ) < 0.01 ) { Velocity.y = 0.0; } + if( std::abs( Velocity.z ) < 0.01 ) { Velocity.z = 0.0; } +*/ +/* + Velocity *= 0.5; + if( std::abs( Velocity.x ) < 0.01 ) { Velocity.x = 0.0; } + if( std::abs( Velocity.y ) < 0.01 ) { Velocity.y = 0.0; } + if( std::abs( Velocity.z ) < 0.01 ) { Velocity.z = 0.0; } +*/ } vector3 TCamera::GetDirection() diff --git a/Camera.h b/Camera.h index ebc98a7a..c9ab5e05 100644 --- a/Camera.h +++ b/Camera.h @@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/. #include "dumb3d.h" #include "dynobj.h" +#include "command.h" using namespace Math3D; @@ -25,7 +26,16 @@ enum TCameraType class TCamera { private: - vector3 pOffset; // nie używane (zerowe) + 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 double Pitch; @@ -36,7 +46,6 @@ class TCamera vector3 LookAt; // współrzędne punktu, na który ma patrzeć vector3 vUp; vector3 Velocity; - vector3 OldVelocity; // lepiej usredniac zeby nie bylo rozbiezne przy malym FPS vector3 CrossPos; double CrossDist; void Init(vector3 NPos, vector3 NAngle); @@ -44,10 +53,10 @@ class TCamera { Pitch = Yaw = Roll = 0; }; - void OnCursorMove(double x, double y); + void OnCursorMove(double const x, double const y); + void OnCommand( command_data const &Command ); void Update(); vector3 GetDirection(); - // vector3 inline GetCrossPos() { return Pos+GetDirection()*CrossDist+CrossPos; }; bool SetMatrix(); bool SetMatrix(glm::mat4 &Matrix); void SetCabMatrix( vector3 &p ); diff --git a/Driver.cpp b/Driver.cpp index e2dbc091..5b88f354 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -828,12 +828,12 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN #if LOGSTOPS WriteLog( pVehicle->asName + " as " + TrainParams->TrainName - + ": at " + std::to_string(Simulation::Time.data().wHour) + ":" + std::to_string(Simulation::Time.data().wMinute) + + ": at " + std::to_string(simulation::Time.data().wHour) + ":" + std::to_string(simulation::Time.data().wMinute) + " skipped " + asNextStop); // informacja #endif // przy jakim dystansie (stanie licznika) ma przesunąć na następny postój fLastStopExpDist = mvOccupied->DistCounter + 0.250 + 0.001 * fLength; - TrainParams->UpdateMTable( Simulation::Time, asNextStop ); + TrainParams->UpdateMTable( simulation::Time, asNextStop ); TrainParams->StationIndexInc(); // przejście do następnej asNextStop = TrainParams->NextStop(); // pobranie kolejnego miejsca zatrzymania // TableClear(); //aby od nowa sprawdziło W4 z inną nazwą już - to nie @@ -930,7 +930,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN // niezależne od sposobu obsługi drzwi, bo // opóźnia również kierownika } - if (TrainParams->UpdateMTable( Simulation::Time, asNextStop) ) + if (TrainParams->UpdateMTable( simulation::Time, asNextStop) ) { // to się wykona tylko raz po zatrzymaniu na W4 if (TrainParams->CheckTrainLatency() < 0.0) iDrivigFlags |= moveLate; // odnotowano spóźnienie @@ -976,7 +976,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN if (TrainParams->StationIndex < TrainParams->StationCount) { // jeśli są dalsze stacje, czekamy do godziny odjazdu - if (TrainParams->IsTimeToGo(Simulation::Time.data().wHour, Simulation::Time.data().wMinute)) + if (TrainParams->IsTimeToGo(simulation::Time.data().wHour, simulation::Time.data().wMinute)) { // z dalszą akcją czekamy do godziny odjazdu /* potencjalny problem z ruszaniem z w4 if (TrainParams->CheckTrainLatency() < 0) @@ -995,7 +995,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN #if LOGSTOPS WriteLog( pVehicle->asName + " as " + TrainParams->TrainName - + ": at " + std::to_string(Simulation::Time.data().wHour) + ":" + std::to_string(Simulation::Time.data().wMinute) + + ": at " + std::to_string(simulation::Time.data().wHour) + ":" + std::to_string(simulation::Time.data().wMinute) + " next " + asNextStop); // informacja #endif if (int(floor(sSpeedTable[i].evEvent->ValueGet(1))) & 1) @@ -1022,7 +1022,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN #if LOGSTOPS WriteLog( pVehicle->asName + " as " + TrainParams->TrainName - + ": at " + std::to_string(Simulation::Time.data().wHour) + ":" + std::to_string(Simulation::Time.data().wMinute) + + ": at " + std::to_string(simulation::Time.data().wHour) + ":" + std::to_string(simulation::Time.data().wMinute) + " end of route."); // informacja #endif asNextStop = TrainParams->NextStop(); // informacja o końcu trasy @@ -2865,7 +2865,7 @@ bool TController::PutCommand(std::string NewCommand, double NewValue1, double Ne } else { // inicjacja pierwszego przystanku i pobranie jego nazwy - TrainParams->UpdateMTable( Simulation::Time, TrainParams->NextStationName ); + TrainParams->UpdateMTable( simulation::Time, TrainParams->NextStationName ); TrainParams->StationIndexInc(); // przejście do następnej iStationStart = TrainParams->StationIndex; asNextStop = TrainParams->NextStop(); diff --git a/EU07.cpp b/EU07.cpp index 09dacf5b..b69a5398 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -23,6 +23,8 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others #include "Globals.h" #include "Logs.h" +#include "keyboardinput.h" +#include "gamepadinput.h" #include "Console.h" #include "PyInt.h" #include "World.h" @@ -60,6 +62,13 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others TWorld World; +namespace input { + +keyboard_input Keyboard; +gamepad_input Gamepad; + +} + #ifdef CAN_I_HAS_LIBPNG void screenshot_save_thread( char *img ) { @@ -113,12 +122,17 @@ void window_resize_callback(GLFWwindow *window, int w, int h) void cursor_pos_callback(GLFWwindow *window, double x, double y) { + input::Keyboard.mouse( x, y ); +#ifdef EU07_USE_OLD_COMMAND_SYSTEM World.OnMouseMove(x * 0.005, y * 0.01); +#endif glfwSetCursorPos(window, 0.0, 0.0); } void key_callback( GLFWwindow *window, int key, int scancode, int action, int mods ) { + input::Keyboard.key( key, action ); + Global::shiftState = ( mods & GLFW_MOD_SHIFT ) ? true : false; Global::ctrlState = ( mods & GLFW_MOD_CONTROL ) ? true : false; @@ -144,6 +158,7 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo break; } #endif + default: { break; } } } else if( action == GLFW_RELEASE ) @@ -326,6 +341,7 @@ int main(int argc, char *argv[]) return -1; } + input::Gamepad.init(); Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów if (!World.Init(window)) @@ -335,9 +351,10 @@ int main(int argc, char *argv[]) } Console *pConsole = new Console(); // Ra: nie wiem, czy ma to sens, ale jakoś zainicjowac trzeba - +/* if( !joyGetNumDevs() ) WriteLog( "No joystick" ); +*/ if( Global::iModifyTGA < 0 ) { // tylko modyfikacja TGA, bez uruchamiania symulacji Global::iMaxTextureSize = 64; //żeby nie zamulać pamięci World.ModifyTGA(); // rekurencyjne przeglądanie katalogów @@ -354,7 +371,8 @@ int main(int argc, char *argv[]) && World.Update() && GfxRenderer.Render()) { - glfwPollEvents(); + glfwPollEvents(); + input::Gamepad.poll(); } Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej) } @@ -364,5 +382,6 @@ int main(int argc, char *argv[]) glfwDestroyWindow(window); glfwTerminate(); + return 0; } diff --git a/EvLaunch.cpp b/EvLaunch.cpp index 28789d14..4fda3368 100644 --- a/EvLaunch.cpp +++ b/EvLaunch.cpp @@ -177,9 +177,9 @@ bool TEventLauncher::Render() } else { // jeśli nie cykliczny, to sprawdzić czas - if (Simulation::Time.data().wHour == iHour) + if (simulation::Time.data().wHour == iHour) { - if (Simulation::Time.data().wMinute == iMinute) + if (simulation::Time.data().wMinute == iMinute) { // zgodność czasu uruchomienia if (UpdatedTime < 10) { diff --git a/Ground.cpp b/Ground.cpp index a282326c..393f2dbc 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -2826,7 +2826,7 @@ bool TGround::Init(std::string File) cParser timeparser( token ); timeparser.getTokens( 2, false, ":" ); - auto &time = Simulation::Time.data(); + auto &time = simulation::Time.data(); timeparser >> time.wHour >> time.wMinute; diff --git a/Model3d.cpp b/Model3d.cpp index 64df1b84..d77e1204 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -956,22 +956,22 @@ void TSubModel::RaAnimation(TAnimType a) glRotatef(v_Angles.z, 0.0f, 0.0f, 1.0f); break; case at_SecondsJump: // sekundy z przeskokiem - glRotatef(Simulation::Time.data().wSecond * 6.0, 0.0, 1.0, 0.0); + glRotatef(simulation::Time.data().wSecond * 6.0, 0.0, 1.0, 0.0); break; case at_MinutesJump: // minuty z przeskokiem - glRotatef(Simulation::Time.data().wMinute * 6.0, 0.0, 1.0, 0.0); + glRotatef(simulation::Time.data().wMinute * 6.0, 0.0, 1.0, 0.0); break; case at_HoursJump: // godziny skokowo 12h/360° - glRotatef(Simulation::Time.data().wHour * 30.0 * 0.5, 0.0, 1.0, 0.0); + glRotatef(simulation::Time.data().wHour * 30.0 * 0.5, 0.0, 1.0, 0.0); break; case at_Hours24Jump: // godziny skokowo 24h/360° - glRotatef(Simulation::Time.data().wHour * 15.0 * 0.25, 0.0, 1.0, 0.0); + glRotatef(simulation::Time.data().wHour * 15.0 * 0.25, 0.0, 1.0, 0.0); break; case at_Seconds: // sekundy płynnie - glRotatef(Simulation::Time.second() * 6.0, 0.0, 1.0, 0.0); + glRotatef(simulation::Time.second() * 6.0, 0.0, 1.0, 0.0); break; case at_Minutes: // minuty płynnie - glRotatef(Simulation::Time.data().wMinute * 6.0 + Simulation::Time.second() * 0.1, 0.0, 1.0, 0.0); + glRotatef(simulation::Time.data().wMinute * 6.0 + simulation::Time.second() * 0.1, 0.0, 1.0, 0.0); break; case at_Hours: // godziny płynnie 12h/360° glRotatef(2.0 * Global::fTimeAngleDeg, 0.0, 1.0, 0.0); @@ -996,7 +996,7 @@ void TSubModel::RaAnimation(TAnimType a) } break; case at_Wind: // ruch pod wpływem wiatru (wiatr będziemy liczyć potem...) - glRotated(1.5 * std::sin(M_PI * Simulation::Time.second() / 6.0), 0.0, 1.0, 0.0); + glRotated(1.5 * std::sin(M_PI * simulation::Time.second() / 6.0), 0.0, 1.0, 0.0); break; case at_Sky: // animacja nieba glRotated(Global::fLatitudeDeg, 1.0, 0.0, 0.0); // ustawienie osi OY na północ diff --git a/Train.cpp b/Train.cpp index ac3e74f8..43ad864a 100644 --- a/Train.cpp +++ b/Train.cpp @@ -13,7 +13,6 @@ http://mozilla.org/MPL/2.0/. */ #include "stdafx.h" - #include "Train.h" #include "Globals.h" @@ -22,12 +21,6 @@ http://mozilla.org/MPL/2.0/. #include "Timer.h" #include "Driver.h" #include "Console.h" -#include "McZapkie\hamulce.h" -#include "McZapkie\MOVER.h" -#include "Camera.h" -//--------------------------------------------------------------------------- - -using namespace Timer; TCab::TCab() { @@ -391,13 +384,390 @@ PyObject *TTrain::GetTrainState() { PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( driver->ActualProximityDist ) ); PyDict_SetItemString( dict, "trainnumber", PyGetString( driver->TrainName().c_str() ) ); // world state data - PyDict_SetItemString( dict, "hours", PyGetInt( Simulation::Time.data().wHour ) ); - PyDict_SetItemString( dict, "minutes", PyGetInt( Simulation::Time.data().wMinute ) ); - PyDict_SetItemString( dict, "seconds", PyGetInt( Simulation::Time.second() ) ); + PyDict_SetItemString( dict, "hours", PyGetInt( simulation::Time.data().wHour ) ); + PyDict_SetItemString( dict, "minutes", PyGetInt( simulation::Time.data().wMinute ) ); + PyDict_SetItemString( dict, "seconds", PyGetInt( simulation::Time.second() ) ); return dict; } +void +TTrain::OnCommand( command_data const &Command ) { + + bool const isEztOer = + ( ( mvControlled->TrainType == dt_EZT ) + && ( mvOccupied->BrakeSubsystem == ss_ESt ) + && ( mvControlled->Battery == true ) + && ( mvControlled->EpFuse == true ) + && ( mvControlled->ActiveDir != 0 ) ); // od yB + + switch( Command.command ) { + + case user_command::mastercontrollerincrease: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvControlled->IncMainCtrl( 1 ) ) { + // sound feedback + play_sound( dsbNastawnikJazdy ); + } + } + break; + } + + case user_command::mastercontrollerincreasefast: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvControlled->IncMainCtrl( 2 ) ) { + // sound feedback + play_sound( dsbNastawnikJazdy ); + } + } + break; + } + + case user_command::mastercontrollerdecrease: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvControlled->DecMainCtrl( 1 ) ) { + // sound feedback + play_sound( dsbNastawnikJazdy ); + } + } + break; + } + + case user_command::mastercontrollerdecreasefast: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvControlled->DecMainCtrl( 2 ) ) { + // sound feedback + play_sound( dsbNastawnikJazdy ); + } + } + break; + } + + case user_command::secondcontrollerincrease: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvControlled->ShuntMode ) { + mvControlled->AnPos += ( Command.time_delta * 0.75f ); + if( mvControlled->AnPos > 1 ) + mvControlled->AnPos = 1; + } + else if( mvControlled->IncScndCtrl( 1 ) ) { + // sound feedback + play_sound( dsbNastawnikBocz, dsbNastawnikJazdy ); + } + } + break; + } + + case user_command::secondcontrollerincreasefast: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvControlled->IncScndCtrl( 2 ) ) { + // sound feedback + play_sound( dsbNastawnikBocz, dsbNastawnikJazdy ); + } + } + break; + } + + case user_command::secondcontrollerdecrease: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvControlled->ShuntMode ) { + mvControlled->AnPos -= ( Command.time_delta * 0.75f ); + if( mvControlled->AnPos > 1 ) + mvControlled->AnPos = 1; + } + else if( mvControlled->DecScndCtrl( 1 ) ) { + // sound feedback + play_sound( dsbNastawnikBocz, dsbNastawnikJazdy ); + } + } + break; + } + + case user_command::secondcontrollerdecreasefast: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvControlled->DecScndCtrl( 2 ) ) { + // sound feedback + play_sound( dsbNastawnikBocz, dsbNastawnikJazdy ); + } + } + break; + } + + case user_command::independentbrakeincrease: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvOccupied->LocalBrake != ManualBrake ) { + mvOccupied->IncLocalBrakeLevel( 1 ); + } + } + break; + } + + case user_command::independentbrakeincreasefast: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvOccupied->LocalBrake != ManualBrake ) { + mvOccupied->IncLocalBrakeLevel( 2 ); + } + } + break; + } + + case user_command::independentbrakedecrease: { + + if( Command.action != GLFW_RELEASE ) { + + if( ( mvOccupied->LocalBrake != ManualBrake ) + // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku - odhamować jakoś trzeba + // TODO: sort AI out so it doesn't do things it doesn't have equipment for + || ( mvOccupied->LocalBrakePos != 0 ) ) { + mvOccupied->DecLocalBrakeLevel( 1 ); + } + } + break; + } + + case user_command::independentbrakedecreasefast: { + + if( Command.action != GLFW_RELEASE ) { + + if( ( mvOccupied->LocalBrake != ManualBrake ) + // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku - odhamować jakoś trzeba + // TODO: sort AI out so it doesn't do things it doesn't have equipment for + || ( mvOccupied->LocalBrakePos != 0 ) ) { + mvOccupied->DecLocalBrakeLevel( 2 ); + } + } + break; + } + + case user_command::independentbrakebailoff: { + // TODO: check if this set of conditions can be simplified. + // it'd be more flexible to have an attribute indicating whether bail off position is supported + if( ( mvControlled->TrainType != dt_EZT ) + && ( ( mvControlled->EngineType == ElectricSeriesMotor ) + || ( mvControlled->EngineType == DieselElectric ) + || ( mvControlled->EngineType == ElectricInductionMotor ) ) + && ( mvOccupied->BrakeCtrlPosNo > 0 ) ) { + + if( Command.action != GLFW_RELEASE ) { + // press or hold + ggReleaserButton.UpdateValue( 1 ); + mvOccupied->BrakeReleaser( 1 ); + } + else { + // release + ggReleaserButton.UpdateValue( 0 ); + mvOccupied->BrakeReleaser( 0 ); + } + } + break; + } + + case user_command::trainbrakeincrease: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvOccupied->BrakeHandle == FV4a ) { + mvOccupied->BrakeLevelAdd( 0.1 /*15.0 * Command.time_delta*/ ); + } + else { + if( mvOccupied->BrakeLevelAdd( Global::fBrakeStep ) ) { + // nieodpowiedni warunek; true, jeśli można dalej kręcić + keybrakecount = 0; + if( ( isEztOer ) && ( mvOccupied->BrakeCtrlPos < 3 ) ) { + // Ra: uzależnić dźwięk od zmiany stanu EP, nie od klawisza + play_sound( dsbPneumaticSwitch ); + } + } + } + } + break; + } + + case user_command::trainbrakedecrease: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvOccupied->BrakeHandle == FV4a ) { + mvOccupied->BrakeLevelAdd( -0.1 /*-15.0 * Command.time_delta*/ ); + } + else { + // nową wersję dostarczył ZiomalCl ("fixed looped sound in ezt when using NUM_9 key") + if( ( mvOccupied->BrakeCtrlPos > -1 ) + || ( keybrakecount > 1 ) ) { + + if( ( isEztOer ) + && ( mvControlled->Mains ) + && ( mvOccupied->BrakeCtrlPos != -1 ) ) { + // Ra: uzależnić dźwięk od zmiany stanu EP, nie od klawisza + play_sound( dsbPneumaticSwitch ); + } + mvOccupied->BrakeLevelAdd( -Global::fBrakeStep ); + } + else + keybrakecount += 1; + // koniec wersji dostarczonej przez ZiomalCl + } + } + break; + } + + case user_command::trainbrakecharging: { + + if( Command.action != GLFW_RELEASE ) { + + // sound feedback + if( ( isEztOer ) + && ( mvControlled->Mains ) + && ( mvOccupied->BrakeCtrlPos != -1 ) ) { + dsbPneumaticSwitch->Play( 0, 0, 0 ); + } + mvOccupied->BrakeLevelSet( -1 ); + } + break; + } + + case user_command::trainbrakerelease: { + + if( Command.action != GLFW_RELEASE ) { + + // sound feedback + if( ( isEztOer ) + && ( ( mvOccupied->BrakeCtrlPos == 1 ) + || ( mvOccupied->BrakeCtrlPos == -1 ) ) ) { + dsbPneumaticSwitch->Play( 0, 0, 0 ); + } + mvOccupied->BrakeLevelSet( 0 ); + } + break; + } + + case user_command::trainbrakefirstservice: { + + if( Command.action != GLFW_RELEASE ) { + + // sound feedback + if( ( isEztOer ) + && ( mvControlled->Mains ) + && ( mvOccupied->BrakeCtrlPos != 1 ) ) { + dsbPneumaticSwitch->Play( 0, 0, 0 ); + } + mvOccupied->BrakeLevelSet( 1 ); + } + break; + } + + case user_command::trainbrakeservice: { + + if( Command.action != GLFW_RELEASE ) { + + // sound feedback + if( ( isEztOer ) + && ( mvControlled->Mains ) + && ( ( mvOccupied->BrakeCtrlPos == 1 ) + || ( mvOccupied->BrakeCtrlPos == -1 ) ) ) { + dsbPneumaticSwitch->Play( 0, 0, 0 ); + } + mvOccupied->BrakeLevelSet( + mvOccupied->BrakeCtrlPosNo / 2 + + ( mvOccupied->BrakeHandle == FV4a ? + 1 : + 0 ) ); + } + break; + } + + case user_command::trainbrakefullservice: { + + if( Command.action != GLFW_RELEASE ) { + + // sound feedback + if( ( isEztOer ) + && ( mvControlled->Mains ) + && ( ( mvOccupied->BrakeCtrlPos == 1 ) + || ( mvOccupied->BrakeCtrlPos == -1 ) ) ) { + dsbPneumaticSwitch->Play( 0, 0, 0 ); + } + mvOccupied->BrakeLevelSet( mvOccupied->BrakeCtrlPosNo - 1 ); + } + break; + } + + case user_command::trainbrakeemergency: { + + if( Command.action != GLFW_RELEASE ) { + + mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_EB ) ); + if( mvOccupied->BrakeCtrlPosNo <= 0.1 ) { + // hamulec bezpieczeństwa dla wagonów + mvOccupied->EmergencyBrakeFlag = true; + } + } + break; + } + + case user_command::reverserincrease: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvOccupied->DirectionForward() ) { + // sound feedback + play_sound( dsbReverserKey, dsbSwitch ); + // aktualizacja skrajnych pojazdów w składzie + if( ( mvOccupied->ActiveDir ) + && ( DynamicObject->Mechanik ) ) { + + DynamicObject->Mechanik->CheckVehicles( Change_direction ); + } + } + } + break; + } + + case user_command::reverserdecrease: { + + if( Command.action != GLFW_RELEASE ) { + + if( mvOccupied->DirectionBackward() ) { + // sound feedback + play_sound( dsbReverserKey, dsbSwitch ); + // aktualizacja skrajnych pojazdów w składzie + if( ( mvOccupied->ActiveDir ) + && ( DynamicObject->Mechanik ) ) { + + DynamicObject->Mechanik->CheckVehicles( Change_direction ); + } + } + } + break; + } + + default: { + + break; + } + } +} + void TTrain::OnKeyDown(int cKey) { // naciśnięcie klawisza bool isEztOer; @@ -409,6 +779,7 @@ void TTrain::OnKeyDown(int cKey) if (Global::shiftState) { // wciśnięty [Shift] +#ifdef EU07_USE_OLD_COMMAND_SYSTEM if (cKey == Global::Keys[k_IncMainCtrlFAST]) // McZapkie-200702: szybkie // przelaczanie na poz. // bezoporowa @@ -419,7 +790,8 @@ void TTrain::OnKeyDown(int cKey) dsbNastawnikJazdy->Play(0, 0, 0); } } - else if (cKey == Global::Keys[k_DirectionBackward]) +#endif + if (cKey == Global::Keys[k_DirectionBackward]) { if (mvOccupied->Radio == false) if (Global::ctrlState) @@ -429,6 +801,7 @@ void TTrain::OnKeyDown(int cKey) mvOccupied->Radio = true; } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_DecMainCtrlFAST]) if (mvControlled->DecMainCtrl(2)) { @@ -469,7 +842,7 @@ void TTrain::OnKeyDown(int cKey) } else ; - else if (cKey == Global::Keys[k_IncLocalBrakeLevelFAST]) + else if( cKey == Global::Keys[ k_IncLocalBrakeLevelFAST ] ) if (mvOccupied->IncLocalBrakeLevel(2)) ; else @@ -479,6 +852,7 @@ void TTrain::OnKeyDown(int cKey) ; else ; +#endif // McZapkie-240302 - wlaczanie glownego obwodu klawiszem M+shift //----------- // hunter-141211: wyl. szybki zalaczony przeniesiony do TTrain::Update() @@ -1177,7 +1551,8 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } else // McZapkie-240302 - klawisze bez shifta { - if (cKey == Global::Keys[k_IncMainCtrl]) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( cKey == Global::Keys[ k_IncMainCtrl ] ) { if (mvControlled->IncMainCtrl(1)) { @@ -1193,13 +1568,13 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } else ; - else if (cKey == Global::Keys[k_IncScndCtrl]) + if (cKey == Global::Keys[k_IncScndCtrl]) // if (MoverParameters->ScndCtrlPosScndCtrlPosNo) // if // (mvControlled->EnginePowerSource.SourceType==CurrentCollector) if (mvControlled->ShuntMode) { - mvControlled->AnPos += (GetDeltaTime() / 0.85f); + mvControlled->AnPos += (Timer::GetDeltaTime() / 0.85f); if (mvControlled->AnPos > 1) mvControlled->AnPos = 1; } @@ -1218,11 +1593,11 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } else ; - else if (cKey == Global::Keys[k_DecScndCtrl]) + else if( cKey == Global::Keys[ k_DecScndCtrl ] ) // if (mvControlled->EnginePowerSource.SourceType==CurrentCollector) if (mvControlled->ShuntMode) { - mvControlled->AnPos -= (GetDeltaTime() / 0.55f); + mvControlled->AnPos -= (Timer::GetDeltaTime() / 0.55f); if (mvControlled->AnPos < 0) mvControlled->AnPos = 0; } @@ -1244,7 +1619,8 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } else ; - else if (cKey == Global::Keys[k_IncLocalBrakeLevel]) +#endif + if( cKey == Global::Keys[ k_IncLocalBrakeLevel ] ) { // Ra 2014-09: w // trybie latania // obsługa jest w @@ -1258,8 +1634,10 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } else ; +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (mvOccupied->LocalBrake != ManualBrake) mvOccupied->IncLocalBrakeLevel(1); +#endif } } else if (cKey == Global::Keys[k_DecLocalBrakeLevel]) @@ -1274,12 +1652,15 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || mvOccupied->DecManualBrakeLevel(1); else ; +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku - // odhamować jakoś trzeba if ((mvOccupied->LocalBrake != ManualBrake) || mvOccupied->LocalBrakePos) mvOccupied->DecLocalBrakeLevel(1); +#endif } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if ((cKey == Global::Keys[k_IncBrakeLevel]) && (mvOccupied->BrakeHandle != FV4a)) // if (mvOccupied->IncBrakeLevel()) if (mvOccupied->BrakeLevelAdd(Global::fBrakeStep)) // nieodpowiedni @@ -1330,14 +1711,16 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || else keybrakecount+=1; */ } - else if (cKey == Global::Keys[k_EmergencyBrake]) +#endif +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + else if( cKey == Global::Keys[ k_EmergencyBrake ] ) { // while (mvOccupied->IncBrakeLevel()); mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EB)); if (mvOccupied->BrakeCtrlPosNo <= 0.1) // hamulec bezpieczeństwa dla wagonów mvOccupied->EmergencyBrakeFlag = true; } - else if (cKey == Global::Keys[k_Brake3]) + else if( cKey == Global::Keys[ k_Brake3 ] ) { if ((isEztOer) && ((mvOccupied->BrakeCtrlPos == 1) || (mvOccupied->BrakeCtrlPos == -1))) { @@ -1350,9 +1733,11 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || // mvOccupied->IncBrakeLevel()); mvOccupied->BrakeLevelSet(mvOccupied->BrakeCtrlPosNo - 1); } +#endif else if (cKey == Global::Keys[k_Brake2]) { - if ((isEztOer) && ((mvOccupied->BrakeCtrlPos == 1) || (mvOccupied->BrakeCtrlPos == -1))) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( ( isEztOer ) && ( ( mvOccupied->BrakeCtrlPos == 1 ) || ( mvOccupied->BrakeCtrlPos == -1 ) ) ) { dsbPneumaticSwitch->SetVolume(-10); dsbPneumaticSwitch->Play(0, 0, 0); @@ -1363,13 +1748,15 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || // mvOccupied->IncBrakeLevel()); mvOccupied->BrakeLevelSet(mvOccupied->BrakeCtrlPosNo / 2 + (mvOccupied->BrakeHandle == FV4a ? 1 : 0)); +#endif if (Global::ctrlState) mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos(bh_NP)); // yB: czy ten stos funkcji nie // powinien być jako oddzielna // funkcja movera? } - else if (cKey == Global::Keys[k_Brake1]) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + else if( cKey == Global::Keys[ k_Brake1 ] ) { if ((isEztOer) && (mvOccupied->BrakeCtrlPos != 1)) { @@ -1380,12 +1767,14 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || // while (mvOccupied->BrakeCtrlPos<1 && mvOccupied->IncBrakeLevel()); mvOccupied->BrakeLevelSet(1); } +#endif else if (cKey == Global::Keys[k_Brake0]) { if (Global::ctrlState) { mvOccupied->BrakeCtrlPos2 = 0; // wyrownaj kapturek } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else { if ((isEztOer) && @@ -1398,7 +1787,9 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || // while (mvOccupied->BrakeCtrlPos<0 && mvOccupied->IncBrakeLevel()); mvOccupied->BrakeLevelSet(0); } +#endif } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_WaveBrake]) //[Num.] { if ((isEztOer) && (mvControlled->Mains) && (mvOccupied->BrakeCtrlPos != -1)) @@ -1410,6 +1801,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || // while (mvOccupied->BrakeCtrlPos<-1 && mvOccupied->IncBrakeLevel()); mvOccupied->BrakeLevelSet(-1); } +#endif else if (cKey == Global::Keys[k_Czuwak]) //--------------- // hunter-131211: zbicie czuwaka przeniesione do TTrain::Update() @@ -1457,6 +1849,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || mvControlled->FuseOn(); } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_DirectionForward]) // McZapkie-240302 - zmiana kierunku: 'd' do przodu, 'r' do tylu { @@ -1483,6 +1876,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || Change_direction); // aktualizacja skrajnych pojazdów w składzie } } +#endif else if (cKey == Global::Keys[k_DirectionBackward]) // r { if (Global::ctrlState) @@ -1494,6 +1888,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || mvOccupied->Radio = false; } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (mvOccupied->DirectionBackward()) { //------------ @@ -1516,6 +1911,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || DynamicObject->Mechanik->CheckVehicles( Change_direction); // aktualizacja skrajnych pojazdów w składzie } +#endif } else if (cKey == Global::Keys[k_Main]) // McZapkie-240302 - wylaczanie glownego obwodu @@ -1634,7 +2030,8 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } } //----------- - else if (cKey == Global::Keys[k_Releaser]) // odluzniacz +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + else if( cKey == Global::Keys[ k_Releaser ] ) // odluzniacz { if (!FreeFlyModeFlag) { @@ -1654,6 +2051,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } } } +#endif else if (cKey == Global::Keys[k_SmallCompressor]) // Winger 160404: mala // sprezarka wl { // Ra: bez [Shift] też dać dźwięk @@ -2374,7 +2772,7 @@ if else { // McZapkie: poruszanie sie po kabinie, w updatemechpos zawarte sa wiezy - +/* auto step = 1.0f; auto const camerayaw = Global::pCamera->Yaw; Math3D::vector3 direction( 0.0f, 0.0f, step ); @@ -2428,6 +2826,7 @@ if else if (cKey == Global::Keys[k_MechDown]) pMechOffset.y -= 0.25; // McZapkie-120302 - siadanie } +*/ } // else @@ -2573,14 +2972,14 @@ void TTrain::UpdateMechPosition(double dt) vMechVelocity.y = -vMechVelocity.y; // ABu011104: 5*pMechShake.y, zeby ladnie pudlem rzucalo :) pMechPosition = pMechOffset + vector3( 1.5 * pMechShake.x, 2.0 * pMechShake.y, 1.5 * pMechShake.z ); - vMechMovement = 0.5 * vMechMovement; +// vMechMovement = 0.5 * vMechMovement; } else { // hamowanie rzucania przy spadku FPS pMechShake -= pMechShake * std::min( dt, 1.0 ); // po tym chyba potrafią zostać jakieś ułamki, które powodują zjazd pMechOffset += vMechMovement * dt; vMechVelocity.y = 0.5 * vMechVelocity.y; pMechPosition = pMechOffset + vector3( pMechShake.x, 5 * pMechShake.y, pMechShake.z ); - vMechMovement = 0.5 * vMechMovement; +// vMechMovement = 0.5 * vMechMovement; } // numer kabiny (-1: kabina B) if( DynamicObject->Mechanik ) // może nie być? @@ -2636,6 +3035,30 @@ TTrain::GetWorldMechPosition() { bool TTrain::Update( double const Deltatime ) { + // check for sent user commands + // NOTE: this is a temporary arrangement, for the transition period from old command setup to the new one + // eventually commands are going to be retrieved directly by the vehicle, filtered through active control stand + // and ultimately executed, provided the stand allows it. + command_data command; + // NOTE: currently we're only storing commands for local vehicle and there's no id system in place, + // so we're supplying 'default' vehicle id of 0 + while( simulation::Commands.pop( command, static_cast( command_target::vehicle ) | 0 ) ) { + + OnCommand( command ); + } + + // update driver's position + { + vector3 Vec = Global::pCamera->Velocity * -2.0;// -7.5 * Timer::GetDeltaRenderTime(); + Vec.y = -Vec.y; + if( mvOccupied->ActiveCab < 0 ) { + Vec *= -1.0f; + Vec.y = -Vec.y; + } + Vec.RotateY( Global::pCamera->Yaw ); + vMechMovement = Vec; + } + DWORD stat; double dt = Deltatime; // Timer::GetDeltaTime(); if (DynamicObject->mdKabina) @@ -2648,7 +3071,7 @@ bool TTrain::Update( double const Deltatime ) fTachoVelocity = Min0R(fabs(11.31 * mvControlled->WheelDiameter * mvControlled->nrot), mvControlled->Vmax * 1.05); { // skacze osobna zmienna - float ff = Simulation::Time.data().wSecond; // skacze co sekunde - pol sekundy + float ff = simulation::Time.data().wSecond; // skacze co sekunde - pol sekundy // pomiar, pol sekundy ustawienie if (ff != fTachoTimer) // jesli w tej sekundzie nie zmienial { @@ -3326,11 +3749,11 @@ bool TTrain::Update( double const Deltatime ) // McZapkie-300302: zegarek if (ggClockMInd.SubModel) { - ggClockSInd.UpdateValue(Simulation::Time.data().wSecond); + ggClockSInd.UpdateValue(simulation::Time.data().wSecond); ggClockSInd.Update(); - ggClockMInd.UpdateValue(Simulation::Time.data().wMinute); + ggClockMInd.UpdateValue(simulation::Time.data().wMinute); ggClockMInd.Update(); - ggClockHInd.UpdateValue(Simulation::Time.data().wHour + Simulation::Time.data().wMinute / 60.0); + ggClockHInd.UpdateValue(simulation::Time.data().wHour + simulation::Time.data().wMinute / 60.0); ggClockHInd.Update(); } @@ -4462,7 +4885,7 @@ bool TTrain::Update( double const Deltatime ) else */ //----------------- - +#ifdef EU07_USE_OLD_COMMAND_SYSTEM if ((!FreeFlyModeFlag) && (!(DynamicObject->Mechanik ? DynamicObject->Mechanik->AIControllFlag : false))) { @@ -4486,6 +4909,7 @@ bool TTrain::Update( double const Deltatime ) else mvOccupied->BrakeReleaser(0); } // FFMF +#endif if (Console::Pressed(Global::Keys[k_Univ1])) { @@ -4742,6 +5166,7 @@ bool TTrain::Update( double const Deltatime ) if (mvOccupied->BrakeCtrlPos2 < -1.5) mvOccupied->BrakeCtrlPos2 = -1.5; } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else { // mvOccupied->BrakeCtrlPosR+=(mvOccupied->BrakeCtrlPosR>mvOccupied->BrakeCtrlPosNo?0:dt*2); @@ -4749,6 +5174,7 @@ bool TTrain::Update( double const Deltatime ) // mvOccupied->BrakeCtrlPos= // floor(mvOccupied->BrakeCtrlPosR+0.499); } +#endif } if ((mvOccupied->BrakeHandle == FV4a) && (Console::Pressed(Global::Keys[k_DecBrakeLevel]))) @@ -4759,6 +5185,7 @@ bool TTrain::Update( double const Deltatime ) if (mvOccupied->BrakeCtrlPos2 < -3) mvOccupied->BrakeCtrlPos2 = -3; } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else { // mvOccupied->BrakeCtrlPosR-=(mvOccupied->BrakeCtrlPosR<-1?0:dt*2); @@ -4766,6 +5193,7 @@ bool TTrain::Update( double const Deltatime ) // floor(mvOccupied->BrakeCtrlPosR+0.499); mvOccupied->BrakeLevelAdd(-dt * 2); } +#endif } // bool kEP; @@ -5003,7 +5431,9 @@ bool TTrain::Update( double const Deltatime ) ggMainOffButton.UpdateValue(0); ggMainOnButton.UpdateValue(0); ggSecurityResetButton.UpdateValue(0); +/* ggReleaserButton.UpdateValue(0); +*/ ggSandButton.UpdateValue(0); ggAntiSlipButton.UpdateValue(0); ggDepartureSignalButton.UpdateValue(0); @@ -6609,3 +7039,23 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con return true; } + +void +TTrain::play_sound( PSound Sound, PSound Fallbacksound ) { + + if( Sound ) { + + Sound->SetCurrentPosition( 0 ); + Sound->SetVolume( DSBVOLUME_MAX ); + Sound->Play( 0, 0, 0 ); + return; + } + if( Fallbacksound ) { + + Fallbacksound->SetCurrentPosition( 0 ); + Fallbacksound->SetVolume( DSBVOLUME_MAX ); + Fallbacksound->Play( 0, 0, 0 ); + return; + } +} + diff --git a/Train.h b/Train.h index 173d1489..d34ff700 100644 --- a/Train.h +++ b/Train.h @@ -7,24 +7,17 @@ obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef TrainH -#define TrainH +#pragma once -//#include "Track.h" -//#include "TrkFoll.h" -#include "Button.h" +#include #include "DynObj.h" +#include "Button.h" #include "Gauge.h" -#include "Model3d.h" #include "Spring.h" -#include "mtable.h" - #include "AdvSound.h" #include "FadeSound.h" #include "PyInt.h" -#include "RealSound.h" -#include "Sound.h" -#include +#include "command.h" // typedef enum {st_Off, st_Starting, st_On, st_ShuttingDown} T4State; @@ -82,6 +75,7 @@ class TTrain bool Init(TDynamicObject *NewDynamicObject, bool e3d = false); void OnKeyDown(int cKey); void OnKeyUp(int cKey); + void OnCommand( command_data const &Command ); // bool SHP() { fShpTimer= 0; }; @@ -113,6 +107,9 @@ class TTrain // initializes a button matching provided label. returns: true if the label was found, false // otherwise bool initialize_button(cParser &Parser, std::string const &Label, int const Cabindex); + // plays specified sound, or fallback sound if the primary sound isn't presend + // NOTE: temporary routine until sound system is sorted out and paired with switches + void play_sound( PSound Sound, PSound Fallbacksound = nullptr ); private: //żeby go nic z zewnątrz nie przestawiało TDynamicObject *DynamicObject; // przestawia zmiana pojazdu [F5] @@ -438,4 +435,3 @@ class TTrain void Silence(); }; //--------------------------------------------------------------------------- -#endif diff --git a/World.cpp b/World.cpp index 7feafa8c..d42f7cfd 100644 --- a/World.cpp +++ b/World.cpp @@ -39,7 +39,7 @@ std::shared_ptr UIHeader = std::make_shared( 20, 20 ); // he std::shared_ptr UITable = std::make_shared( 20, 100 ); // schedule or scan table std::shared_ptr UITranscripts = std::make_shared( 85, 600 ); // voice transcripts -namespace Simulation { +namespace simulation { simulation_time Time; @@ -82,14 +82,13 @@ simulation_time::init() { void simulation_time::update( double const Deltatime ) { - // use large enough buffer to hold long time skips - auto milliseconds = m_time.wMilliseconds + static_cast(std::floor( 1000.0 * Deltatime )); - while( milliseconds >= 1000.0 ) { + m_milliseconds += ( 1000.0 * Deltatime ); + while( m_milliseconds >= 1000.0 ) { ++m_time.wSecond; - milliseconds -= 1000; + m_milliseconds -= 1000.0; } - m_time.wMilliseconds = milliseconds; + m_time.wMilliseconds = std::floor( m_milliseconds ); while( m_time.wSecond >= 60 ) { ++m_time.wMinute; @@ -310,7 +309,7 @@ bool TWorld::Init( GLFWwindow *Window ) { glfwSetWindowTitle( window, ( Global::AppName + " (" + Global::SceneryFile + ")" ).c_str() ); // nazwa scenerii - Simulation::Time.init(); + simulation::Time.init(); Environment.init(); Camera.Init(Global::FreeCameraInit[0], Global::FreeCameraInitAngle[0]); @@ -502,11 +501,11 @@ void TWorld::OnKeyDown(int cKey) // additional time speedup keys in debug mode if( Global::ctrlState ) { // ctrl-f3 - Simulation::Time.update( 20.0 * 60.0 ); + simulation::Time.update( 20.0 * 60.0 ); } else if( Global::shiftState ) { // shift-f3 - Simulation::Time.update( 5.0 * 60.0 ); + simulation::Time.update( 5.0 * 60.0 ); } } if( ( false == Global::ctrlState ) @@ -972,13 +971,15 @@ bool TWorld::Update() WriteLog("Scenery moved"); }; #endif + Timer::UpdateTimers(Global::iPause != 0); + if( (Global::iPause == false) - || (m_init == false) ) - { // jak pauza, to nie ma po co tego przeliczać + || (m_init == false) ) { + // jak pauza, to nie ma po co tego przeliczać + simulation::Time.update( Timer::GetDeltaTime() ); // Ra 2014-07: przeliczenie kąta czasu (do animacji zależnych od czasu) - Simulation::Time.update( Timer::GetDeltaTime() ); - auto const &time = Simulation::Time.data(); + auto const &time = simulation::Time.data(); Global::fTimeAngleDeg = time.wHour * 15.0 + time.wMinute * 0.25 + ( ( time.wSecond + 0.001 * time.wMilliseconds ) / 240.0 ); Global::fClockAngleDeg[ 0 ] = 36.0 * ( time.wSecond % 10 ); // jednostki sekund Global::fClockAngleDeg[ 1 ] = 36.0 * ( time.wSecond / 10 ); // dziesiątki sekund @@ -1107,6 +1108,13 @@ bool TWorld::Update() fTime50Hz += dt; // w pauzie też trzeba zliczać czas, bo przy dużym FPS będzie problem z odczytem ramek while( fTime50Hz >= 1.0 / 50.0 ) { Console::Update(); // to i tak trzeba wywoływać + Update_UI(); + + Camera.Velocity *= 0.65; + if( std::abs( Camera.Velocity.x ) < 0.01 ) { Camera.Velocity.x = 0.0; } + if( std::abs( Camera.Velocity.y ) < 0.01 ) { Camera.Velocity.y = 0.0; } + if( std::abs( Camera.Velocity.z ) < 0.01 ) { Camera.Velocity.z = 0.0; } + fTime50Hz -= 1.0 / 50.0; } @@ -1114,8 +1122,6 @@ bool TWorld::Update() Update_Camera( dt ); - Update_UI(); // TBD, TODO: move the ui updates to secondary fixed step routines, to reduce workload? - GfxRenderer.Update( dt ); ResourceSweep(); @@ -1644,7 +1650,7 @@ TWorld::Update_UI() { case( GLFW_KEY_F1 ) : { // f1, default mode: current time and timetable excerpt - auto const &time = Simulation::Time.data(); + auto const &time = simulation::Time.data(); uitextline1 = "Time: " + to_string( time.wHour ) + ":" @@ -1695,7 +1701,7 @@ TWorld::Update_UI() { auto const table = tmp->Mechanik->Timetable(); if( table == nullptr ) { break; } - auto const &time = Simulation::Time.data(); + auto const &time = simulation::Time.data(); uitextline1 = "Time: " + to_string( time.wHour ) + ":" @@ -2023,8 +2029,8 @@ TWorld::Update_UI() { to_string( tmp->MoverParameters->RunningShape.R, 1 ) ) + " An=" + to_string( tmp->MoverParameters->AccN, 2 ); // przyspieszenie poprzeczne - if( tprev != Simulation::Time.data().wSecond ) { - tprev = Simulation::Time.data().wSecond; + if( tprev != simulation::Time.data().wSecond ) { + tprev = simulation::Time.data().wSecond; Acc = ( tmp->MoverParameters->Vel - VelPrev ) / 3.6; VelPrev = tmp->MoverParameters->Vel; } @@ -2184,8 +2190,7 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz) if (e) if ((e->Type == tp_Multiple) || (e->Type == tp_Lights) || (e->evJoined != 0)) // tylko jawne albo niejawne Multiple - Ground.AddToQuery(e, NULL); // drugi parametr to dynamic wywołujący - tu - // brak + Ground.AddToQuery(e, NULL); // drugi parametr to dynamic wywołujący - tu brak } break; case 3: // rozkaz dla AI @@ -2229,12 +2234,12 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz) if (*pRozkaz->iPar & 1) // ustawienie czasu { double t = pRozkaz->fPar[1]; - Simulation::Time.data().wDay = std::floor(t); // niby nie powinno być dnia, ale... + simulation::Time.data().wDay = std::floor(t); // niby nie powinno być dnia, ale... if (Global::fMoveLight >= 0) Global::fMoveLight = t; // trzeba by deklinację Słońca przeliczyć - Simulation::Time.data().wHour = std::floor(24 * t) - 24.0 * Simulation::Time.data().wDay; - Simulation::Time.data().wMinute = std::floor(60 * 24 * t) - 60.0 * (24.0 * Simulation::Time.data().wDay + Simulation::Time.data().wHour); - Simulation::Time.data().wSecond = std::floor( 60 * 60 * 24 * t ) - 60.0 * ( 60.0 * ( 24.0 * Simulation::Time.data().wDay + Simulation::Time.data().wHour ) + Simulation::Time.data().wMinute ); + simulation::Time.data().wHour = std::floor(24 * t) - 24.0 * simulation::Time.data().wDay; + simulation::Time.data().wMinute = std::floor(60 * 24 * t) - 60.0 * (24.0 * simulation::Time.data().wDay + simulation::Time.data().wHour); + simulation::Time.data().wSecond = std::floor( 60 * 60 * 24 * t ) - 60.0 * ( 60.0 * ( 24.0 * simulation::Time.data().wDay + simulation::Time.data().wHour ) + simulation::Time.data().wMinute ); } if (*pRozkaz->iPar & 2) { // ustawienie flag zapauzowania diff --git a/World.h b/World.h index dd15dbc3..312bd3cf 100644 --- a/World.h +++ b/World.h @@ -49,11 +49,12 @@ private: daymonth( WORD &Day, WORD &Month, WORD const Year, WORD const Yearday ); SYSTEMTIME m_time; + double m_milliseconds{ 0.0 }; int m_yearday; char m_monthdaycounts[ 2 ][ 13 ]; }; -namespace Simulation { +namespace simulation { extern simulation_time Time; diff --git a/command.cpp b/command.cpp new file mode 100644 index 00000000..b1bde4f4 --- /dev/null +++ b/command.cpp @@ -0,0 +1,300 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +#include "stdafx.h" +#include "command.h" + +#include "globals.h" +#include "logs.h" +#include "timer.h" + +namespace simulation { + +command_queue Commands; + +} + +// posts specified command for specified recipient +void +command_queue::push( command_data const &Command, std::size_t const Recipient ) { + + auto lookup = m_commands.emplace( Recipient, commanddata_sequence() ); + // recipient stack was either located or created, so we can add to it quite safely + lookup.first->second.emplace( Command ); +} + +// retrieves oldest posted command for specified recipient, if any. returns: true on retrieval, false if there's nothing to retrieve +bool +command_queue::pop( command_data &Command, std::size_t const Recipient ) { + + auto lookup = m_commands.find( Recipient ); + if( lookup == m_commands.end() ) { + // no command stack for this recipient, so no commands + return false; + } + auto &commands = lookup->second; + if( true == commands.empty() ) { + + return false; + } + // we have command stack with command(s) on it, retrieve and pop the first one + Command = commands.front(); + commands.pop(); + + return true; +} + +command_relay::command_relay() { + + m_targets = commandtarget_map{ + + { user_command::mastercontrollerincrease, command_target::vehicle }, + { user_command::mastercontrollerincreasefast, command_target::vehicle }, + { user_command::mastercontrollerdecrease, command_target::vehicle }, + { user_command::mastercontrollerdecreasefast, command_target::vehicle }, + { user_command::secondcontrollerincrease, command_target::vehicle }, + { user_command::secondcontrollerincreasefast, command_target::vehicle }, + { user_command::secondcontrollerdecrease, command_target::vehicle }, + { user_command::secondcontrollerdecreasefast, command_target::vehicle }, + { user_command::independentbrakeincrease, command_target::vehicle }, + { user_command::independentbrakeincreasefast, command_target::vehicle }, + { user_command::independentbrakedecrease, command_target::vehicle }, + { user_command::independentbrakedecreasefast, command_target::vehicle }, + { user_command::independentbrakebailoff, command_target::vehicle }, + { user_command::trainbrakeincrease, command_target::vehicle }, + { user_command::trainbrakedecrease, command_target::vehicle }, + { user_command::trainbrakecharging, command_target::vehicle }, + { user_command::trainbrakerelease, command_target::vehicle }, + { user_command::trainbrakefirstservice, command_target::vehicle }, + { user_command::trainbrakeservice, command_target::vehicle }, + { user_command::trainbrakefullservice, command_target::vehicle }, + { user_command::trainbrakeemergency, command_target::vehicle }, +/* +const int k_AntiSlipping = 21; +const int k_Sand = 22; +const int k_Main = 23; +*/ + { user_command::reverserincrease, command_target::vehicle }, + { user_command::reverserdecrease, command_target::vehicle }, +/* +const int k_Fuse = 26; +const int k_Compressor = 27; +const int k_Converter = 28; +const int k_MaxCurrent = 29; +const int k_CurrentAutoRelay = 30; +const int k_BrakeProfile = 31; +const int k_Czuwak = 32; +const int k_Horn = 33; +const int k_Horn2 = 34; +const int k_FailedEngineCutOff = 35; +*/ + { user_command::viewturn, command_target::entity }, + { user_command::movevector, command_target::entity }, + { user_command::moveleft, command_target::entity }, + { user_command::moveright, command_target::entity }, + { user_command::moveforward, command_target::entity }, + { user_command::moveback, command_target::entity }, + { user_command::moveup, command_target::entity }, + { user_command::movedown, command_target::entity }, + { user_command::moveleftfast, command_target::entity }, + { user_command::moverightfast, command_target::entity }, + { user_command::moveforwardfast, command_target::entity }, + { user_command::movebackfast, command_target::entity }, + { user_command::moveupfast, command_target::entity }, + { user_command::movedownfast, command_target::entity } +/* + { user_command::moveleftfastest, command_target::entity }, + { user_command::moverightfastest, command_target::entity }, + { user_command::moveforwardfastest, command_target::entity }, + { user_command::movebackfastest, command_target::entity }, + { user_command::moveupfastest, command_target::entity }, + { user_command::movedownfastest, command_target::entity } +*/ +/* +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; +const int k_OpenLeft = 49; +const int k_OpenRight = 50; +const int k_CloseLeft = 51; +const int k_CloseRight = 52; +const int k_DepartureSignal = 53; +const int k_PantFrontUp = 54; +const int k_PantRearUp = 55; +const int k_PantFrontDown = 56; +const int k_PantRearDown = 57; +const int k_Heating = 58; +// const int k_FreeFlyMode= 59; +const int k_LeftSign = 60; +const int k_UpperSign = 61; +const int k_RightSign = 62; +const int k_SmallCompressor = 63; +const int k_StLinOff = 64; +const int k_CurrentNext = 65; +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; +const int k_Battery = 72; +const int k_WalkMode = 73; +int const k_DimHeadlights = 74; +*/ + }; + +#ifdef _DEBUG + m_commandnames = { + + "mastercontrollerincrease", + "mastercontrollerincreasefast", + "mastercontrollerdecrease", + "mastercontrollerdecreasefast", + "secondcontrollerincrease", + "secondcontrollerincreasefast", + "secondcontrollerdecrease", + "secondcontrollerdecreasefast", + "independentbrakeincrease", + "independentbrakeincreasefast", + "independentbrakedecrease", + "independentbrakedecreasefast", + "independentbrakebailoff", + "trainbrakeincrease", + "trainbrakedecrease", + "trainbrakecharging", + "trainbrakerelease", + "trainbrakefirstservice", + "trainbrakeservice", + "trainbrakefullservice", + "trainbrakeemergency", +/* +const int k_AntiSlipping = 21; +const int k_Sand = 22; +const int k_Main = 23; +*/ + "reverserincrease", + "reverserdecrease", +/* +const int k_Fuse = 26; +const int k_Compressor = 27; +const int k_Converter = 28; +const int k_MaxCurrent = 29; +const int k_CurrentAutoRelay = 30; +const int k_BrakeProfile = 31; +const int k_Czuwak = 32; +const int k_Horn = 33; +const int k_Horn2 = 34; +const int k_FailedEngineCutOff = 35; +*/ + "", //"viewturn", + "", //"movevector", + "", //"moveleft", + "", //"moveright", + "", //"moveforward", + "", //"moveback", + "", //"moveup", + "", //"movedown", + "", //"moveleftfast", + "", //"moverightfast", + "", //"moveforwardfast", + "", //"movebackfast", + "", //"moveupfast", + "" //"movedownfast" +/* + "moveleftfastest", + "moverightfastest", + "moveforwardfastest", + "movebackfastest", + "moveupfastest", + "movedownfastest" +*/ +/* +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; +const int k_OpenLeft = 49; +const int k_OpenRight = 50; +const int k_CloseLeft = 51; +const int k_CloseRight = 52; +const int k_DepartureSignal = 53; +const int k_PantFrontUp = 54; +const int k_PantRearUp = 55; +const int k_PantFrontDown = 56; +const int k_PantRearDown = 57; +const int k_Heating = 58; +// const int k_FreeFlyMode= 59; +const int k_LeftSign = 60; +const int k_UpperSign = 61; +const int k_RightSign = 62; +const int k_SmallCompressor = 63; +const int k_StLinOff = 64; +const int k_CurrentNext = 65; +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; +const int k_Battery = 72; +const int k_WalkMode = 73; +int const k_DimHeadlights = 74; +*/ + }; +#endif +} + +void +command_relay::post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2, int const Action, std::uint16_t const Recipient ) const { + + auto const &lookup = m_targets.find( Command ); + if( lookup == m_targets.end() ) { + // shouldn't be really needed but, eh + return; + } + if( ( lookup->second == command_target::vehicle ) + && ( true == FreeFlyModeFlag ) ) { + // don't pass vehicle commands if the user isn't in one + return; + } + + simulation::Commands.push( + command_data{ + Command, + Action, + Param1, + Param2, + Timer::GetDeltaTime() }, + static_cast( lookup->second ) | Recipient ); + +#ifdef _DEBUG + if( Action != GLFW_RELEASE ) { + // key was pressed or is still held + auto const &commandname = m_commandnames.at( static_cast( Command ) ); + if( false == commandname.empty() ) { + WriteLog( "Command issued: " + commandname ); + } + } +/* + else { + // key was released (but we don't log this) + WriteLog( "Key released: " + m_commandnames.at( static_cast( Command ) ) ); + } +*/ +#endif +} + +//--------------------------------------------------------------------------- diff --git a/command.h b/command.h new file mode 100644 index 00000000..ad02d2f7 --- /dev/null +++ b/command.h @@ -0,0 +1,196 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +#pragma once + +#include +#include + +enum class user_command { + + mastercontrollerincrease, + mastercontrollerincreasefast, + mastercontrollerdecrease, + mastercontrollerdecreasefast, + secondcontrollerincrease, + secondcontrollerincreasefast, + secondcontrollerdecrease, + secondcontrollerdecreasefast, + independentbrakeincrease, + independentbrakeincreasefast, + independentbrakedecrease, + independentbrakedecreasefast, + independentbrakebailoff, + trainbrakeincrease, + trainbrakedecrease, + trainbrakecharging, + trainbrakerelease, + trainbrakefirstservice, + trainbrakeservice, + trainbrakefullservice, + trainbrakeemergency, +/* +const int k_AntiSlipping = 21; +const int k_Sand = 22; +const int k_Main = 23; +*/ + reverserincrease, + reverserdecrease, +/* +const int k_Fuse = 26; +const int k_Compressor = 27; +const int k_Converter = 28; +const int k_MaxCurrent = 29; +const int k_CurrentAutoRelay = 30; +const int k_BrakeProfile = 31; +const int k_Czuwak = 32; +const int k_Horn = 33; +const int k_Horn2 = 34; +const int k_FailedEngineCutOff = 35; +*/ + viewturn, + movevector, + moveleft, + moveright, + moveforward, + moveback, + moveup, + movedown, + moveleftfast, + moverightfast, + moveforwardfast, + movebackfast, + moveupfast, + movedownfast +/* + moveleftfastest, + moverightfastest, + moveforwardfastest, + movebackfastest, + moveupfastest, + movedownfastest +*/ +/* +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; +const int k_OpenLeft = 49; +const int k_OpenRight = 50; +const int k_CloseLeft = 51; +const int k_CloseRight = 52; +const int k_DepartureSignal = 53; +const int k_PantFrontUp = 54; +const int k_PantRearUp = 55; +const int k_PantFrontDown = 56; +const int k_PantRearDown = 57; +const int k_Heating = 58; +// const int k_FreeFlyMode= 59; +const int k_LeftSign = 60; +const int k_UpperSign = 61; +const int k_RightSign = 62; +const int k_SmallCompressor = 63; +const int k_StLinOff = 64; +const int k_CurrentNext = 65; +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; +const int k_Battery = 72; +const int k_WalkMode = 73; +int const k_DimHeadlights = 74; +*/ + +}; + +enum class command_target { + + userinterface, + simulation, +/* + // NOTE: there's no need for consist- and unit-specific commands at this point, but it's a possibility. + // since command targets are mutually exclusive these don't reduce ranges for individual vehicles etc + consist = 0x4000, + unit = 0x8000, +*/ + // values are combined with object id. 0xffff objects of each type should be quite enough ("for everyone") + vehicle = 0x10000, + signal = 0x20000, + entity = 0x40000 +}; + +struct command_data { + + user_command command; + int action; // press, repeat or release + std::uint64_t param1; + std::uint64_t param2; + double time_delta; +}; + +// command_queues: collects and holds commands from input sources, for processing by their intended recipients +// NOTE: this won't scale well. +// TODO: turn it into a dispatcher and build individual command sequences into the items, where they can be examined without lookups + +class command_queue { + +public: +// methods + // posts specified command for specified recipient + void + push( command_data const &Command, std::size_t const Recipient ); + // retrieves oldest posted command for specified recipient, if any. returns: true on retrieval, false if there's nothing to retrieve + bool + pop( command_data &Command, std::size_t const Recipient ); + +private: +// types + typedef std::queue commanddata_sequence; + typedef std::unordered_map commanddatasequence_map; +// members + commanddatasequence_map m_commands; + +}; + +// NOTE: simulation should be a (light) wrapper rather than namespace so we could potentially instance it, +// but realistically it's not like we're going to run more than one simulation at a time +namespace simulation { + +extern command_queue Commands; + +} + +// command_relay: composite class component, passes specified command to appropriate command stack + +class command_relay { + +public: +// constructors + command_relay(); +// methods + // posts specified command for the specified recipient + // TODO: replace uint16_t with recipient handle, based on item id + void + post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2, int const Action, std::uint16_t const Recipient ) const; +private: +// types + typedef std::unordered_map commandtarget_map; +// members + commandtarget_map m_targets; +#ifdef _DEBUG + std::vector m_commandnames; +#endif +}; + +//--------------------------------------------------------------------------- diff --git a/gamepadinput.cpp b/gamepadinput.cpp new file mode 100644 index 00000000..2c1dfa1a --- /dev/null +++ b/gamepadinput.cpp @@ -0,0 +1,352 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +#include "stdafx.h" +#include "gamepadinput.h" +#include "logs.h" +#include "timer.h" +#include "usefull.h" + +glm::vec2 circle_to_square( glm::vec2 const &Point, int const Roundness = 0 ) { + + // Determine the theta angle + auto angle = std::atan2( Point.x, Point.y ) + M_PI; + + glm::vec2 squared; + // Scale according to which wall we're clamping to + // X+ wall + if( angle <= M_PI_4 || angle > 7 * M_PI_4 ) + squared = Point * (float)( 1.0 / std::cos( angle ) ); + // Y+ wall + else if( angle > M_PI_4 && angle <= 3 * M_PI_4 ) + squared = Point * (float)( 1.0 / std::sin( angle ) ); + // X- wall + else if( angle > 3 * M_PI_4 && angle <= 5 * M_PI_4 ) + squared = Point * (float)( -1.0 / std::cos( angle ) ); + // Y- wall + else if( angle > 5 * M_PI_4 && angle <= 7 * M_PI_4 ) + squared = Point * (float)( -1.0 / std::sin( angle ) ); + + // Early-out for a perfect square output + if( Roundness == 0 ) + return squared; + + // Find the inner-roundness scaling factor and LERP + auto const length = glm::length( Point ); + auto const factor = std::pow( length, Roundness ); + return interpolate( Point, squared, factor ); +} + +gamepad_input::gamepad_input() { + + m_modecommands = { + + { user_command::mastercontrollerincrease, user_command::mastercontrollerdecrease }, + { user_command::trainbrakedecrease, user_command::trainbrakeincrease }, + { user_command::secondcontrollerincrease, user_command::secondcontrollerdecrease }, + { user_command::independentbrakedecrease, user_command::independentbrakeincrease } + }; +} + +bool +gamepad_input::init() { + + // NOTE: we're only checking for joystick_1 and rely for it to stay connected throughout. + // not exactly flexible, but for quick hack it'll do + auto const name = glfwGetJoystickName( GLFW_JOYSTICK_1 ); + if( name != nullptr ) { + WriteLog( "Connected gamepad: " + std::string( name ) ); + m_deviceid = GLFW_JOYSTICK_1; + } + else { + // no joystick, + WriteLog( "No gamepad detected" ); + m_axes.clear(); + m_buttons.clear(); + return false; + } + + int count; + + glfwGetJoystickAxes( m_deviceid, &count ); + m_axes.resize( count ); + + glfwGetJoystickButtons( m_deviceid, &count ); + m_buttons.resize( count ); + + return true; +} + +// checks state of the controls and sends issued commands +void +gamepad_input::poll() { + + int count; std::size_t idx = 0; + // poll button state + auto const buttons = glfwGetJoystickButtons( m_deviceid, &count ); + if( count ) { // safety check in case joystick gets pulled out + for( auto &button : m_buttons ) { + + if( button != buttons[ idx ] ) { + // button pressed or released, both are important + on_button( + static_cast( idx ), + ( buttons[ idx ] == 1 ? + GLFW_PRESS : + GLFW_RELEASE ) ); + } + else { + // otherwise we only pass info about button being held down + if( button == 1 ) { + + on_button( + static_cast( idx ), + GLFW_REPEAT ); + } + } + button = buttons[ idx ]; + ++idx; + } + } + + if( m_deviceid == -1 ) { + // if there's no gamepad we can skip the rest + return; + } + // poll axes state + idx = 0; + glm::vec2 leftstick, rightstick, triggers; + auto const axes = glfwGetJoystickAxes( m_deviceid, &count ); + if( count ) { + // safety check in case joystick gets pulled out + if( count >= 2 ) { + leftstick = glm::vec2( + ( std::abs( axes[ gamepad_axes::leftstick_x ] ) > m_deadzone ? + axes[ gamepad_axes::leftstick_x ] : + 0.0f ), + ( std::abs( axes[ gamepad_axes::leftstick_y ] ) > m_deadzone ? + axes[ gamepad_axes::leftstick_y ] : + 0.0f ) ); + } + if( count >= 4 ) { + rightstick = glm::vec2( + ( std::abs( axes[ gamepad_axes::rightstick_x ] ) > m_deadzone ? + axes[ gamepad_axes::rightstick_x ] : + 0.0f ), + ( std::abs( axes[ gamepad_axes::rightstick_y ] ) > m_deadzone ? + axes[ gamepad_axes::rightstick_y ] : + 0.0f ) ); + } + if( count >= 6 ) { + triggers = glm::vec2( + ( axes[ gamepad_axes::lefttrigger ] > m_deadzone ? + axes[ gamepad_axes::lefttrigger ] : + 0.0f ), + ( axes[ gamepad_axes::righttrigger ] > m_deadzone ? + axes[ gamepad_axes::righttrigger ] : + 0.0f ) ); + } + } + process_axes( leftstick, rightstick, triggers ); +} + +void +gamepad_input::on_button( gamepad_button const Button, int const Action ) { + + switch( Button ) { + // NOTE: this is rigid coupling, down the road we should support more flexible binding of functions with buttons + case gamepad_button::a: + case gamepad_button::b: + case gamepad_button::x: + case gamepad_button::y: { + + if( Action == GLFW_RELEASE ) { + // if the button was released the stick controls movement + m_mode = control_mode::entity; + // zero the stick and the accumulator so the input won't bleed between modes + m_leftstick = glm::vec2(); + m_modeaccumulator = 0.0f; + } + else { + // otherwise set control mode to match pressed button + m_mode = static_cast( Button ); + } + break; + } + default: { + break; + } + } +} + +void +gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, glm::vec2 const &Triggers ) { + + // left stick, look around + if( ( Rightstick.x != 0.0f ) || ( Rightstick.y != 0.0f ) ) { + // TODO: make toggles for the axis flip + auto const deltatime = Timer::GetDeltaRenderTime() * 60.0; + double const turnx = Rightstick.x * 10.0 * deltatime; + double const turny = -Rightstick.y * 10.0 * deltatime; + m_relay.post( + user_command::viewturn, + reinterpret_cast( turnx ), + reinterpret_cast( turny ), + GLFW_PRESS, + // as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0 + // TODO: pass correct entity id once the missing systems are in place + 0 ); + } + + // right stick, either movement or controls, depending on currently active mode + if( m_mode == control_mode::entity ) { + + if( ( Leftstick.x != 0.0 || Leftstick.y != 0.0 ) + || ( m_leftstick.x != 0.0 || m_leftstick.y != 0.0 ) ) { + double const movex = static_cast( Leftstick.x ); + double const movez = static_cast( Leftstick.y ); + m_relay.post( + user_command::movevector, + reinterpret_cast( movex ), + reinterpret_cast( movez ), + GLFW_PRESS, + 0 ); + } +/* + Leftstick = circle_to_square( Leftstick ); + if( Leftstick.y >= 0.0f ) { + // forward + process_axis( + Leftstick.y, m_leftstick.y, + 1.0, + user_command::moveforward, + user_command::moveforwardfast, + 0 ); + } + if( Leftstick.y <= 0.0f ) { + // back + process_axis( + Leftstick.y, m_leftstick.y, + -1.0, + user_command::moveback, + user_command::movebackfast, + 0 ); + } + if( Leftstick.x >= 0.0f ) { + // right + process_axis( + Leftstick.x, m_leftstick.x, + 1.0, + user_command::moveright, + user_command::moverightfast, + 0 ); + } + if( Leftstick.x <= 0.0f ) { + // left + process_axis( + Leftstick.x, m_leftstick.x, + -1.0, + user_command::moveleft, + user_command::moveleftfast, + 0 ); + } +*/ + } + else { + // vehicle control modes + process_mode( Leftstick.y, 0 ); + } + + m_rightstick = Rightstick; + m_leftstick = Leftstick; + 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 ) { + + // TODO: separate multiplier for each mode, to allow different, customizable sensitivity for each control + auto const deltatime = Timer::GetDeltaTime() * 15.0; + auto const &lookup = m_modecommands.at( static_cast( m_mode ) ); + + if( Value >= 0.0f ) { + if( m_modeaccumulator < 0.0f ) { + // reset accumulator if we're going in the other direction i.e. issuing opposite control + m_modeaccumulator = 0.0f; + } + if( Value > m_deadzone ) { + m_modeaccumulator += Value * deltatime; + while( m_modeaccumulator >= 1.0f ) { + // send commands if the accumulator(s) was filled + m_relay.post( + lookup.first, + 0, 0, + GLFW_PRESS, + Recipient ); + m_modeaccumulator -= 1.0f; + } + } + } + else { + if( m_modeaccumulator > 0.0f ) { + // reset accumulator if we're going in the other direction i.e. issuing opposite control + m_modeaccumulator = 0.0f; + } + if( Value < m_deadzone ) { + m_modeaccumulator += Value * deltatime; + while( m_modeaccumulator <= -1.0f ) { + // send commands if the accumulator(s) was filled + m_relay.post( + lookup.second, + 0, 0, + GLFW_PRESS, + Recipient ); + m_modeaccumulator += 1.0f; + } + } + } +} + +//--------------------------------------------------------------------------- diff --git a/gamepadinput.h b/gamepadinput.h new file mode 100644 index 00000000..21b33cb7 --- /dev/null +++ b/gamepadinput.h @@ -0,0 +1,86 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +#pragma once + +#include +#include "command.h" + +class gamepad_input { + +public: +// constructors + gamepad_input(); + +// methods + // checks state of the controls and sends issued commands + bool + init(); + void + poll(); + +private: +// types + enum gamepad_button { + a, + b, + x, + y, + left_shoulder, + right_shoulder, + back, + start, + left_sticker, + right_sticker, + dpad_up, + dpad_right, + dpad_down, + dpad_left + }; + enum gamepad_axes { + leftstick_x, + leftstick_y, + rightstick_x, + rightstick_y, + lefttrigger, + righttrigger + }; + enum class control_mode { + entity = -1, + vehicle_mastercontroller, + vehicle_trainbrake, + vehicle_secondarycontroller, + vehicle_independentbrake + }; + typedef std::vector float_sequence; + typedef std::vector char_sequence; + typedef std::vector< std::pair< user_command, user_command > > commandpair_sequence; + +// 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 + command_relay m_relay; + float_sequence m_axes; + char_sequence m_buttons; + int m_deviceid{ -1 }; + control_mode m_mode{ control_mode::entity }; + commandpair_sequence m_modecommands; // sets of commands issued depending on the active control mode + float m_deadzone{ 0.15f }; // TODO: allow to configure this + glm::vec2 m_leftstick; + glm::vec2 m_rightstick; + glm::vec2 m_triggers; + double m_modeaccumulator; // used to throttle command input rate for vehicle controls +}; + +//--------------------------------------------------------------------------- diff --git a/keyboardinput.cpp b/keyboardinput.cpp new file mode 100644 index 00000000..eacbee31 --- /dev/null +++ b/keyboardinput.cpp @@ -0,0 +1,204 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +#include "stdafx.h" +#include "keyboardinput.h" +#include "logs.h" + +void +keyboard_input::recall_bindings() { + + // TODO: implement + + bind(); +} + +bool +keyboard_input::key( int const Key, int const Action ) { + + bool modifier( false ); + + if( ( Key == GLFW_KEY_LEFT_SHIFT ) || ( Key == GLFW_KEY_RIGHT_SHIFT ) ) { + // update internal state, but don't bother passing these + m_shift = + ( Action == GLFW_RELEASE ? + false : + true ); + modifier = true; + } + if( ( Key == GLFW_KEY_LEFT_CONTROL ) || ( Key == GLFW_KEY_RIGHT_CONTROL ) ) { + // update internal state, but don't bother passing these + m_ctrl = + ( Action == GLFW_RELEASE ? + false : + true ); + modifier = true; + } + if( ( Key == GLFW_KEY_LEFT_ALT ) || ( Key == GLFW_KEY_RIGHT_ALT ) ) { + // currently we have no interest in these whatsoever + return false; + } + + // include active modifiers for currently pressed key, except if the key is a modifier itself + auto const key = + Key + | ( modifier ? 0 : ( m_shift ? keymodifier::shift : 0 ) ) + | ( modifier ? 0 : ( m_ctrl ? keymodifier::control : 0 ) ); + + auto const lookup = m_bindings.find( key ); + if( lookup == m_bindings.end() ) { + // no binding for this key + return false; + } + // NOTE: basic keyboard controls don't have any parameters + // as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0 + // TODO: pass correct entity id once the missing systems are in place + m_relay.post( lookup->second, 0, 0, Action, 0 ); + + return true; +} + +void +keyboard_input::mouse( double Mousex, double Mousey ) { + + m_relay.post( + user_command::viewturn, + reinterpret_cast( Mousex ), + reinterpret_cast( Mousey ), + GLFW_PRESS, + // as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0 + // TODO: pass correct entity id once the missing systems are in place + 0 ); +} + +void +keyboard_input::default_bindings() { + + m_commands = { + + { "mastercontrollerincrease", command_target::vehicle, GLFW_KEY_KP_ADD }, + { "mastercontrollerincreasefast", command_target::vehicle, GLFW_KEY_KP_ADD | keymodifier::shift }, + { "mastercontrollerdecrease", command_target::vehicle, GLFW_KEY_KP_SUBTRACT }, + { "mastercontrollerdecreasefast", command_target::vehicle, GLFW_KEY_KP_SUBTRACT | keymodifier::shift }, + { "secondcontrollerincrease", command_target::vehicle, GLFW_KEY_KP_DIVIDE }, + { "secondcontrollerincreasefast", command_target::vehicle, GLFW_KEY_KP_DIVIDE | keymodifier::shift }, + { "secondcontrollerdecrease", command_target::vehicle, GLFW_KEY_KP_MULTIPLY }, + { "secondcontrollerdecreasefast", command_target::vehicle, GLFW_KEY_KP_MULTIPLY | keymodifier::shift }, + { "independentbrakeincrease", command_target::vehicle, GLFW_KEY_KP_1 }, + { "independentbrakeincreasefast", command_target::vehicle, GLFW_KEY_KP_1 | keymodifier::shift }, + { "independentbrakedecrease", command_target::vehicle, GLFW_KEY_KP_7 }, + { "independentbrakedecreasefast", command_target::vehicle, GLFW_KEY_KP_7 | keymodifier::shift }, + { "independentbrakebailoff", command_target::vehicle, GLFW_KEY_KP_4 }, + { "trainbrakeincrease", command_target::vehicle, GLFW_KEY_KP_3 }, + { "trainbrakedecrease", command_target::vehicle, GLFW_KEY_KP_9 }, + { "trainbrakecharging", command_target::vehicle, GLFW_KEY_KP_DECIMAL }, + { "trainbrakerelease", command_target::vehicle, GLFW_KEY_KP_6 }, + { "trainbrakefirstservice", command_target::vehicle, GLFW_KEY_KP_8 }, + { "trainbrakeservice", command_target::vehicle, GLFW_KEY_KP_5 }, + { "trainbrakefullservice", command_target::vehicle, GLFW_KEY_KP_2 }, + { "trainbrakeemergency", command_target::vehicle, GLFW_KEY_KP_0 }, +/* +const int k_AntiSlipping = 21; +const int k_Sand = 22; +const int k_Main = 23; +*/ + { "reverserincrease", command_target::vehicle, GLFW_KEY_D }, + { "reverserdecrease", command_target::vehicle, GLFW_KEY_R }, +/* +const int k_Fuse = 26; +const int k_Compressor = 27; +const int k_Converter = 28; +const int k_MaxCurrent = 29; +const int k_CurrentAutoRelay = 30; +const int k_BrakeProfile = 31; +const int k_Czuwak = 32; +const int k_Horn = 33; +const int k_Horn2 = 34; +const int k_FailedEngineCutOff = 35; +*/ + { "viewturn", command_target::entity, -1 }, + { "movevector", command_target::entity, -1 }, + { "moveleft", command_target::entity, GLFW_KEY_LEFT }, + { "moveright", command_target::entity, GLFW_KEY_RIGHT }, + { "moveforward", command_target::entity, GLFW_KEY_UP }, + { "moveback", command_target::entity, GLFW_KEY_DOWN }, + { "moveup", command_target::entity, GLFW_KEY_PAGE_UP }, + { "movedown", command_target::entity, GLFW_KEY_PAGE_DOWN }, + { "moveleftfast", command_target::entity, GLFW_KEY_LEFT | keymodifier::shift }, + { "moverightfast", command_target::entity, GLFW_KEY_RIGHT | keymodifier::shift }, + { "moveforwardfast", command_target::entity, GLFW_KEY_UP | keymodifier::shift }, + { "movebackfast", command_target::entity, GLFW_KEY_DOWN | keymodifier::shift }, + { "moveupfast", command_target::entity, GLFW_KEY_PAGE_UP | keymodifier::shift }, + { "movedownfast", command_target::entity, GLFW_KEY_PAGE_DOWN | keymodifier::shift } +/* + { "moveleftfastest", command_target::entity, GLFW_KEY_LEFT | keymodifier::control }, + { "moverightfastest", command_target::entity, GLFW_KEY_RIGHT | keymodifier::control }, + { "moveforwardfastest", command_target::entity, GLFW_KEY_UP | keymodifier::control }, + { "movebackfastest", command_target::entity, GLFW_KEY_DOWN | keymodifier::control }, + { "moveupfastest", command_target::entity, GLFW_KEY_PAGE_UP | keymodifier::control }, + { "movedownfastest", command_target::entity, GLFW_KEY_PAGE_DOWN | keymodifier::control } +*/ +/* +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; +const int k_OpenLeft = 49; +const int k_OpenRight = 50; +const int k_CloseLeft = 51; +const int k_CloseRight = 52; +const int k_DepartureSignal = 53; +const int k_PantFrontUp = 54; +const int k_PantRearUp = 55; +const int k_PantFrontDown = 56; +const int k_PantRearDown = 57; +const int k_Heating = 58; +// const int k_FreeFlyMode= 59; +const int k_LeftSign = 60; +const int k_UpperSign = 61; +const int k_RightSign = 62; +const int k_SmallCompressor = 63; +const int k_StLinOff = 64; +const int k_CurrentNext = 65; +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; +const int k_Battery = 72; +const int k_WalkMode = 73; +int const k_DimHeadlights = 74; +*/ + }; + + bind(); +} + +void +keyboard_input::bind() { + + m_bindings.clear(); + + int commandcode{ 0 }; + for( auto const &command : m_commands ) { + + if( command.binding != -1 ) { + m_bindings.emplace( + command.binding, + static_cast( commandcode ) ); + } + ++commandcode; + } +} + +//--------------------------------------------------------------------------- diff --git a/keyboardinput.h b/keyboardinput.h new file mode 100644 index 00000000..c8e2fb43 --- /dev/null +++ b/keyboardinput.h @@ -0,0 +1,61 @@ +/* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*/ + +#pragma once + +#include +#include "command.h" + +class keyboard_input { + +public: +// constructors + keyboard_input() { default_bindings(); } + +// methods + void + recall_bindings(); + bool + key( int const Key, int const Action ); + void + mouse( double const Mousex, double const Mousey ); + +private: +// types + enum keymodifier : int { + + shift = 0x10000, + control = 0x20000 + }; + + struct command_setup { + + std::string name; + command_target target; + int binding; + }; + + typedef std::vector commandsetup_sequence; + typedef std::unordered_map usercommand_map; + +// methods + void + default_bindings(); + void + bind(); + +// members + commandsetup_sequence m_commands; + usercommand_map m_bindings; + command_relay m_relay; + bool m_shift{ false }; + bool m_ctrl{ false }; +}; + +//--------------------------------------------------------------------------- diff --git a/maszyna.vcxproj.filters b/maszyna.vcxproj.filters index 9ccc0f0b..56dc3ce8 100644 --- a/maszyna.vcxproj.filters +++ b/maszyna.vcxproj.filters @@ -16,15 +16,15 @@ {fafd38ab-4c2a-48c8-8e66-ad0d928573b3} - - {2d73d7b2-5252-499c-963a-88fa3cb1af53} - {36684428-8a48-435f-bca4-a24d9bfe2587} - + {cdf75bec-91f7-413c-8b57-9e32cba49148} + + {2d73d7b2-5252-499c-963a-88fa3cb1af53} + @@ -157,7 +157,7 @@ Source Files\mczapkie - Source Files\console + Source Files\input Source Files\mczapkie @@ -169,13 +169,13 @@ Source Files\mczapkie - Source Files\console + Source Files\input Source Files - Source Files\console + Source Files\input Source Files @@ -213,6 +213,15 @@ Source Files + + Source Files + + + Source Files\input + + + Source Files + @@ -291,10 +300,10 @@ Header Files\mczapkie - Header Files\console + Header Files\input - Header Files\console + Header Files\input Header Files @@ -375,7 +384,7 @@ Header Files - Header Files\console + Header Files\input Header Files @@ -413,6 +422,15 @@ Header Files + + Header Files + + + Header Files\input + + + Header Files + diff --git a/moon.cpp b/moon.cpp index f3892960..a7db52e5 100644 --- a/moon.cpp +++ b/moon.cpp @@ -116,7 +116,7 @@ void cMoon::move() { static double radtodeg = 57.295779513; // converts from radians to degrees static double degtorad = 0.0174532925; // converts from degrees to radians - SYSTEMTIME localtime = Simulation::Time.data(); // time for the calculation + SYSTEMTIME localtime = simulation::Time.data(); // time for the calculation if( m_observer.hour >= 0 ) { localtime.wHour = m_observer.hour; } if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; } @@ -284,7 +284,7 @@ void cMoon::irradiance() { static double radtodeg = 57.295779513; // converts from radians to degrees static double degtorad = 0.0174532925; // converts from degrees to radians - m_body.dayang = ( Simulation::Time.year_day() - 1 ) * 360.0 / 365.0; + m_body.dayang = ( simulation::Time.year_day() - 1 ) * 360.0 / 365.0; double sd = sin( degtorad * m_body.dayang ); // sine of the day angle double cd = cos( degtorad * m_body.dayang ); // cosine of the day angle or delination m_body.erv = 1.000110 + 0.034221*cd + 0.001280*sd; @@ -310,7 +310,7 @@ void cMoon::phase() { // calculate moon's age in days from new moon - float ip = normalize( ( Simulation::Time.julian_day() - 2451550.1f ) / 29.530588853f ); + float ip = normalize( ( simulation::Time.julian_day() - 2451550.1f ) / 29.530588853f ); m_phase = ip * 29.53f; } diff --git a/sun.cpp b/sun.cpp index 258c4b9c..879709cb 100644 --- a/sun.cpp +++ b/sun.cpp @@ -115,7 +115,7 @@ void cSun::move() { static double radtodeg = 57.295779513; // converts from radians to degrees static double degtorad = 0.0174532925; // converts from degrees to radians - SYSTEMTIME localtime = Simulation::Time.data(); // time for the calculation + SYSTEMTIME localtime = simulation::Time.data(); // time for the calculation if( m_observer.hour >= 0 ) { localtime.wHour = m_observer.hour; } if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; } @@ -258,9 +258,9 @@ void cSun::irradiance() { static double degrad = 57.295779513; // converts from radians to degrees static double raddeg = 0.0174532925; // converts from degrees to radians - auto const &localtime = Simulation::Time.data(); // time for the calculation + auto const &localtime = simulation::Time.data(); // time for the calculation - m_body.dayang = ( Simulation::Time.year_day() - 1 ) * 360.0 / 365.0; + m_body.dayang = ( simulation::Time.year_day() - 1 ) * 360.0 / 365.0; double sd = sin( raddeg * m_body.dayang ); // sine of the day angle double cd = cos( raddeg * m_body.dayang ); // cosine of the day angle or delination m_body.erv = 1.000110 + 0.034221*cd + 0.001280*sd; From 1034fb8aa99eb3465b8a7c220e5f69784a99c7c1 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Mon, 10 Apr 2017 15:18:08 +0200 Subject: [PATCH 03/12] control for battery, pantographs, line breaker, converter and compressor --- Camera.cpp | 114 +------- DynObj.cpp | 3 +- Float3d.h | 26 +- Gauge.cpp | 17 +- Gauge.h | 15 +- McZapkie/Mover.cpp | 3 + Model3d.cpp | 17 +- Train.cpp | 659 +++++++++++++++++++++++++++++++++++++------ Train.h | 3 + command.cpp | 60 ++-- command.h | 31 +- gamepadinput.cpp | 47 +-- keyboardinput.cpp | 162 +++++++++-- keyboardinput.h | 15 + maszyna.vcxproj.user | 8 +- 15 files changed, 830 insertions(+), 350 deletions(-) diff --git a/Camera.cpp b/Camera.cpp index 75297e4f..06b38254 100644 --- a/Camera.cpp +++ b/Camera.cpp @@ -295,97 +295,6 @@ TCamera::OnCommand( command_data const &Command ) { } break; } -/* - case user_command::moveforwardfastest: { - - if( Command.action != GLFW_RELEASE ) { - m_keys.forward = true; - m_moverate.z = - ( Type == tp_Free ? - 8.0 : - 0.8 ); - } - else { - m_keys.forward = false; - } - break; - } - - case user_command::movebackfastest: { - - if( Command.action != GLFW_RELEASE ) { - m_keys.back = true; - m_moverate.z = - ( Type == tp_Free ? - 8.0 : - 0.8 ); - } - else { - m_keys.back = false; - } - break; - } - - case user_command::moveleftfastest: { - - if( Command.action != GLFW_RELEASE ) { - m_keys.left = true; - m_moverate.x = - ( Type == tp_Free ? - 8.0 : - 0.8 ); - } - else { - m_keys.left = false; - } - break; - } - - case user_command::moverightfastest: { - - if( Command.action != GLFW_RELEASE ) { - m_keys.right = true; - m_moverate.x = - ( Type == tp_Free ? - 8.0 : - 0.8 ); - } - else { - m_keys.right = false; - } - break; - } - - case user_command::moveupfastest: { - - if( Command.action != GLFW_RELEASE ) { - m_keys.up = true; - m_moverate.y = - ( Type == tp_Free ? - 8.0 : - 0.8 ); - } - else { - m_keys.up = false; - } - break; - } - - case user_command::movedownfastest: { - - if( Command.action != GLFW_RELEASE ) { - m_keys.down = true; - m_moverate.y = - ( Type == tp_Free ? - 8.0 : - 0.8 ); - } - else { - m_keys.down = false; - } - break; - } -*/ } } @@ -463,32 +372,11 @@ void TCamera::Update() #endif if( Type == tp_Free ) { + // free movement position update is handled here, movement while in vehicle is handled by train update vector3 Vec = Velocity; Vec.RotateY( Yaw ); Pos += Vec * 5.0 * deltatime; } - else { - - } -/* - if( deltatime < 1.0 / 20.0 ) { - // płynne hamowanie ruchu - Velocity -= Velocity * 20.0 * deltatime; - } - else { - // instant stop - Velocity.Zero(); - } - if( std::abs( Velocity.x ) < 0.01 ) { Velocity.x = 0.0; } - if( std::abs( Velocity.y ) < 0.01 ) { Velocity.y = 0.0; } - if( std::abs( Velocity.z ) < 0.01 ) { Velocity.z = 0.0; } -*/ -/* - Velocity *= 0.5; - if( std::abs( Velocity.x ) < 0.01 ) { Velocity.x = 0.0; } - if( std::abs( Velocity.y ) < 0.01 ) { Velocity.y = 0.0; } - if( std::abs( Velocity.z ) < 0.01 ) { Velocity.z = 0.0; } -*/ } vector3 TCamera::GetDirection() diff --git a/DynObj.cpp b/DynObj.cpp index 78d5b437..d25a37af 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -3291,8 +3291,7 @@ bool TDynamicObject::Update(double dt, double dt1) if (tmpTraction.TractionVoltage == 0) { // to coś wyłączało dźwięk silnika w ST43! MoverParameters->ConverterFlag = false; - MoverParameters->CompressorFlag = false; // Ra: to jest wątpliwe - wyłączenie - // sprężarki powinno być w jednym miejscu! + MoverParameters->CompressorFlag = false; // Ra: to jest wątpliwe - wyłączenie sprężarki powinno być w jednym miejscu! } } } diff --git a/Float3d.h b/Float3d.h index 0acc89cd..6c309357 100644 --- a/Float3d.h +++ b/Float3d.h @@ -66,7 +66,7 @@ inline float3 operator/( float3 const &v, float const k ) }; inline float3 SafeNormalize(const float3 &v) { // bezpieczna normalizacja (wektor długości 1.0) - double l = v.Length(); + auto const l = v.Length(); float3 retVal; if (l == 0) retVal.x = retVal.y = retVal.z = 0; @@ -104,11 +104,11 @@ class float4 z = c; w = d; }; - double inline float4::LengthSquared() const + float inline float4::LengthSquared() const { return x * x + y * y + z * z + w * w; }; - double inline float4::Length() const + float inline float4::Length() const { return sqrt(x * x + y * y + z * z + w * w); }; @@ -132,26 +132,26 @@ inline float4 operator+(const float4 &v1, const float4 &v2) { return float4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w); }; -inline float4 operator/(const float4 &v, double k) +inline float4 operator/(const float4 &v, float const k) { return float4(v.x / k, v.y / k, v.z / k, v.w / k); }; inline float4 Normalize(const float4 &v) { // bezpieczna normalizacja (wektor długości 1.0) - double l = v.LengthSquared(); - if (l == 1.0) + auto const lengthsquared = v.LengthSquared(); + if (lengthsquared == 1.0) return v; - if (l == 0.0) + if (lengthsquared == 0.0) return float4(); // wektor zerowy, w=1 else - return v / sqrt(l); // pierwiastek liczony tylko jeśli trzeba wykonać dzielenia + return v / std::sqrt(lengthsquared); // pierwiastek liczony tylko jeśli trzeba wykonać dzielenia }; inline float Dot(const float4 &q1, const float4 &q2) { // iloczyn skalarny return q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w; } -inline float4 &operator*=(float4 &v1, double d) +inline float4 &operator*=(float4 &v1, float const d) { // mnożenie przez skalar, jaki ma sens? v1.x *= d; v1.y *= d; @@ -172,7 +172,7 @@ inline float4 Slerp(const float4 &q0, const float4 &q1, float t) new_q1.w = -new_q1.w; cosOmega = -cosOmega; } - double k0, k1; + float k0, k1; if (cosOmega > 0.9999f) { // jeśli jesteśmy z (t) na maksimum kosinusa, to tam prawie liniowo jest k0 = 1.0f - t; @@ -180,9 +180,9 @@ inline float4 Slerp(const float4 &q0, const float4 &q1, float t) } else { // a w ogólnym przypadku trzeba liczyć na trygonometrię - double sinOmega = sqrt(1.0f - cosOmega * cosOmega); // sinus z jedynki tryg. - double omega = atan2(sinOmega, cosOmega); // wyznaczenie kąta - double oneOverSinOmega = 1.0f / sinOmega; // odwrotność sinusa, bo sinus w mianowniku + auto const sinOmega = std::sqrt(1.0f - cosOmega * cosOmega); // sinus z jedynki tryg. + auto const omega = std::atan2(sinOmega, cosOmega); // wyznaczenie kąta + auto const oneOverSinOmega = 1.0f / sinOmega; // odwrotność sinusa, bo sinus w mianowniku k0 = sin((1.0f - t) * omega) * oneOverSinOmega; k1 = sin(t * omega) * oneOverSinOmega; } diff --git a/Gauge.cpp b/Gauge.cpp index aead0cca..99b424a0 100644 --- a/Gauge.cpp +++ b/Gauge.cpp @@ -136,19 +136,22 @@ void TGauge::PutValue(double fNewDesired) fValue = fDesiredValue; }; +double TGauge::GetValue() const { + // we feed value in range 0-1 so we should be getting it reported in the same range + return ( fValue - fOffset ) / fScale; +} + void TGauge::Update() { float dt = Timer::GetDeltaTime(); - if ((fFriction > 0) && (dt < 0.5 * fFriction)) // McZapkie-281102: - // zabezpieczenie przed - // oscylacjami dla dlugich - // czasow - fValue += dt * (fDesiredValue - fValue) / fFriction; + if( ( fFriction > 0 ) && ( dt < 0.5 * fFriction ) ) { + // McZapkie-281102: zabezpieczenie przed oscylacjami dla dlugich czasow + fValue += dt * ( fDesiredValue - fValue ) / fFriction; + } else fValue = fDesiredValue; if (SubModel) - { // warunek na wszelki wypadek, gdyby się submodel nie - // podłączył + { // warunek na wszelki wypadek, gdyby się submodel nie podłączył TSubModel *sm; switch (eType) { diff --git a/Gauge.h b/Gauge.h index de6ba90b..e2236a8d 100644 --- a/Gauge.h +++ b/Gauge.h @@ -25,11 +25,11 @@ class TGauge // zmienne "gg" { // animowany wskaźnik, mogący przyjmować wiele stanów pośrednich private: TGaugeType eType; // typ ruchu - double fFriction; // hamowanie przy zliżaniu się do zadanej wartości - double fDesiredValue; // wartość docelowa - double fValue; // wartość obecna - double fOffset; // wartość początkowa ("0") - double fScale; // wartość końcowa ("1") + double fFriction{ 0.0 }; // hamowanie przy zliżaniu się do zadanej wartości + double fDesiredValue{ 0.0 }; // wartość docelowa + double fValue{ 0.0 }; // wartość obecna + double fOffset{ 0.0 }; // wartość początkowa ("0") + double fScale{ 1.0 }; // wartość końcowa ("1") double fStepSize; // nie używane char cDataType; // typ zmiennej parametru: f-float, d-double, i-int union @@ -51,10 +51,7 @@ class TGauge // zmienne "gg" void DecValue(double fNewDesired); void UpdateValue(double fNewDesired); void PutValue(double fNewDesired); - float GetValue() - { - return fValue; - }; + double GetValue() const; void Update(); void Render(); void AssignFloat(float *fValue); diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index eed06456..7a114a15 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -6891,6 +6891,9 @@ void TMoverParameters::LoadFIZ_Switches( std::string const &Input ) { extract_value( PantSwitchType, "Pantograph", Input, "" ); extract_value( ConvSwitchType, "Converter", Input, "" ); + // because people can't make up their minds whether it's "impulse" or "Impulse"... + PantSwitchType = ToLower( PantSwitchType ); + ConvSwitchType = ToLower( ConvSwitchType ); } void TMoverParameters::LoadFIZ_MotorParamTable( std::string const &Input ) { diff --git a/Model3d.cpp b/Model3d.cpp index d77e1204..297232a5 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -321,8 +321,13 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) >> discard >> fFarDecayRadius >> discard >> fCosFalloffAngle // kąt liczony dla średnicy, a nie promienia >> discard >> fCosHotspotAngle; // kąt liczony dla średnicy, a nie promienia - fCosFalloffAngle = std::cos( DegToRad( 0.5f * fCosFalloffAngle ) ); - fCosHotspotAngle = std::cos( DegToRad( 0.5f * fCosHotspotAngle ) ); + // convert conve parameters if specified in degrees + if( fCosFalloffAngle > 1.0 ) { + fCosFalloffAngle = std::cos( DegToRad( 0.5f * fCosFalloffAngle ) ); + } + if( fCosHotspotAngle > 1.0 ) { + fCosHotspotAngle = std::cos( DegToRad( 0.5f * fCosHotspotAngle ) ); + } iNumVerts = 1; /* iFlags |= 0x4010; // rysowane w cyklu nieprzezroczystych, macierz musi zostać bez zmiany @@ -2023,6 +2028,14 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, float8 *v, // so as a workaround we're doing it here manually iFlags |= 0x20; } + // intercept and fix hotspot values if specified in degrees and not directly + if( fCosFalloffAngle > 1.0 ) { + fCosFalloffAngle = std::cos( DegToRad( 0.5f * fCosFalloffAngle ) ); + } + if( fCosHotspotAngle > 1.0 ) { + fCosHotspotAngle = std::cos( DegToRad( 0.5f * fCosHotspotAngle ) ); + } + iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem tablic) iVboPtr = tVboPtr; diff --git a/Train.cpp b/Train.cpp index 43ad864a..ec477ff0 100644 --- a/Train.cpp +++ b/Train.cpp @@ -761,6 +761,525 @@ TTrain::OnCommand( command_data const &Command ) { break; } + case user_command::batterytoggle: { + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == mvOccupied->Battery ) { + // turn on + // wyłącznik jest też w SN61, ewentualnie załączać prąd na stałe z poziomu FIZ + if( mvOccupied->BatterySwitch( true ) ) { + // bateria potrzebna np. do zapalenia świateł + if( ggBatteryButton.SubModel ) { + ggBatteryButton.UpdateValue( 1 ); + } + // audio feedback + play_sound( dsbSwitch ); + // side-effects + if( mvOccupied->LightsPosNo > 0 ) { + SetLights(); + } + if( TestFlag( mvOccupied->SecuritySystem.SystemType, 2 ) ) { + // Ra: znowu w kabinie jest coś, co być nie powinno! + SetFlag( mvOccupied->SecuritySystem.Status, s_active ); + SetFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ); + } + } + } + else { + //turn off + if( mvOccupied->BatterySwitch( false ) ) { + // ewentualnie zablokować z FIZ, np. w samochodach się nie odłącza akumulatora + if( ggBatteryButton.SubModel ) { + ggBatteryButton.UpdateValue( 0 ); + } + // audio feedback + play_sound( dsbSwitch ); + // side-effects + mvControlled->PantFront( false ); + mvControlled->PantRear( false ); + } + } + + } + break; + } + + case user_command::pantographtogglefront: { + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == ( mvOccupied->ActiveCab == 1 ? mvControlled->PantFrontUp : mvControlled->PantRearUp ) ) { + // turn on... + if( mvOccupied->ActiveCab == 1 ) { + // przedni gdy w kabinie 1 + mvControlled->PantFrontSP = false; + if( mvControlled->PantFront( true ) ) { + if( mvControlled->PantFrontStart != 1 ) { + if( ggPantFrontButton.SubModel ) { + ggPantFrontButton.UpdateValue( 1.0 ); + } + play_sound( dsbSwitch ); + } + } + } + else { + // rear otherwise + mvControlled->PantRearSP = false; + if( mvControlled->PantRear( true ) ) { + if( mvControlled->PantRearStart != 1 ) { + if( ggPantRearButton.SubModel ) { + ggPantRearButton.UpdateValue( 1.0 ); + } + play_sound( dsbSwitch ); + } + } + } + } + else { + // ...or turn off + if( mvOccupied->ActiveCab == 1 ) { + // przedni gdy w kabinie 1 + mvControlled->PantFrontSP = false; + if( false == mvControlled->PantFront( false ) ) { + if( mvControlled->PantFrontStart != 0 ) { + if( ggPantFrontButton.SubModel ) { + ggPantFrontButton.UpdateValue( + ( mvOccupied->PantSwitchType != "impulse" ? + 0.0 : + 1.0 ) ); + } + play_sound( dsbSwitch ); + } + } + } + else { + // rear otherwise + mvControlled->PantRearSP = false; + if( false == mvControlled->PantRear( false ) ) { + if( mvControlled->PantRearStart != 0 ) { + if( ggPantRearButton.SubModel ) { + ggPantRearButton.UpdateValue( + ( mvOccupied->PantSwitchType != "impulse" ? + 0.0 : + 1.0 ) ); + } + play_sound( dsbSwitch ); + } + } + } + } + } + else if( Command.action == GLFW_RELEASE ) { + // impulse switches return automatically to neutral position + if( mvOccupied->PantSwitchType == "impulse" ) { + if( mvOccupied->ActiveCab == 1 ) { + // przedni gdy w kabinie 1 + if( ggPantFrontButton.GetValue() > 0.1 ) { + play_sound( dsbSwitch ); + } + if( ggPantFrontButton.SubModel ) { + ggPantFrontButton.UpdateValue( 0.0 ); + } + } + else { + // rear otherwise + if( ggPantRearButton.GetValue() > 0.1 ) { + play_sound( dsbSwitch ); + } + if( ggPantRearButton.SubModel ) { + ggPantRearButton.UpdateValue( 0.0 ); + } + } + } + } + break; + } + + case user_command::pantographtogglerear: { + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == ( mvOccupied->ActiveCab == 1 ? mvControlled->PantRearUp : mvControlled->PantFrontUp ) ) { + // turn on... + if( mvOccupied->ActiveCab == 1 ) { + // rear if in front cab + mvControlled->PantRearSP = false; + if( mvControlled->PantRear( true ) ) { + if( mvControlled->PantRearStart != 1 ) { + if( ggPantRearButton.SubModel ) { + ggPantRearButton.UpdateValue( 1.0 ); + } + play_sound( dsbSwitch ); + } + } + } + else { + // front otherwise + mvControlled->PantFrontSP = false; + if( mvControlled->PantFront( true ) ) { + if( mvControlled->PantFrontStart != 1 ) { + if( ggPantFrontButton.SubModel ) { + ggPantFrontButton.UpdateValue( 1.0 ); + } + play_sound( dsbSwitch ); + } + } + } + } + else { + // ...or turn off + if( mvOccupied->ActiveCab == 1 ) { + // rear if in front cab + mvControlled->PantRearSP = false; + if( false == mvControlled->PantRear( false ) ) { + if( mvControlled->PantRearStart != 0 ) { + if( ggPantRearButton.SubModel ) { + ggPantRearButton.UpdateValue( + ( mvOccupied->PantSwitchType != "impulse" ? + 0.0 : + 1.0 ) ); + } + play_sound( dsbSwitch ); + } + } + } + else { + // front otherwise + mvControlled->PantFrontSP = false; + if( false == mvControlled->PantFront( false ) ) { + if( mvControlled->PantFrontStart != 0 ) { + if( ggPantFrontButton.SubModel ) { + ggPantFrontButton.UpdateValue( + ( mvOccupied->PantSwitchType != "impulse" ? + 0.0 : + 1.0 ) ); + } + play_sound( dsbSwitch ); + } + } + } + } + } + else if( Command.action == GLFW_RELEASE ) { + // impulse switches return automatically to neutral position + if( mvOccupied->PantSwitchType == "impulse" ) { + if( mvOccupied->ActiveCab == 1 ) { + // tylny gdy w kabinie 1 + if( ggPantRearButton.GetValue() > 0.1 ) { + play_sound( dsbSwitch ); + } + if( ggPantRearButton.SubModel ) { + ggPantRearButton.UpdateValue( 0.0 ); + } + } + else { + // front otherwise + if( ggPantFrontButton.GetValue() > 0.1 ) { + play_sound( dsbSwitch ); + } + if( ggPantFrontButton.SubModel ) { + ggPantFrontButton.UpdateValue( 0.0 ); + } + play_sound( dsbSwitch ); + } + } + } + break; + } + + case user_command::linebreakertoggle: { + + if( Command.action != GLFW_RELEASE ) { + // press or hold... + if( false == mvControlled->Mains ) { + // ...to close the circuit + if( false == m_linebreakerclosed ) { + // safety check so we don't close the circuit right after opening + if( ggMainOnButton.SubModel != nullptr ) { + // two separate switches to close and break the circuit + // audio feedback + if( Command.action == GLFW_PRESS ) { + play_sound( dsbSwitch ); + } + // visual feedback + ggMainOnButton.UpdateValue( 1.0 ); + } + else if( ggMainButton.SubModel != nullptr ) { + // single two-state switch + // audio feedback + if( Command.action == GLFW_PRESS ) { + play_sound( dsbSwitch ); + } + // visual feedback + ggMainButton.UpdateValue( 1.0 ); + } + // keep track of period the button is held down, to determine when/if circuit closes + fMainRelayTimer += 0.33; // Command.time_delta * 5.0; + // NOTE: this shouldn't be necessary, what exactly does it fix? + if( mvControlled->Mains != true ) { + // hunter-080812: poprawka + // adjusted further to take into account state of the switch + mvControlled->ConverterSwitch( ggConverterButton.GetValue() > 0.5 ); + mvControlled->CompressorSwitch( ggCompressorButton.GetValue() > 0.5 ); + } + if( fMainRelayTimer > mvControlled->InitialCtrlDelay ) { + // wlaczanie WSa z opoznieniem + if( mvControlled->MainSwitch( true ) ) { + // sound feedback, engine start for diesel vehicle + if( mvControlled->EngineType == DieselEngine ) { + play_sound( dsbDieselIgnition ); + } + } + } + } + } + else { + // ...to open the circuit + if( true == m_linebreakerclosed ) { + // safety check so we don't open the circuit right after closing + if( mvControlled->MainSwitch( false ) ) { + + if( ggMainOffButton.SubModel != nullptr ) { + // two separate switches to close and break the circuit + // audio feedback + if( Command.action == GLFW_PRESS ) { + play_sound( dsbSwitch ); + } + // visual feedback + ggMainOffButton.UpdateValue( 1.0 ); + } + else if( ggMainButton.SubModel != nullptr ) { + // single two-state switch + // NOTE: we don't have switch type definition for the line breaker switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz + if( mvControlled->TrainType == dt_EZT ) { + // audio feedback + if( Command.action == GLFW_PRESS ) { + play_sound( dsbSwitch ); + } + // visual feedback + ggMainButton.UpdateValue( 1.0 ); + } + else { + // audio feedback + if( Command.action == GLFW_PRESS ) { + play_sound( dsbSwitch ); + } + // visual feedback + ggMainButton.UpdateValue( 0.0 ); + } + } + // side-effects + mvControlled->ConverterSwitch( ggConverterButton.GetValue() > 0.5 ); + mvControlled->CompressorSwitch( ggCompressorButton.GetValue() > 0.5 ); + } + // play sound immediately when the switch is hit, not after release + if( fMainRelayTimer > 0.0f ) { + play_sound( dsbRelay ); + fMainRelayTimer = 0.0f; + } + } + } + } + else { + // release... + if( false == mvControlled->Mains ) { + // ...after opening circuit, or holding for too short time to close it +/* + if( mvControlled->ConverterAllow ) { + // po puszczeniu przycisku od WSa odpalanie potwora + mvControlled->ConverterSwitch( true ); + } +*/ + // hunter-091012: przeniesione z mover.pas, zeby dzwiek sie nie zapetlal, + if( fMainRelayTimer > 0.0f ) { + play_sound( dsbRelay ); + fMainRelayTimer = 0.0f; + } + // we don't exactly know which of the two buttons was used, so reset both + if( ggMainOnButton.SubModel != nullptr ) { + // setup with two separate swiches + ggMainOnButton.UpdateValue( 0.0 ); + } + if( ggMainOffButton.SubModel != nullptr ) { + // setup with two separate swiches + ggMainOffButton.UpdateValue( 0.0 ); + } + // and the two-state switch too, for good measure + if( ggMainButton.SubModel != nullptr ) { + ggMainButton.UpdateValue( 0.0 ); + // NOTE: we don't have switch type definition for the line breaker switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz + if( mvControlled->TrainType == dt_EZT ) { + // audio feedback + play_sound( dsbSwitch ); + } + } + m_linebreakerclosed = false; + } + else { + // ...after closing the circuit + if( ggMainOnButton.SubModel != nullptr ) { + // setup with two separate switches + ggMainOnButton.UpdateValue( 0.0 ); + } + // NOTE: we don't have switch type definition for the line breaker switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz + if( mvControlled->TrainType == dt_EZT ) { + if( ggMainButton.SubModel != nullptr ) { + ggMainButton.UpdateValue( 0.0 ); + // audio feedback + play_sound( dsbSwitch ); + } + } + m_linebreakerclosed = true; + } + } + break; + } + + case user_command::convertertoggle: { + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == mvControlled->ConverterAllow ) { + // turn on + if( ( mvControlled->EnginePowerSource.SourceType != CurrentCollector ) + || ( mvControlled->PantRearVolt != 0.0 ) + || ( mvControlled->PantFrontVolt != 0.0 ) ) { + // visual feedback + ggConverterButton.UpdateValue( 1.0 ); + // sound feedback + if( ggConverterButton.GetValue() < 0.5 ) { + play_sound( dsbSwitch ); + } + // impulse type switch has no effect if there's no power + // NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway + if( ( mvOccupied->ConvSwitchType != "impulse" ) + || ( mvControlled->Mains ) ) { + if( true == mvControlled->ConverterSwitch( true ) ) { + // side effects + // control the compressor, if it's paired with the converter + if( mvControlled->CompressorPower == 2 ) { + // hunter-091012: tak jest poprawnie + mvControlled->CompressorSwitch( true ); + } + } + } + } + } + else { + //turn off + if( true == mvControlled->ConverterSwitch( false ) ) { + // sound feedback + play_sound( dsbSwitch ); + // visual feedback + ggConverterButton.UpdateValue( 0.0 ); + if( ggConverterOffButton.SubModel != nullptr ) { + ggConverterOffButton.UpdateValue( 1.0 ); + } + // side effects + // control the compressor, if it's paired with the converter + if( mvControlled->CompressorPower == 2 ) { + // hunter-091012: tak jest poprawnie + mvControlled->CompressorSwitch( false ); + } + if( ( mvControlled->TrainType == dt_EZT ) + && ( !TestFlag( mvControlled->EngDmgFlag, 4 ) ) ) { + mvControlled->ConvOvldFlag = false; + } + } + } + } + else if( Command.action == GLFW_RELEASE ){ + // on button release... + if( mvOccupied->ConvSwitchType == "impulse" ) { + // ...return switches to start position if applicable + if( ( ggConverterButton.GetValue() > 0.0 ) + || ( ggConverterOffButton.GetValue() > 0.0 ) ) { + // sound feedback + play_sound( dsbSwitch ); + } + ggConverterButton.UpdateValue( 0.0 ); + ggConverterOffButton.UpdateValue( 0.0 ); + } + } + break; + } + + case user_command::compressortoggle: { + + if( mvControlled->CompressorPower < 2 ) { + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == mvControlled->CompressorAllow ) { + // turn on + // visual feedback + ggCompressorButton.UpdateValue( 1.0 ); + // sound feedback + if( ggCompressorButton.GetValue() < 0.5 ) { + play_sound( dsbSwitch ); + } + // impulse type switch has no effect if there's no power + // NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway + // (we're presuming impulse type switch for all EMUs for the time being) +/* + if( ( mvControlled->TrainType != dt_EZT ) + || ( mvControlled->Mains ) ) { +*/ + mvControlled->CompressorSwitch( true ); +/* + } +*/ + } + else { + //turn off + if( true == mvControlled->CompressorSwitch( false ) ) { + // sound feedback + play_sound( dsbSwitch ); + // NOTE: we don't have switch type definition for the compresor switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz +/* + if( mvControlled->TrainType == dt_EZT ) { + // visual feedback + ggCompressorButton.UpdateValue( 1.0 ); + } + else { +*/ + // visual feedback + ggCompressorButton.UpdateValue( 0.0 ); +/* + } +*/ + } + } + } + else if( Command.action == GLFW_RELEASE ) { + // on button release... +/* + // TODO: check if compressor switch is two-state or impulse type + // NOTE: we don't have switch type definition for the compresor switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz + if( mvControlled->TrainType == dt_EZT ) { + if( ggCompressorButton.SubModel != nullptr ) { + ggCompressorButton.UpdateValue( 0.0 ); + // audio feedback + play_sound( dsbSwitch ); + } + } +*/ + } + } + break; + } + default: { break; @@ -852,23 +1371,7 @@ void TTrain::OnKeyDown(int cKey) ; else ; -#endif - // McZapkie-240302 - wlaczanie glownego obwodu klawiszem M+shift - //----------- - // hunter-141211: wyl. szybki zalaczony przeniesiony do TTrain::Update() - /* if (cKey==Global::Keys[k_Main]) - { - ggMainOnButton.PutValue(1); - if (mvControlled->MainSwitch(true)) - { - if (mvControlled->EngineType==DieselEngine) - dsbDieselIgnition->Play(0,0,0); - else - dsbNastawnikJazdy->Play(0,0,0); - } - } - else */ - if (cKey == Global::Keys[k_Battery]) + if( cKey == Global::Keys[ k_Battery ] ) { // if // (((mvControlled->TrainType==dt_EZT)||(mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->EngineType==DieselElectric))&&(!mvControlled->Battery)) @@ -895,7 +1398,8 @@ void TTrain::OnKeyDown(int cKey) } } } - else if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // shift&ctrl are used for light dimming +#endif + if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // shift&ctrl are used for light dimming { if (mvControlled->TrainType == dt_EZT) { @@ -930,7 +1434,8 @@ void TTrain::OnKeyDown(int cKey) } } } - if (cKey == Global::Keys[k_Main]) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( cKey == Global::Keys[ k_Main ] ) { if (fabs(ggMainOnButton.GetValue()) < 0.001) if (dsbSwitch) @@ -939,6 +1444,7 @@ void TTrain::OnKeyDown(int cKey) dsbSwitch->Play(0, 0, 0); } } +#endif else if (cKey == Global::Keys[k_BrakeProfile]) // McZapkie-240302-B: //----------- @@ -991,34 +1497,7 @@ void TTrain::OnKeyDown(int cKey) } } } - //----------- - // hunter-261211: przetwornica i sprzezarka przeniesione do - // TTrain::Update() - /* if (cKey==Global::Keys[k_Converter]) //NBMX 14-09-2003: -przetwornica wl - { -if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || -(mvControlled->EnginePowerSource.SourceType!=CurrentCollector) || -(!Global::bLiveTraction)) - if (mvControlled->ConverterSwitch(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0,0,0); - } - } - else - if (cKey==Global::Keys[k_Compressor]) //NBMX 14-09-2003: sprezarka wl - { - if ((mvControlled->ConverterFlag) || -(mvControlled->CompressorPower<2)) - if (mvControlled->CompressorSwitch(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0,0,0); - } - } - else */ - +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_Converter]) { if (ggConverterButton.GetValue() == 0) @@ -1040,7 +1519,8 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || dsbSwitch->Play(0, 0, 0); } } - else if (cKey == Global::Keys[k_SmallCompressor]) // Winger 160404: mala +#endif + else if( cKey == Global::Keys[ k_SmallCompressor ] ) // Winger 160404: mala // sprezarka wl { // Ra: dźwięk, gdy razem z [Shift] if ((mvControlled->TrainType & dt_EZT) ? mvControlled == mvOccupied : @@ -1184,7 +1664,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } } } - +#ifdef EU07_USE_OLD_COMMAND_SYSTEM //----------- else if (cKey == Global::Keys[k_PantFrontUp]) { // Winger 160204: podn. @@ -1243,7 +1723,8 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } } } - else if (cKey == Global::Keys[k_Active]) // yB 300407: przelacznik rozrzadu +#endif + else if( cKey == Global::Keys[ k_Active ] ) // yB 300407: przelacznik rozrzadu { // Ra 2014-06: uruchomiłem to, aby aktywować czuwak w zajmowanym członie, // a wyłączyć w innych // Ra 2014-03: aktywacja czuwaka przepięta na ustawienie kierunku w @@ -1839,7 +2320,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || if (Global::ctrlState) // z controlem { ggConverterFuseButton.PutValue(1); // hunter-261211 - if ((mvControlled->Mains == false) && (ggConverterButton.GetValue() == 0) && + if ((mvControlled->Mains == false) && (ggConverterButton.GetValue() < 0.01) && (mvControlled->TrainType != dt_EZT)) mvControlled->ConvOvldFlag = false; } @@ -1913,7 +2394,8 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } #endif } - else if (cKey == Global::Keys[k_Main]) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + else if( cKey == Global::Keys[ k_Main ] ) // McZapkie-240302 - wylaczanie glownego obwodu //----------- // hunter-141211: wyl. szybki wylaczony przeniesiony do TTrain::Update() @@ -1925,7 +2407,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || dsbSwitch->Play(0, 0, 0); } } - else if (cKey == Global::Keys[k_Battery]) + else if( cKey == Global::Keys[ k_Battery ] ) { // if ((mvControlled->TrainType==dt_EZT) || // (mvControlled->EngineType==ElectricSeriesMotor)|| @@ -1944,7 +2426,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || mvControlled->PantRear(false); } } - +#endif //----------- // if (cKey==Global::Keys[k_Active]) //yB 300407: przelacznik // rozrzadu @@ -2006,6 +2488,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_Converter]) //----------- // hunter-261211: przetwornica i sprzezarka przeniesione do @@ -2030,7 +2513,6 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } } //----------- -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if( cKey == Global::Keys[ k_Releaser ] ) // odluzniacz { if (!FreeFlyModeFlag) @@ -2052,8 +2534,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || } } #endif - else if (cKey == Global::Keys[k_SmallCompressor]) // Winger 160404: mala - // sprezarka wl + else if (cKey == Global::Keys[k_SmallCompressor]) // Winger 160404: mala sprezarka wl { // Ra: bez [Shift] też dać dźwięk if ((mvControlled->TrainType & dt_EZT) ? mvControlled == mvOccupied : !mvOccupied->ActiveCab) // tylko w maszynowym @@ -2164,9 +2645,7 @@ if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || false; // wyjście z maszynowego wyłącza sprężarkę pomocniczą } else if (cKey == Global::Keys[k_Couple]) - { // ABu051104: male zmiany, zeby - // mozna bylo laczyc odlegle - // wagony + { // ABu051104: male zmiany, zeby mozna bylo laczyc odlegle wagony // da sie zoptymalizowac, ale nie ma na to czasu :( if (iCabn > 0) { @@ -2409,6 +2888,7 @@ if } } //----------- +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_PantFrontDown]) // Winger 160204: // opuszczanie prz. patyka { @@ -2462,7 +2942,8 @@ if } } } - else if (cKey == Global::Keys[k_Heating]) // Winger 020304: ogrzewanie - +#endif + else if( cKey == Global::Keys[ k_Heating ] ) // Winger 020304: ogrzewanie - // wylaczenie { // Ra 2014-09: w trybie latania obsługa jest w World.cpp if (!FreeFlyModeFlag) @@ -3061,6 +3542,7 @@ bool TTrain::Update( double const Deltatime ) DWORD stat; double dt = Deltatime; // Timer::GetDeltaTime(); + if (DynamicObject->mdKabina) { // Ra: TODO: odczyty klawiatury/pulpitu nie // powinny być uzależnione od istnienia modelu @@ -3327,8 +3809,10 @@ bool TTrain::Update( double const Deltatime ) if (mvControlled->TrainType != dt_EZT) mvControlled->MainSwitch(false); } - else if (fConverterTimer >= fConverterPrzekaznik) - mvControlled->CompressorSwitch(true); + else if( fConverterTimer >= fConverterPrzekaznik ) { + // changed switch from always true to take into account state of the compressor switch + mvControlled->CompressorSwitch( mvControlled->CompressorAllow ); + } } } else @@ -4473,17 +4957,29 @@ bool TTrain::Update( double const Deltatime ) //--------- // Winger 010304 - pantografy - if (ggPantFrontButton.SubModel) + // NOTE: shouldn't the pantograph updates check whether it's front or rear cabin? + if (ggPantFrontButton.SubModel ) { - if (mvControlled->PantFrontUp) - ggPantFrontButton.PutValue(1); - else - ggPantFrontButton.PutValue(0); + if( mvOccupied->PantSwitchType != "impulse" ) { + ggPantFrontButton.UpdateValue( + ( mvOccupied->ActiveCab == 1 ? + mvControlled->PantFrontUp : + mvControlled->PantRearUp ) ? + 1.0 : + 0.0 ); + } ggPantFrontButton.Update(); } if (ggPantRearButton.SubModel) { - ggPantRearButton.PutValue(mvControlled->PantRearUp ? 1 : 0); + if( mvOccupied->PantSwitchType != "impulse" ) { + ggPantRearButton.UpdateValue( + ( mvOccupied->ActiveCab == 1 ? + mvControlled->PantRearUp : + mvControlled->PantFrontUp ) ? + 1.0 : + 0.0 ); + } ggPantRearButton.Update(); } if (ggPantFrontButtonOff.SubModel) @@ -4492,8 +4988,7 @@ bool TTrain::Update( double const Deltatime ) } // Winger 020304 - ogrzewanie //---------- - // hunter-080812: poprawka na ogrzewanie w elektrykach - usuniete - // uzaleznienie od przetwornicy + // hunter-080812: poprawka na ogrzewanie w elektrykach - usuniete uzaleznienie od przetwornicy if (ggTrainHeatingButton.SubModel) { if (mvControlled->Heating) @@ -4633,8 +5128,8 @@ bool TTrain::Update( double const Deltatime ) { SetFlag(mvOccupied->WarningSignal, 2); } - //---------------- +#ifdef EU07_USE_OLD_COMMAND_SYSTEM // hunter-141211: wyl. szybki zalaczony i wylaczony przeniesiony z // OnKeyPress() if (Global::shiftState && Console::Pressed(Global::Keys[k_Main])) @@ -4670,7 +5165,6 @@ bool TTrain::Update( double const Deltatime ) ggMainOnButton.UpdateValue(0); } //--- - if (!Global::shiftState && Console::Pressed(Global::Keys[k_Main])) { ggMainOffButton.PutValue(1); @@ -4679,7 +5173,7 @@ bool TTrain::Update( double const Deltatime ) } else ggMainOffButton.UpdateValue(0); - +#endif /* if (cKey==Global::Keys[k_Main]) //z shiftem { ggMainOnButton.PutValue(1); @@ -4809,6 +5303,7 @@ bool TTrain::Update( double const Deltatime ) else ggAntiSlipButton.UpdateValue(0); //----------------- +#ifdef EU07_USE_OLD_COMMAND_SYSTEM // hunter-261211: przetwornica i sprezarka if (Global::shiftState && Console::Pressed(Global::Keys[k_Converter])) // NBMX 14-09-2003: przetwornica wl @@ -4832,7 +5327,6 @@ bool TTrain::Update( double const Deltatime ) ggConverterOffButton.PutValue(0); } } - // if ( // Global::shiftState&&Console::Pressed(Global::Keys[k_Compressor])&&((mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->TrainType==dt_EZT)) // ) //NBMX 14-09-2003: sprezarka wl @@ -4842,7 +5336,6 @@ bool TTrain::Update( double const Deltatime ) ggCompressorButton.PutValue(1); mvControlled->CompressorSwitch(true); } - if (!Global::shiftState && Console::Pressed(Global::Keys[k_Converter])) // NBMX 14-09-2003: przetwornica wl { @@ -4852,7 +5345,6 @@ bool TTrain::Update( double const Deltatime ) if ((mvControlled->TrainType == dt_EZT) && (!TestFlag(mvControlled->EngDmgFlag, 4))) mvControlled->ConvOvldFlag = false; } - // if ( // !Global::shiftState&&Console::Pressed(Global::Keys[k_Compressor])&&((mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->TrainType==dt_EZT)) // ) //NBMX 14-09-2003: sprezarka wl @@ -4862,7 +5354,7 @@ bool TTrain::Update( double const Deltatime ) ggCompressorButton.PutValue(0); mvControlled->CompressorSwitch(false); } - +#endif /* bez szifta if (cKey==Global::Keys[k_Converter]) //NBMX wyl przetwornicy @@ -5231,7 +5723,7 @@ bool TTrain::Update( double const Deltatime ) if (!DynamicObject->Mechanik->AIControllFlag) // tylko jeśli nie prowadzi AI mvControlled->DepartureSignal = false; } - +#ifdef EU07_USE_OLD_COMMAND_SYSTEM if (Console::Pressed(Global::Keys[k_Main])) //[] { if (Global::shiftState) @@ -5241,7 +5733,7 @@ bool TTrain::Update( double const Deltatime ) } else ggMainButton.PutValue(0); - +#endif if (Console::Pressed(Global::Keys[k_CurrentNext])) { if (mvControlled->TrainType != dt_EZT) @@ -5299,7 +5791,7 @@ bool TTrain::Update( double const Deltatime ) } } } - +#ifdef EU07_USE_OLD_COMMAND_SYSTEM // Winger 010304 PantAllDownButton if (Console::Pressed(Global::Keys[k_PantFrontUp])) { @@ -5313,7 +5805,6 @@ bool TTrain::Update( double const Deltatime ) ggPantFrontButton.PutValue(0); ggPantAllDownButton.PutValue(0); } - if (Console::Pressed(Global::Keys[k_PantRearUp])) { if (Global::shiftState) @@ -5326,7 +5817,7 @@ bool TTrain::Update( double const Deltatime ) ggPantRearButton.PutValue(0); ggPantFrontButtonOff.PutValue(0); } - +#endif /* if ((mvControlled->Mains) && (mvControlled->EngineType==ElectricSeriesMotor)) { @@ -5428,8 +5919,10 @@ bool TTrain::Update( double const Deltatime ) ggUniversal4Button.PermIncValue(dt); ggUniversal4Button.Update(); +/* ggMainOffButton.UpdateValue(0); ggMainOnButton.UpdateValue(0); +*/ ggSecurityResetButton.UpdateValue(0); /* ggReleaserButton.UpdateValue(0); diff --git a/Train.h b/Train.h index d34ff700..11366a7d 100644 --- a/Train.h +++ b/Train.h @@ -111,6 +111,9 @@ class TTrain // NOTE: temporary routine until sound system is sorted out and paired with switches void play_sound( PSound Sound, PSound Fallbacksound = nullptr ); + // helper variable, to prevent immediate switch between closing and opening line breaker circuit + bool m_linebreakerclosed{ false }; + private: //żeby go nic z zewnątrz nie przestawiało TDynamicObject *DynamicObject; // przestawia zmiana pojazdu [F5] private: //żeby go nic z zewnątrz nie przestawiało diff --git a/command.cpp b/command.cpp index b1bde4f4..edbb388f 100644 --- a/command.cpp +++ b/command.cpp @@ -78,14 +78,16 @@ command_relay::command_relay() { /* const int k_AntiSlipping = 21; const int k_Sand = 22; -const int k_Main = 23; */ + { user_command::linebreakertoggle, command_target::vehicle }, { user_command::reverserincrease, command_target::vehicle }, { user_command::reverserdecrease, command_target::vehicle }, /* const int k_Fuse = 26; -const int k_Compressor = 27; -const int k_Converter = 28; +*/ + { user_command::compressortoggle, command_target::vehicle }, + { user_command::convertertoggle, command_target::vehicle }, +/* const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; const int k_BrakeProfile = 31; @@ -107,15 +109,7 @@ const int k_FailedEngineCutOff = 35; { user_command::moveforwardfast, command_target::entity }, { user_command::movebackfast, command_target::entity }, { user_command::moveupfast, command_target::entity }, - { user_command::movedownfast, command_target::entity } -/* - { user_command::moveleftfastest, command_target::entity }, - { user_command::moverightfastest, command_target::entity }, - { user_command::moveforwardfastest, command_target::entity }, - { user_command::movebackfastest, command_target::entity }, - { user_command::moveupfastest, command_target::entity }, - { user_command::movedownfastest, command_target::entity } -*/ + { user_command::movedownfast, command_target::entity }, /* const int k_CabForward = 42; const int k_CabBackward = 43; @@ -129,10 +123,10 @@ const int k_OpenRight = 50; const int k_CloseLeft = 51; const int k_CloseRight = 52; const int k_DepartureSignal = 53; -const int k_PantFrontUp = 54; -const int k_PantRearUp = 55; -const int k_PantFrontDown = 56; -const int k_PantRearDown = 57; +*/ + { user_command::pantographtogglefront, command_target::vehicle }, + { user_command::pantographtogglerear, command_target::vehicle }, +/* const int k_Heating = 58; // const int k_FreeFlyMode= 59; const int k_LeftSign = 60; @@ -147,7 +141,9 @@ const int k_Univ3 = 68; const int k_Univ4 = 69; const int k_EndSign = 70; const int k_Active = 71; -const int k_Battery = 72; +*/ + { user_command::batterytoggle, command_target::vehicle } +/* const int k_WalkMode = 73; int const k_DimHeadlights = 74; */ @@ -180,14 +176,16 @@ int const k_DimHeadlights = 74; /* const int k_AntiSlipping = 21; const int k_Sand = 22; -const int k_Main = 23; */ + "linebreakertoggle", "reverserincrease", "reverserdecrease", /* const int k_Fuse = 26; -const int k_Compressor = 27; -const int k_Converter = 28; +*/ + "compressortoggle", + "convertertoggle", +/* const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; const int k_BrakeProfile = 31; @@ -209,15 +207,7 @@ const int k_FailedEngineCutOff = 35; "", //"moveforwardfast", "", //"movebackfast", "", //"moveupfast", - "" //"movedownfast" -/* - "moveleftfastest", - "moverightfastest", - "moveforwardfastest", - "movebackfastest", - "moveupfastest", - "movedownfastest" -*/ + "", //"movedownfast" /* const int k_CabForward = 42; const int k_CabBackward = 43; @@ -231,10 +221,10 @@ const int k_OpenRight = 50; const int k_CloseLeft = 51; const int k_CloseRight = 52; const int k_DepartureSignal = 53; -const int k_PantFrontUp = 54; -const int k_PantRearUp = 55; -const int k_PantFrontDown = 56; -const int k_PantRearDown = 57; +*/ + "pantographtogglefront", + "pantographtogglerear", +/* const int k_Heating = 58; // const int k_FreeFlyMode= 59; const int k_LeftSign = 60; @@ -249,7 +239,9 @@ const int k_Univ3 = 68; const int k_Univ4 = 69; const int k_EndSign = 70; const int k_Active = 71; -const int k_Battery = 72; +*/ + "batterytoggle" +/* const int k_WalkMode = 73; int const k_DimHeadlights = 74; */ diff --git a/command.h b/command.h index ad02d2f7..313cc5bf 100644 --- a/command.h +++ b/command.h @@ -38,14 +38,16 @@ enum class user_command { /* const int k_AntiSlipping = 21; const int k_Sand = 22; -const int k_Main = 23; */ + linebreakertoggle, reverserincrease, reverserdecrease, /* const int k_Fuse = 26; -const int k_Compressor = 27; -const int k_Converter = 28; +*/ + compressortoggle, + convertertoggle, +/* const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; const int k_BrakeProfile = 31; @@ -67,15 +69,7 @@ const int k_FailedEngineCutOff = 35; moveforwardfast, movebackfast, moveupfast, - movedownfast -/* - moveleftfastest, - moverightfastest, - moveforwardfastest, - movebackfastest, - moveupfastest, - movedownfastest -*/ + movedownfast, /* const int k_CabForward = 42; const int k_CabBackward = 43; @@ -89,10 +83,10 @@ const int k_OpenRight = 50; const int k_CloseLeft = 51; const int k_CloseRight = 52; const int k_DepartureSignal = 53; -const int k_PantFrontUp = 54; -const int k_PantRearUp = 55; -const int k_PantFrontDown = 56; -const int k_PantRearDown = 57; +*/ + pantographtogglefront, + pantographtogglerear, +/* const int k_Heating = 58; // const int k_FreeFlyMode= 59; const int k_LeftSign = 60; @@ -107,11 +101,12 @@ const int k_Univ3 = 68; const int k_Univ4 = 69; const int k_EndSign = 70; const int k_Active = 71; -const int k_Battery = 72; +*/ + batterytoggle +/* const int k_WalkMode = 73; int const k_DimHeadlights = 74; */ - }; enum class command_target { diff --git a/gamepadinput.cpp b/gamepadinput.cpp index 2c1dfa1a..3240b3cd 100644 --- a/gamepadinput.cpp +++ b/gamepadinput.cpp @@ -188,7 +188,7 @@ gamepad_input::on_button( gamepad_button const Button, int const Action ) { void gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, glm::vec2 const &Triggers ) { - // left stick, look around + // right stick, look around if( ( Rightstick.x != 0.0f ) || ( Rightstick.y != 0.0f ) ) { // TODO: make toggles for the axis flip auto const deltatime = Timer::GetDeltaRenderTime() * 60.0; @@ -204,7 +204,7 @@ gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, g 0 ); } - // right stick, either movement or controls, depending on currently active mode + // left stick, either movement or controls, depending on currently active mode if( m_mode == control_mode::entity ) { if( ( Leftstick.x != 0.0 || Leftstick.y != 0.0 ) @@ -218,45 +218,6 @@ gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, g GLFW_PRESS, 0 ); } -/* - Leftstick = circle_to_square( Leftstick ); - if( Leftstick.y >= 0.0f ) { - // forward - process_axis( - Leftstick.y, m_leftstick.y, - 1.0, - user_command::moveforward, - user_command::moveforwardfast, - 0 ); - } - if( Leftstick.y <= 0.0f ) { - // back - process_axis( - Leftstick.y, m_leftstick.y, - -1.0, - user_command::moveback, - user_command::movebackfast, - 0 ); - } - if( Leftstick.x >= 0.0f ) { - // right - process_axis( - Leftstick.x, m_leftstick.x, - 1.0, - user_command::moveright, - user_command::moverightfast, - 0 ); - } - if( Leftstick.x <= 0.0f ) { - // left - process_axis( - Leftstick.x, m_leftstick.x, - -1.0, - user_command::moveleft, - user_command::moveleftfast, - 0 ); - } -*/ } else { // vehicle control modes @@ -317,7 +278,7 @@ gamepad_input::process_mode( float const Value, std::uint16_t const Recipient ) m_modeaccumulator = 0.0f; } if( Value > m_deadzone ) { - m_modeaccumulator += Value * deltatime; + m_modeaccumulator += ( Value - m_deadzone ) / ( 1.0 - m_deadzone ) * deltatime; while( m_modeaccumulator >= 1.0f ) { // send commands if the accumulator(s) was filled m_relay.post( @@ -335,7 +296,7 @@ gamepad_input::process_mode( float const Value, std::uint16_t const Recipient ) m_modeaccumulator = 0.0f; } if( Value < m_deadzone ) { - m_modeaccumulator += Value * deltatime; + m_modeaccumulator += ( Value + m_deadzone ) / ( 1.0 - m_deadzone ) * deltatime; while( m_modeaccumulator <= -1.0f ) { // send commands if the accumulator(s) was filled m_relay.post( diff --git a/keyboardinput.cpp b/keyboardinput.cpp index eacbee31..03f48a13 100644 --- a/keyboardinput.cpp +++ b/keyboardinput.cpp @@ -31,6 +31,7 @@ keyboard_input::key( int const Key, int const Action ) { false : true ); modifier = true; + // whenever shift key is used it may affect currently pressed movement keys, so check and update these } if( ( Key == GLFW_KEY_LEFT_CONTROL ) || ( Key == GLFW_KEY_RIGHT_CONTROL ) ) { // update internal state, but don't bother passing these @@ -45,6 +46,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; + } + // include active modifiers for currently pressed key, except if the key is a modifier itself auto const key = Key @@ -106,14 +117,16 @@ keyboard_input::default_bindings() { /* const int k_AntiSlipping = 21; const int k_Sand = 22; -const int k_Main = 23; */ + { "linebreakertoggle", command_target::vehicle, GLFW_KEY_M }, { "reverserincrease", command_target::vehicle, GLFW_KEY_D }, { "reverserdecrease", command_target::vehicle, GLFW_KEY_R }, /* const int k_Fuse = 26; -const int k_Compressor = 27; -const int k_Converter = 28; +*/ + { "compressortoggle", command_target::vehicle, GLFW_KEY_C }, + { "convertertoggle", command_target::vehicle, GLFW_KEY_X }, +/* const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; const int k_BrakeProfile = 31; @@ -130,20 +143,12 @@ const int k_FailedEngineCutOff = 35; { "moveback", command_target::entity, GLFW_KEY_DOWN }, { "moveup", command_target::entity, GLFW_KEY_PAGE_UP }, { "movedown", command_target::entity, GLFW_KEY_PAGE_DOWN }, - { "moveleftfast", command_target::entity, GLFW_KEY_LEFT | keymodifier::shift }, - { "moverightfast", command_target::entity, GLFW_KEY_RIGHT | keymodifier::shift }, - { "moveforwardfast", command_target::entity, GLFW_KEY_UP | keymodifier::shift }, - { "movebackfast", command_target::entity, GLFW_KEY_DOWN | keymodifier::shift }, - { "moveupfast", command_target::entity, GLFW_KEY_PAGE_UP | keymodifier::shift }, - { "movedownfast", command_target::entity, GLFW_KEY_PAGE_DOWN | keymodifier::shift } -/* - { "moveleftfastest", command_target::entity, GLFW_KEY_LEFT | keymodifier::control }, - { "moverightfastest", command_target::entity, GLFW_KEY_RIGHT | keymodifier::control }, - { "moveforwardfastest", command_target::entity, GLFW_KEY_UP | keymodifier::control }, - { "movebackfastest", command_target::entity, GLFW_KEY_DOWN | keymodifier::control }, - { "moveupfastest", command_target::entity, GLFW_KEY_PAGE_UP | keymodifier::control }, - { "movedownfastest", command_target::entity, GLFW_KEY_PAGE_DOWN | keymodifier::control } -*/ + { "moveleftfast", command_target::entity, -1 }, + { "moverightfast", command_target::entity, -1 }, + { "moveforwardfast", command_target::entity, -1 }, + { "movebackfast", command_target::entity, -1 }, + { "moveupfast", command_target::entity, -1 }, + { "movedownfast", command_target::entity, -1 }, /* const int k_CabForward = 42; const int k_CabBackward = 43; @@ -157,10 +162,10 @@ const int k_OpenRight = 50; const int k_CloseLeft = 51; const int k_CloseRight = 52; const int k_DepartureSignal = 53; -const int k_PantFrontUp = 54; -const int k_PantRearUp = 55; -const int k_PantFrontDown = 56; -const int k_PantRearDown = 57; +*/ + { "pantographtogglefront", command_target::vehicle, GLFW_KEY_P }, + { "pantographtogglerear", command_target::vehicle, GLFW_KEY_O }, +/* const int k_Heating = 58; // const int k_FreeFlyMode= 59; const int k_LeftSign = 60; @@ -175,7 +180,9 @@ const int k_Univ3 = 68; const int k_Univ4 = 69; const int k_EndSign = 70; const int k_Active = 71; -const int k_Battery = 72; +*/ + { "batterytoggle", command_target::vehicle, GLFW_KEY_J } +/* const int k_WalkMode = 73; int const k_DimHeadlights = 74; */ @@ -199,6 +206,117 @@ keyboard_input::bind() { } ++commandcode; } + // cache movement key bindings, so we can test them faster in the input loop + m_bindingscache.forward = m_commands[ static_cast( user_command::moveforward ) ].binding; + m_bindingscache.back = m_commands[ static_cast( user_command::moveback ) ].binding; + m_bindingscache.left = m_commands[ static_cast( user_command::moveleft ) ].binding; + m_bindingscache.right = m_commands[ static_cast( user_command::moveright ) ].binding; + m_bindingscache.up = m_commands[ static_cast( user_command::moveup ) ].binding; + m_bindingscache.down = m_commands[ static_cast( user_command::movedown ) ].binding; +} + +// NOTE: ugliest code ever, gg +bool +keyboard_input::update_movement( int const Key, int const Action ) { + + bool shift = + ( ( Key == GLFW_KEY_LEFT_SHIFT ) + || ( Key == GLFW_KEY_RIGHT_SHIFT ) ); + bool movementkey = + ( ( Key == m_bindingscache.forward ) + || ( Key == m_bindingscache.back ) + || ( Key == m_bindingscache.left ) + || ( Key == m_bindingscache.right ) + || ( Key == m_bindingscache.up ) + || ( Key == m_bindingscache.down ) ); + + if( false == ( shift || movementkey ) ) { return false; } + + 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 ] ); } + } + + return false; } //--------------------------------------------------------------------------- diff --git a/keyboardinput.h b/keyboardinput.h index c8e2fb43..1c92acdf 100644 --- a/keyboardinput.h +++ b/keyboardinput.h @@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/. #pragma once #include +#include #include "command.h" class keyboard_input { @@ -44,11 +45,23 @@ private: typedef std::vector commandsetup_sequence; typedef std::unordered_map usercommand_map; + struct bindings_cache { + + int forward{ -1 }; + int back{ -1 }; + int left{ -1 }; + int right{ -1 }; + int up{ -1 }; + int down{ -1 }; + }; + // methods void default_bindings(); void bind(); + bool + update_movement( int const Key, int const Action ); // members commandsetup_sequence m_commands; @@ -56,6 +69,8 @@ private: command_relay m_relay; bool m_shift{ false }; bool m_ctrl{ false }; + bindings_cache m_bindingscache; + std::array m_keys; }; //--------------------------------------------------------------------------- diff --git a/maszyna.vcxproj.user b/maszyna.vcxproj.user index 3aea8305..803ce541 100644 --- a/maszyna.vcxproj.user +++ b/maszyna.vcxproj.user @@ -1,7 +1,7 @@  - ..\..\Projects\maszyna + ..\..\..\development\maszyna WindowsLocalDebugger @@ -9,11 +9,11 @@ WindowsLocalDebugger - ..\..\Projects\maszyna + ..\..\..\development\maszyna WindowsLocalDebugger - ..\..\Projects\maszyna + ..\..\..\development\maszyna WindowsLocalDebugger _NO_DEBUG_HEAP=1 @@ -23,7 +23,7 @@ _NO_DEBUG_HEAP=1 - ..\..\Projects\maszyna + ..\..\..\development\maszyna WindowsLocalDebugger _NO_DEBUG_HEAP=1 From fafb7a63c3951e8a29f9a34c7a1699cae4f45792 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Thu, 13 Apr 2017 15:56:28 +0200 Subject: [PATCH 04/12] control for alerter, doors, vehicle lights. support for multiple logs. fixes for relaytype 45, 46 --- EU07.cpp | 6 +- Globals.cpp | 7 +- Globals.h | 1 + Ground.cpp | 8 +- Logs.cpp | 47 +- McZapkie/MOVER.h | 21 +- McZapkie/Mover.cpp | 256 ++-- McZapkie/mctools.cpp | 20 +- McZapkie/mctools.h | 2 +- Train.cpp | 2529 ++++++++++++++++++++++++--------------- Train.h | 100 +- World.cpp | 31 +- command.cpp | 57 +- command.h | 26 +- keyboardinput.cpp | 27 +- maszyna.vcxproj.filters | 4 +- renderer.cpp | 2 +- stdafx.h | 1 + 18 files changed, 1951 insertions(+), 1194 deletions(-) diff --git a/EU07.cpp b/EU07.cpp index b69a5398..f36b2573 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -214,7 +214,11 @@ int main(int argc, char *argv[]) if (!glfwInit()) return -1; - DeleteFile("errors.txt"); +#ifdef _WINDOWS + DeleteFile( "log.txt" ); + DeleteFile( "errors.txt" ); + _mkdir("logs"); +#endif Global::LoadIniFile("eu07.ini"); Global::InitKeys(); diff --git a/Globals.cpp b/Globals.cpp index 5663318f..e5cd1de9 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -166,6 +166,7 @@ bool Global::bOldSmudge = false; // Używanie starej smugi bool Global::bWireFrame = false; bool Global::bSoundEnabled = true; int Global::iWriteLogEnabled = 3; // maska bitowa: 1-zapis do pliku, 2-okienko, 4-nazwy torów +bool Global::MultipleLogs{ false }; bool Global::bManageNodes = true; bool Global::bDecompressDDS = false; // czy programowa dekompresja DDS @@ -374,7 +375,11 @@ void Global::ConfigParse(cParser &Parser) Global::iWriteLogEnabled = stol_def(token,3); } } - else if (token == "adjustscreenfreq") + else if( token == "multiplelogs" ) { + Parser.getTokens(); + Parser >> Global::MultipleLogs; + } + else if( token == "adjustscreenfreq" ) { // McZapkie-240403 - czestotliwosc odswiezania ekranu Parser.getTokens(); diff --git a/Globals.h b/Globals.h index 26e9d8be..d2d48623 100644 --- a/Globals.h +++ b/Globals.h @@ -214,6 +214,7 @@ class Global static void SetCameraPosition(Math3D::vector3 pNewCameraPosition); static void SetCameraRotation(double Yaw); static int iWriteLogEnabled; // maska bitowa: 1-zapis do pliku, 2-okienko + static bool MultipleLogs; // McZapkie-221002: definicja swiatla dziennego static float Background[3]; static GLfloat AtmoColor[]; diff --git a/Ground.cpp b/Ground.cpp index 393f2dbc..c01957bb 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -386,7 +386,7 @@ void TGroundNode::RenderAlphaVBO() if( ( PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012 { glDisable( GL_BLEND ); - glAlphaFunc( GL_GREATER, 0.45f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f + glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f }; #endif @@ -662,7 +662,7 @@ void TGroundNode::RenderAlphaDL() if ((PROBLEND)) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012 { glDisable(GL_BLEND); - glAlphaFunc(GL_GREATER, 0.45f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f + glAlphaFunc(GL_GREATER, 0.50f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f }; #endif if (!DisplayListID) //||Global::bReCompile) //Ra: wymuszenie rekompilacji @@ -4758,7 +4758,7 @@ TGround::Render( Math3D::vector3 const &Camera ) { bool TGround::RenderDL(vector3 pPosition) { // renderowanie scenerii z Display List - faza nieprzezroczystych glDisable(GL_BLEND); - glAlphaFunc(GL_GREATER, 0.45f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f + glAlphaFunc(GL_GREATER, 0.50f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f ++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji) CameraDirection.x = sin(Global::pCameraRotation); // wektor kierunkowy CameraDirection.z = cos(Global::pCameraRotation); @@ -4848,7 +4848,7 @@ bool TGround::RenderAlphaDL(vector3 pPosition) bool TGround::RenderVBO(vector3 pPosition) { // renderowanie scenerii z VBO - faza nieprzezroczystych glDisable(GL_BLEND); - glAlphaFunc(GL_GREATER, 0.45f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f + glAlphaFunc(GL_GREATER, 0.50f); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f ++TGroundRect::iFrameNumber; // zwięszenie licznika ramek CameraDirection.x = sin(Global::pCameraRotation); // wektor kierunkowy CameraDirection.z = cos(Global::pCameraRotation); diff --git a/Logs.cpp b/Logs.cpp index eff68c90..a4a22fb0 100644 --- a/Logs.cpp +++ b/Logs.cpp @@ -18,6 +18,33 @@ std::ofstream comms; // lista komunikatow "comms.txt", można go wyłączyć char endstring[10] = "\n"; +std::string filename_date() { + + ::SYSTEMTIME st; + ::GetSystemTime( &st ); + char buffer[ 256 ]; + sprintf( buffer, + "%d%02d%02d_%02d%02d", + st.wYear, + st.wMonth, + st.wDay, + st.wHour, + st.wMinute ); + + return std::string( buffer ); +} + +std::string filename_scenery() { + + auto extension = Global::SceneryFile.rfind( '.' ); + if( extension != std::string::npos ) { + return Global::SceneryFile.substr( 0, extension ); + } + else { + return Global::SceneryFile; + } +} + void WriteConsoleOnly(const char *str, double value) { char buf[255]; @@ -57,8 +84,14 @@ void WriteLog(const char *str, bool newline) { if (Global::iWriteLogEnabled & 1) { - if (!output.is_open()) - output.open("log.txt", std::ios::trunc); + if( !output.is_open() ) { + + std::string const filename = + ( Global::MultipleLogs ? + "logs/log (" + filename_scenery() + ") " + filename_date() + ".txt" : + "log.txt" ); + output.open( filename, std::ios::trunc ); + } output << str; if (newline) output << "\n"; @@ -72,9 +105,13 @@ void WriteLog(const char *str, bool newline) void ErrorLog(const char *str) { // Ra: bezwarunkowa rejestracja poważnych błędów - if (!errors.is_open()) - { - errors.open("errors.txt", std::ios::trunc); + if (!errors.is_open()) { + + std::string const filename = + ( Global::MultipleLogs ? + "logs/errors (" + filename_scenery() + ") " + filename_date() + ".txt" : + "errors.txt" ); + errors.open( filename, std::ios::trunc ); errors << "EU07.EXE " + Global::asRelease << "\n"; } if (str) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 6d7d2c40..448a65b9 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -416,37 +416,30 @@ struct TPowerParameters struct { _mover__3 RHeater; - }; struct { _mover__2 RPowerCable; - }; struct { TCurrentCollector CollectorParameters; - }; struct { _mover__1 RAccumulator; - }; struct { TEngineTypes GeneratorEngine; - }; struct { double InputVoltage; - }; struct { TPowerType PowerType; - }; }; @@ -670,10 +663,18 @@ public: /*nastawniki:*/ int MainCtrlPosNo = 0; /*ilosc pozycji nastawnika*/ int ScndCtrlPosNo = 0; - int LightsPosNo = 0; // NOTE: values higher than 0 seem to break the current code for light switches + int LightsPosNo = 0; int LightsDefPos = 1; bool LightsWrap = false; int Lights[2][17]; // pozycje świateł, przód - tył, 1 .. 16 + enum light { + + headlight_left = 0x01, + redmarker_left = 0x02, + headlight_upper = 0x04, + headlight_right = 0x10, + redmarker_right = 0x20, + }; bool ScndInMain = false; /*zaleznosc bocznika od nastawnika*/ bool MBrake = false; /*Czy jest hamulec reczny*/ double StopBrakeDecc = 0.0; @@ -1173,6 +1174,10 @@ extract_value( _Type &Variable, std::string const &Key, std::string const &Input } } +template <> +bool +extract_value( bool &Variable, std::string const &Key, std::string const &Input, std::string const &Default ); + inline std::string extract_value( std::string const &Key, std::string const &Input ) { diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 7a114a15..debab692 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -1814,8 +1814,9 @@ bool TMoverParameters::IncScndCtrl(int CtrlSpeed) LastRelayTime = 0; if ((OK) && (EngineType == ElectricInductionMotor)) + // NOTE: round() already adds 0.5, are the ones added here as well correct? if ((Vmax < 250)) - ScndCtrlActualPos = Round(Vel + 0.5f); + ScndCtrlActualPos = Round(Vel + 0.5); else ScndCtrlActualPos = Round(Vel * 1.0 / 2 + 0.5); @@ -2031,10 +2032,12 @@ void TMoverParameters::SecuritySystemCheck(double dt) (Battery)) // Ra: EZT ma teraz czuwak w rozrządczym { // CA - if (Vel >= - SecuritySystem - .AwareMinSpeed) // domyślnie predkość większa od 10% Vmax, albo podanej jawnie w FIZ - { + if( ( SecuritySystem.AwareMinSpeed > 0.0 ? + ( Vel >= SecuritySystem.AwareMinSpeed ) : + ( ActiveDir != 0 ) ) ) { + // domyślnie predkość większa od 10% Vmax, albo podanej jawnie w FIZ + // with defined minspeed of 0 the alerter will activate with reverser out of neutral position + // this emulates behaviour of engines like SM42 SecuritySystem.SystemTimer += dt; if (TestFlag(SecuritySystem.SystemType, 1) && TestFlag(SecuritySystem.Status, s_aware)) // jeśli świeci albo miga @@ -4087,106 +4090,152 @@ double TMoverParameters::TractionForce(double dt) if ((MainCtrlPos == 0) || (ShuntMode)) ScndCtrlPos = 0; - else if (AutoRelayFlag) - switch (RelayType) - { - case 0: - { - if ((Im <= (MPTRelay[ScndCtrlPos].Iup * PosRatio)) && - (ScndCtrlPos < ScndCtrlPosNo)) - ++ScndCtrlPos; - if ((Im >= (MPTRelay[ScndCtrlPos].Idown * PosRatio)) && (ScndCtrlPos > 0)) - --ScndCtrlPos; - break; - } - case 1: - { - if ((MPTRelay[ScndCtrlPos].Iup < Vel) && (ScndCtrlPos < ScndCtrlPosNo)) - ++ScndCtrlPos; - if ((MPTRelay[ScndCtrlPos].Idown > Vel) && (ScndCtrlPos > 0)) - --ScndCtrlPos; - break; - } - case 2: - { - if ((MPTRelay[ScndCtrlPos].Iup < Vel) && (ScndCtrlPos < ScndCtrlPosNo) && - (EnginePower < (tmp * 0.99))) - ++ScndCtrlPos; - if ((MPTRelay[ScndCtrlPos].Idown < Im) && (ScndCtrlPos > 0)) - --ScndCtrlPos; - break; - } - case 41: - { - if ((MainCtrlPos == MainCtrlPosNo) && - (tmpV * 3.6 > MPTRelay[ScndCtrlPos].Iup) && (ScndCtrlPos < ScndCtrlPosNo)) - { - ++ScndCtrlPos; - enrot = enrot * 0.73; - } - if ((Im > MPTRelay[ScndCtrlPos].Idown) && (ScndCtrlPos > 0)) - --ScndCtrlPos; - break; - } - case 45: - { - if ((MainCtrlPos > 11) && (ScndCtrlPos < ScndCtrlPosNo)) - if ((ScndCtrlPos == 0)) - if ((MPTRelay[ScndCtrlPos].Iup > Im)) - ++ScndCtrlPos; - else if ((MPTRelay[ScndCtrlPos].Iup < Vel)) - ++ScndCtrlPos; + else { + if( AutoRelayFlag ) { - // malenie - if ((ScndCtrlPos > 0) && (MainCtrlPos < 12)) - if ((ScndCtrlPos == ScndCtrlPosNo)) - if ((MPTRelay[ScndCtrlPos].Idown < Im)) - --ScndCtrlPos; - else if ((MPTRelay[ScndCtrlPos].Idown > Vel)) - --ScndCtrlPos; - if ((MainCtrlPos < 11) && (ScndCtrlPos > 2)) - ScndCtrlPos = 2; - if ((MainCtrlPos < 9) && (ScndCtrlPos > 0)) - ScndCtrlPos = 0; - } - case 46: - { - // wzrastanie - if ((MainCtrlPos > 9) && (ScndCtrlPos < ScndCtrlPosNo)) - if ((ScndCtrlPos) % 2 == 0) - if ((MPTRelay[ScndCtrlPos].Iup > Im)) - ++ScndCtrlPos; - else if ((MPTRelay[ScndCtrlPos - 1].Iup > Im) && - (MPTRelay[ScndCtrlPos].Iup < Vel)) - ++ScndCtrlPos; + switch( RelayType ) { - // malenie - if ((MainCtrlPos < 10) && (ScndCtrlPos > 0)) - if ((ScndCtrlPos) % 2 == 0) - if ((MPTRelay[ScndCtrlPos].Idown < Im)) + case 0: { + + if( ( Im <= ( MPTRelay[ ScndCtrlPos ].Iup * PosRatio ) ) && + ( ScndCtrlPos < ScndCtrlPosNo ) ) + ++ScndCtrlPos; + if( ( Im >= ( MPTRelay[ ScndCtrlPos ].Idown * PosRatio ) ) && ( ScndCtrlPos > 0 ) ) --ScndCtrlPos; - else if ((MPTRelay[ScndCtrlPos + 1].Idown < Im) && - (MPTRelay[ScndCtrlPos].Idown > Vel)) + break; + } + case 1: { + + if( ( MPTRelay[ ScndCtrlPos ].Iup < Vel ) && ( ScndCtrlPos < ScndCtrlPosNo ) ) + ++ScndCtrlPos; + if( ( MPTRelay[ ScndCtrlPos ].Idown > Vel ) && ( ScndCtrlPos > 0 ) ) --ScndCtrlPos; - if ((MainCtrlPos < 9) && (ScndCtrlPos > 2)) - ScndCtrlPos = 2; - if ((MainCtrlPos < 6) && (ScndCtrlPos > 0)) - ScndCtrlPos = 0; + break; + } + case 2: { + + if( ( MPTRelay[ ScndCtrlPos ].Iup < Vel ) && ( ScndCtrlPos < ScndCtrlPosNo ) && + ( EnginePower < ( tmp * 0.99 ) ) ) + ++ScndCtrlPos; + if( ( MPTRelay[ ScndCtrlPos ].Idown < Im ) && ( ScndCtrlPos > 0 ) ) + --ScndCtrlPos; + break; + } + case 41: + { + if( ( MainCtrlPos == MainCtrlPosNo ) + && ( tmpV * 3.6 > MPTRelay[ ScndCtrlPos ].Iup ) + && ( ScndCtrlPos < ScndCtrlPosNo ) ) { + ++ScndCtrlPos; + enrot = enrot * 0.73; + } + if( ( Im > MPTRelay[ ScndCtrlPos ].Idown ) + && ( ScndCtrlPos > 0 ) ) { + --ScndCtrlPos; + } + break; + } + case 45: + { + if( ( MainCtrlPos >= 10 ) && ( ScndCtrlPos < ScndCtrlPosNo ) ) { + if( ScndCtrlPos == 0 ) { + 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; + } + } + } + // malenie + if( ( ScndCtrlPos > 0 ) && ( MainCtrlPos < 10 ) ) { + if( ScndCtrlPos == 1 ) { + if( Im > MPTRelay[ ScndCtrlPos - 1 ].Idown ) { + --ScndCtrlPos; + } + } + else { + if( Vel < MPTRelay[ ScndCtrlPos ].Idown ) { + --ScndCtrlPos; + } + } + } + // 3rd level drops with master controller at position lower than 10... + if( MainCtrlPos < 10 ) { + ScndCtrlPos = std::min( 2, ScndCtrlPos ); + } + // ...and below position 7 field shunt drops altogether + if( MainCtrlPos < 7 ) { + ScndCtrlPos = 0; + } + break; + } + case 46: + { + // wzrastanie + if( ( MainCtrlPos >= 10 ) + && ( ScndCtrlPos < ScndCtrlPosNo ) ) { + if( ( ScndCtrlPos ) % 2 == 0 ) { + if( ( MPTRelay[ ScndCtrlPos ].Iup > Im ) ) { + ++ScndCtrlPos; + } + } + else { + if( ( MPTRelay[ ScndCtrlPos - 1 ].Iup > Im ) + && ( MPTRelay[ ScndCtrlPos ].Iup < Vel ) ) { + ++ScndCtrlPos; + } + } + } + // malenie + if( ( MainCtrlPos < 10 ) + && ( ScndCtrlPos > 0 ) ) { + if( ( ScndCtrlPos ) % 2 == 0 ) { + if( ( MPTRelay[ ScndCtrlPos ].Idown < Im ) ) { + --ScndCtrlPos; + } + } + else { + if( ( MPTRelay[ ScndCtrlPos + 1 ].Idown < Im ) + && ( MPTRelay[ ScndCtrlPos ].Idown > Vel ) ) { + --ScndCtrlPos; + } + } + } + if( MainCtrlPos < 10 ) { + ScndCtrlPos = std::min( 2, ScndCtrlPos ); + } + if( MainCtrlPos < 7 ) { + ScndCtrlPos = 0; + } + break; + } + default: { + break; + } + } // switch RelayType } - } // switch RelayType + } break; } // DieselElectric case ElectricInductionMotor: { - if ((Mains)) // nie wchodzić w funkcję bez potrzeby - if ((abs(Voltage) < EnginePowerSource.CollectorParameters.MinV) || - (abs(Voltage) > EnginePowerSource.CollectorParameters.MaxV + 200)) - { - MainSwitch(false); + if( ( Mains ) ) { + // nie wchodzić w funkcję bez potrzeby + if( ( abs( Voltage ) < EnginePowerSource.CollectorParameters.MinV ) + || ( abs( Voltage ) > EnginePowerSource.CollectorParameters.MaxV + 200 ) ) { + MainSwitch( false ); } - tmpV = abs(nrot) * (PI * WheelDiameter) * - 3.6; //*DirAbsolute*eimc[eimc_s_p]; - do przemyslenia dzialanie pp + } + tmpV = abs(nrot) * (PI * WheelDiameter) * 3.6; //*DirAbsolute*eimc[eimc_s_p]; - do przemyslenia dzialanie pp if ((Mains)) { @@ -7915,3 +7964,22 @@ double TMoverParameters::ShowCurrentP(int AmpN) return current; } } + +template <> +bool +extract_value( bool &Variable, std::string const &Key, std::string const &Input, std::string const &Default ) { + + auto value = extract_value( Key, Input ); + if( false == value.empty() ) { + // set the specified variable to retrieved value + Variable = ( ToLower( value ) == "yes" ); + return true; // located the variable + } + else { + // set the variable to provided default value + if( false == Default.empty() ) { + Variable = ( ToLower( Default ) == "yes" ); + } + return false; // supplied the default + } +} diff --git a/McZapkie/mctools.cpp b/McZapkie/mctools.cpp index f91f7b9d..37c8b148 100644 --- a/McZapkie/mctools.cpp +++ b/McZapkie/mctools.cpp @@ -72,23 +72,11 @@ double Min0R(double x1, double x2) // TODO: replace with something sensible std::string Now() { - std::time_t timenow = std::time( nullptr ); - std::tm tm = *std::localtime( &timenow ); - std::stringstream converter; - converter << std::put_time( &tm, "%c" ); + std::time_t timenow = std::time( nullptr ); + std::tm tm = *std::localtime( &timenow ); + std::stringstream converter; + converter << std::put_time( &tm, "%c" ); return converter.str(); - -/* char buffer[ 256 ]; - sprintf( buffer, - "%d-%02d-%02d %02d:%02d:%02d.%03d", - st.wYear, - st.wMonth, - st.wDay, - st.wHour, - st.wMinute, - st.wSecond, - st.wMilliseconds ); -*/ } bool TestFlag(int Flag, int Value) diff --git a/McZapkie/mctools.h b/McZapkie/mctools.h index 817f34ec..a0ecf5af 100644 --- a/McZapkie/mctools.h +++ b/McZapkie/mctools.h @@ -62,7 +62,7 @@ inline double Sign(double x) return x >= 0 ? 1.0 : -1.0; } -inline long Round(float f) +inline long Round(double const f) { return (long)(f + 0.5); //return lround(f); diff --git a/Train.cpp b/Train.cpp index ec477ff0..d17783b0 100644 --- a/Train.cpp +++ b/Train.cpp @@ -131,6 +131,54 @@ void TCab::Update() } }; +// 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 +TTrain::commandhandler_map const TTrain::m_commandhandlers = { + + { user_command::mastercontrollerincrease, &TTrain::OnCommand_mastercontrollerincrease }, + { user_command::mastercontrollerincreasefast, &TTrain::OnCommand_mastercontrollerincreasefast }, + { user_command::mastercontrollerdecrease, &TTrain::OnCommand_mastercontrollerdecrease }, + { user_command::mastercontrollerdecreasefast, &TTrain::OnCommand_mastercontrollerdecreasefast }, + { user_command::secondcontrollerincrease, &TTrain::OnCommand_secondcontrollerincrease }, + { user_command::secondcontrollerincreasefast, &TTrain::OnCommand_secondcontrollerincreasefast }, + { user_command::secondcontrollerdecrease, &TTrain::OnCommand_secondcontrollerdecrease }, + { user_command::secondcontrollerdecreasefast, &TTrain::OnCommand_secondcontrollerdecreasefast }, + { user_command::independentbrakeincrease, &TTrain::OnCommand_independentbrakeincrease }, + { user_command::independentbrakeincreasefast, &TTrain::OnCommand_independentbrakeincreasefast }, + { user_command::independentbrakedecrease, &TTrain::OnCommand_independentbrakedecrease }, + { user_command::independentbrakedecreasefast, &TTrain::OnCommand_independentbrakedecreasefast }, + { user_command::independentbrakebailoff, &TTrain::OnCommand_independentbrakebailoff }, + { user_command::trainbrakeincrease, &TTrain::OnCommand_trainbrakeincrease }, + { user_command::trainbrakedecrease, &TTrain::OnCommand_trainbrakedecrease }, + { user_command::trainbrakecharging, &TTrain::OnCommand_trainbrakecharging }, + { user_command::trainbrakerelease, &TTrain::OnCommand_trainbrakerelease }, + { user_command::trainbrakefirstservice, &TTrain::OnCommand_trainbrakefirstservice }, + { user_command::trainbrakeservice, &TTrain::OnCommand_trainbrakeservice }, + { user_command::trainbrakefullservice, &TTrain::OnCommand_trainbrakefullservice }, + { user_command::trainbrakeemergency, &TTrain::OnCommand_trainbrakeemergency }, + { user_command::reverserincrease, &TTrain::OnCommand_reverserincrease }, + { user_command::reverserdecrease, &TTrain::OnCommand_reverserdecrease }, + { user_command::alerteracknowledge, &TTrain::OnCommand_alerteracknowledge }, + { user_command::batterytoggle, &TTrain::OnCommand_batterytoggle }, + { user_command::pantographtogglefront, &TTrain::OnCommand_pantographtogglefront }, + { user_command::pantographtogglerear, &TTrain::OnCommand_pantographtogglerear }, + { user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle }, + { user_command::convertertoggle, &TTrain::OnCommand_convertertoggle }, + { user_command::compressortoggle, &TTrain::OnCommand_compressortoggle }, + { user_command::headlighttoggleleft, &TTrain::OnCommand_headlighttoggleleft }, + { user_command::headlighttoggleright, &TTrain::OnCommand_headlighttoggleright }, + { user_command::headlighttoggleupper, &TTrain::OnCommand_headlighttoggleupper }, + { user_command::redmarkertoggleleft, &TTrain::OnCommand_redmarkertoggleleft }, + { user_command::redmarkertoggleright, &TTrain::OnCommand_redmarkertoggleright }, + { user_command::headlighttogglerearleft, &TTrain::OnCommand_headlighttogglerearleft }, + { user_command::headlighttogglerearright, &TTrain::OnCommand_headlighttogglerearright }, + { user_command::headlighttogglerearupper, &TTrain::OnCommand_headlighttogglerearupper }, + { user_command::redmarkertogglerearleft, &TTrain::OnCommand_redmarkertogglerearleft }, + { user_command::redmarkertogglerearright, &TTrain::OnCommand_redmarkertogglerearright }, + { user_command::doortoggleleft, &TTrain::OnCommand_doortoggleleft }, + { user_command::doortoggleright, &TTrain::OnCommand_doortoggleright } +}; + TTrain::TTrain() { ActiveUniversal4 = false; @@ -391,898 +439,1389 @@ PyObject *TTrain::GetTrainState() { return dict; } -void -TTrain::OnCommand( command_data const &Command ) { +bool TTrain::is_eztoer() const { - bool const isEztOer = + return ( ( mvControlled->TrainType == dt_EZT ) && ( mvOccupied->BrakeSubsystem == ss_ESt ) && ( mvControlled->Battery == true ) && ( mvControlled->EpFuse == true ) && ( mvControlled->ActiveDir != 0 ) ); // od yB +} - switch( Command.command ) { +// command handlers +void TTrain::OnCommand_mastercontrollerincrease( TTrain *Train, command_data const &Command ) { - case user_command::mastercontrollerincrease: { + if( Command.action != GLFW_RELEASE ) { + // on press or hold + if( Train->mvControlled->IncMainCtrl( 1 ) ) { + // sound feedback + Train->play_sound( Train->dsbNastawnikJazdy ); + } + } +} - if( Command.action != GLFW_RELEASE ) { +void TTrain::OnCommand_mastercontrollerincreasefast( TTrain *Train, command_data const &Command ) { - if( mvControlled->IncMainCtrl( 1 ) ) { - // sound feedback - play_sound( dsbNastawnikJazdy ); + if( Command.action != GLFW_RELEASE ) { + // on press or hold + if( Train->mvControlled->IncMainCtrl( 2 ) ) { + // sound feedback + Train->play_sound( Train->dsbNastawnikJazdy ); + } + } +} + +void TTrain::OnCommand_mastercontrollerdecrease( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + // on press or hold + if( Train->mvControlled->DecMainCtrl( 1 ) ) { + // sound feedback + Train->play_sound( Train->dsbNastawnikJazdy ); + } + } +} + +void TTrain::OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + // on press or hold + if( Train->mvControlled->DecMainCtrl( 2 ) ) { + // sound feedback + Train->play_sound( Train->dsbNastawnikJazdy ); + } + } +} + +void TTrain::OnCommand_secondcontrollerincrease( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + // on press or hold + if( Train->mvControlled->ShuntMode ) { + Train->mvControlled->AnPos += ( Command.time_delta * 0.75f ); + if( Train->mvControlled->AnPos > 1 ) + Train->mvControlled->AnPos = 1; + } + else if( Train->mvControlled->IncScndCtrl( 1 ) ) { + // sound feedback + Train->play_sound( Train->dsbNastawnikBocz, Train->dsbNastawnikJazdy, DSBVOLUME_MAX, 0 ); + } + } +} + +void TTrain::OnCommand_secondcontrollerincreasefast( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + // on press or hold + if( Train->mvControlled->IncScndCtrl( 2 ) ) { + // sound feedback + Train->play_sound( Train->dsbNastawnikBocz, Train->dsbNastawnikJazdy, DSBVOLUME_MAX, 0 ); + } + } +} + +void TTrain::OnCommand_secondcontrollerdecrease( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + // on press or hold + if( Train->mvControlled->ShuntMode ) { + Train->mvControlled->AnPos -= ( Command.time_delta * 0.75f ); + if( Train->mvControlled->AnPos > 1 ) + Train->mvControlled->AnPos = 1; + } + else if( Train->mvControlled->DecScndCtrl( 1 ) ) { + // sound feedback + Train->play_sound( Train->dsbNastawnikBocz, Train->dsbNastawnikJazdy, DSBVOLUME_MAX, 0 ); + } + } +} + +void TTrain::OnCommand_secondcontrollerdecreasefast( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + // on press or hold + if( Train->mvControlled->DecScndCtrl( 2 ) ) { + // sound feedback + Train->play_sound( Train->dsbNastawnikBocz, Train->dsbNastawnikJazdy, DSBVOLUME_MAX, 0 ); + } + } +} + +void TTrain::OnCommand_independentbrakeincrease( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + + if( Train->mvOccupied->LocalBrake != ManualBrake ) { + Train->mvOccupied->IncLocalBrakeLevel( 1 ); + } + } +} + +void TTrain::OnCommand_independentbrakeincreasefast( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + + if( Train->mvOccupied->LocalBrake != ManualBrake ) { + Train->mvOccupied->IncLocalBrakeLevel( 2 ); + } + } +} + +void TTrain::OnCommand_independentbrakedecrease( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + + if( ( Train->mvOccupied->LocalBrake != ManualBrake ) + // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku - odhamować jakoś trzeba + // TODO: sort AI out so it doesn't do things it doesn't have equipment for + || ( Train->mvOccupied->LocalBrakePos != 0 ) ) { + Train->mvOccupied->DecLocalBrakeLevel( 1 ); + } + } +} + +void TTrain::OnCommand_independentbrakedecreasefast( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + + if( ( Train->mvOccupied->LocalBrake != ManualBrake ) + // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku - odhamować jakoś trzeba + // TODO: sort AI out so it doesn't do things it doesn't have equipment for + || ( Train->mvOccupied->LocalBrakePos != 0 ) ) { + Train->mvOccupied->DecLocalBrakeLevel( 2 ); + } + } +} + +void TTrain::OnCommand_independentbrakebailoff( TTrain *Train, command_data const &Command ) { + // TODO: check if this set of conditions can be simplified. + // it'd be more flexible to have an attribute indicating whether bail off position is supported + if( ( Train->mvControlled->TrainType != dt_EZT ) + && ( ( Train->mvControlled->EngineType == ElectricSeriesMotor ) + || ( Train->mvControlled->EngineType == DieselElectric ) + || ( Train->mvControlled->EngineType == ElectricInductionMotor ) ) + && ( Train->mvOccupied->BrakeCtrlPosNo > 0 ) ) { + + if( Command.action != GLFW_RELEASE ) { + // press or hold + Train->ggReleaserButton.UpdateValue( 1 ); + Train->mvOccupied->BrakeReleaser( 1 ); + } + else { + // release + Train->ggReleaserButton.UpdateValue( 0 ); + Train->mvOccupied->BrakeReleaser( 0 ); + } + } +} + +void TTrain::OnCommand_trainbrakeincrease( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + + if( Train->mvOccupied->BrakeHandle == FV4a ) { + Train->mvOccupied->BrakeLevelAdd( 0.1 /*15.0 * Command.time_delta*/ ); + } + else { + if( Train->mvOccupied->BrakeLevelAdd( Global::fBrakeStep ) ) { + // nieodpowiedni warunek; true, jeśli można dalej kręcić + Train->keybrakecount = 0; + if( ( Train->is_eztoer() ) && ( Train->mvOccupied->BrakeCtrlPos < 3 ) ) { + // Ra: uzależnić dźwięk od zmiany stanu EP, nie od klawisza + Train->play_sound( Train->dsbPneumaticSwitch ); } } - break; + } + } +} + +void TTrain::OnCommand_trainbrakedecrease( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + + if( Train->mvOccupied->BrakeHandle == FV4a ) { + Train->mvOccupied->BrakeLevelAdd( -0.1 /*-15.0 * Command.time_delta*/ ); + } + else { + // nową wersję dostarczył ZiomalCl ("fixed looped sound in ezt when using NUM_9 key") + if( ( Train->mvOccupied->BrakeCtrlPos > -1 ) + || ( Train->keybrakecount > 1 ) ) { + + if( ( Train->is_eztoer() ) + && ( Train->mvControlled->Mains ) + && ( Train->mvOccupied->BrakeCtrlPos != -1 ) ) { + // Ra: uzależnić dźwięk od zmiany stanu EP, nie od klawisza + Train->play_sound( Train->dsbPneumaticSwitch ); + } + Train->mvOccupied->BrakeLevelAdd( -Global::fBrakeStep ); + } + else + Train->keybrakecount += 1; + // koniec wersji dostarczonej przez ZiomalCl + } + } +} + +void TTrain::OnCommand_trainbrakecharging( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_RELEASE ) { + + // sound feedback + if( ( Train->is_eztoer() ) + && ( Train->mvControlled->Mains ) + && ( Train->mvOccupied->BrakeCtrlPos != -1 ) ) { + Train->play_sound( Train->dsbPneumaticSwitch ); } - case user_command::mastercontrollerincreasefast: { + Train->mvOccupied->BrakeLevelSet( -1 ); + } +} - if( Command.action != GLFW_RELEASE ) { +void TTrain::OnCommand_trainbrakerelease( TTrain *Train, command_data const &Command ) { - if( mvControlled->IncMainCtrl( 2 ) ) { - // sound feedback - play_sound( dsbNastawnikJazdy ); - } - } - break; + if( Command.action != GLFW_RELEASE ) { + + // sound feedback + if( ( Train->is_eztoer() ) + && ( ( Train->mvOccupied->BrakeCtrlPos == 1 ) + || ( Train->mvOccupied->BrakeCtrlPos == -1 ) ) ) { + Train->play_sound( Train->dsbPneumaticSwitch ); } - case user_command::mastercontrollerdecrease: { + Train->mvOccupied->BrakeLevelSet( 0 ); + } +} - if( Command.action != GLFW_RELEASE ) { +void TTrain::OnCommand_trainbrakefirstservice( TTrain *Train, command_data const &Command ) { - if( mvControlled->DecMainCtrl( 1 ) ) { - // sound feedback - play_sound( dsbNastawnikJazdy ); - } - } - break; + if( Command.action != GLFW_RELEASE ) { + + // sound feedback + if( ( Train->is_eztoer() ) + && ( Train->mvControlled->Mains ) + && ( Train->mvOccupied->BrakeCtrlPos != 1 ) ) { + Train->play_sound( Train->dsbPneumaticSwitch ); } - case user_command::mastercontrollerdecreasefast: { + Train->mvOccupied->BrakeLevelSet( 1 ); + } +} - if( Command.action != GLFW_RELEASE ) { +void TTrain::OnCommand_trainbrakeservice( TTrain *Train, command_data const &Command ) { - if( mvControlled->DecMainCtrl( 2 ) ) { - // sound feedback - play_sound( dsbNastawnikJazdy ); - } - } - break; + if( Command.action != GLFW_RELEASE ) { + + // sound feedback + if( ( Train->is_eztoer() ) + && ( Train->mvControlled->Mains ) + && ( ( Train->mvOccupied->BrakeCtrlPos == 1 ) + || ( Train->mvOccupied->BrakeCtrlPos == -1 ) ) ) { + Train->play_sound( Train->dsbPneumaticSwitch ); } - case user_command::secondcontrollerincrease: { + Train->mvOccupied->BrakeLevelSet( + Train->mvOccupied->BrakeCtrlPosNo / 2 + + ( Train->mvOccupied->BrakeHandle == FV4a ? + 1 : + 0 ) ); + } +} - if( Command.action != GLFW_RELEASE ) { +void TTrain::OnCommand_trainbrakefullservice( TTrain *Train, command_data const &Command ) { - if( mvControlled->ShuntMode ) { - mvControlled->AnPos += ( Command.time_delta * 0.75f ); - if( mvControlled->AnPos > 1 ) - mvControlled->AnPos = 1; - } - else if( mvControlled->IncScndCtrl( 1 ) ) { - // sound feedback - play_sound( dsbNastawnikBocz, dsbNastawnikJazdy ); - } - } - break; + if( Command.action != GLFW_RELEASE ) { + + // sound feedback + if( ( Train->is_eztoer() ) + && ( Train->mvControlled->Mains ) + && ( ( Train->mvOccupied->BrakeCtrlPos == 1 ) + || ( Train->mvOccupied->BrakeCtrlPos == -1 ) ) ) { + Train->play_sound( Train->dsbPneumaticSwitch ); } + Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->BrakeCtrlPosNo - 1 ); + } +} - case user_command::secondcontrollerincreasefast: { +void TTrain::OnCommand_trainbrakeemergency( TTrain *Train, command_data const &Command ) { - if( Command.action != GLFW_RELEASE ) { + if( Command.action != GLFW_RELEASE ) { - if( mvControlled->IncScndCtrl( 2 ) ) { - // sound feedback - play_sound( dsbNastawnikBocz, dsbNastawnikJazdy ); - } - } - break; + Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->Handle->GetPos( bh_EB ) ); + if( Train->mvOccupied->BrakeCtrlPosNo <= 0.1 ) { + // hamulec bezpieczeństwa dla wagonów + Train->mvOccupied->EmergencyBrakeFlag = true; } + } +} - case user_command::secondcontrollerdecrease: { +void TTrain::OnCommand_reverserincrease( TTrain *Train, command_data const &Command ) { - if( Command.action != GLFW_RELEASE ) { + if( Command.action != GLFW_RELEASE ) { - if( mvControlled->ShuntMode ) { - mvControlled->AnPos -= ( Command.time_delta * 0.75f ); - if( mvControlled->AnPos > 1 ) - mvControlled->AnPos = 1; - } - else if( mvControlled->DecScndCtrl( 1 ) ) { - // sound feedback - play_sound( dsbNastawnikBocz, dsbNastawnikJazdy ); - } + if( Train->mvOccupied->DirectionForward() ) { + // sound feedback + Train->play_sound( Train->dsbReverserKey, Train->dsbSwitch, DSBVOLUME_MAX, 0 ); + // aktualizacja skrajnych pojazdów w składzie + if( ( Train->mvOccupied->ActiveDir ) + && ( Train->DynamicObject->Mechanik ) ) { + + Train->DynamicObject->Mechanik->CheckVehicles( Change_direction ); } - break; } + } +} - case user_command::secondcontrollerdecreasefast: { +void TTrain::OnCommand_reverserdecrease( TTrain *Train, command_data const &Command ) { - if( Command.action != GLFW_RELEASE ) { + if( Command.action != GLFW_RELEASE ) { - if( mvControlled->DecScndCtrl( 2 ) ) { - // sound feedback - play_sound( dsbNastawnikBocz, dsbNastawnikJazdy ); - } + if( Train->mvOccupied->DirectionBackward() ) { + // sound feedback + Train->play_sound( Train->dsbReverserKey, Train->dsbSwitch, DSBVOLUME_MAX, 0 ); + // aktualizacja skrajnych pojazdów w składzie + if( ( Train->mvOccupied->ActiveDir ) + && ( Train->DynamicObject->Mechanik ) ) { + + Train->DynamicObject->Mechanik->CheckVehicles( Change_direction ); } - break; } + } +} - case user_command::independentbrakeincrease: { +void TTrain::OnCommand_alerteracknowledge( TTrain *Train, command_data const &Command ) { - if( Command.action != GLFW_RELEASE ) { - - if( mvOccupied->LocalBrake != ManualBrake ) { - mvOccupied->IncLocalBrakeLevel( 1 ); - } - } - break; + if( Command.action != GLFW_RELEASE ) { + // press or hold + Train->fCzuwakTestTimer += 0.035f; + if( Train->CAflag == false ) { + Train->CAflag = true; + Train->mvOccupied->SecuritySystemReset(); } - - case user_command::independentbrakeincreasefast: { - - if( Command.action != GLFW_RELEASE ) { - - if( mvOccupied->LocalBrake != ManualBrake ) { - mvOccupied->IncLocalBrakeLevel( 2 ); - } + else { + if( Train->fCzuwakTestTimer > 1.0 ) { + SetFlag( Train->mvOccupied->SecuritySystem.Status, s_CAtest ); } - break; } - - case user_command::independentbrakedecrease: { - - if( Command.action != GLFW_RELEASE ) { - - if( ( mvOccupied->LocalBrake != ManualBrake ) - // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku - odhamować jakoś trzeba - // TODO: sort AI out so it doesn't do things it doesn't have equipment for - || ( mvOccupied->LocalBrakePos != 0 ) ) { - mvOccupied->DecLocalBrakeLevel( 1 ); - } - } - break; + // visual feedback + Train->ggSecurityResetButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggSecurityResetButton.GetValue() < 0.05 ) { + Train->play_sound( Train->dsbSwitch ); } - - case user_command::independentbrakedecreasefast: { - - if( Command.action != GLFW_RELEASE ) { - - if( ( mvOccupied->LocalBrake != ManualBrake ) - // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku - odhamować jakoś trzeba - // TODO: sort AI out so it doesn't do things it doesn't have equipment for - || ( mvOccupied->LocalBrakePos != 0 ) ) { - mvOccupied->DecLocalBrakeLevel( 2 ); - } - } - break; + } + else { + // release + Train->fCzuwakTestTimer = 0.0f; + if( TestFlag( Train->mvOccupied->SecuritySystem.Status, s_CAtest ) ) { + SetFlag( Train->mvOccupied->SecuritySystem.Status, -s_CAtest ); + Train->mvOccupied->s_CAtestebrake = false; + Train->mvOccupied->SecuritySystem.SystemBrakeCATestTimer = 0.0; } + Train->CAflag = false; + // visual feedback + Train->ggSecurityResetButton.UpdateValue( 0.0 ); + } +} - case user_command::independentbrakebailoff: { - // TODO: check if this set of conditions can be simplified. - // it'd be more flexible to have an attribute indicating whether bail off position is supported - if( ( mvControlled->TrainType != dt_EZT ) - && ( ( mvControlled->EngineType == ElectricSeriesMotor ) - || ( mvControlled->EngineType == DieselElectric ) - || ( mvControlled->EngineType == ElectricInductionMotor ) ) - && ( mvOccupied->BrakeCtrlPosNo > 0 ) ) { +void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command ) { - if( Command.action != GLFW_RELEASE ) { - // press or hold - ggReleaserButton.UpdateValue( 1 ); - mvOccupied->BrakeReleaser( 1 ); + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == Train->mvOccupied->Battery ) { + // turn on + // wyłącznik jest też w SN61, ewentualnie załączać prąd na stałe z poziomu FIZ + if( Train->mvOccupied->BatterySwitch( true ) ) { + // bateria potrzebna np. do zapalenia świateł + if( Train->ggBatteryButton.SubModel ) { + Train->ggBatteryButton.UpdateValue( 1 ); } - else { - // release - ggReleaserButton.UpdateValue( 0 ); - mvOccupied->BrakeReleaser( 0 ); + // audio feedback + Train->play_sound( Train->dsbSwitch ); + // side-effects + if( Train->mvOccupied->LightsPosNo > 0 ) { + Train->SetLights(); + } + if( TestFlag( Train->mvOccupied->SecuritySystem.SystemType, 2 ) ) { + // Ra: znowu w kabinie jest coś, co być nie powinno! + SetFlag( Train->mvOccupied->SecuritySystem.Status, s_active ); + SetFlag( Train->mvOccupied->SecuritySystem.Status, s_SHPalarm ); } } - break; } - - case user_command::trainbrakeincrease: { - - if( Command.action != GLFW_RELEASE ) { - - if( mvOccupied->BrakeHandle == FV4a ) { - mvOccupied->BrakeLevelAdd( 0.1 /*15.0 * Command.time_delta*/ ); - } - else { - if( mvOccupied->BrakeLevelAdd( Global::fBrakeStep ) ) { - // nieodpowiedni warunek; true, jeśli można dalej kręcić - keybrakecount = 0; - if( ( isEztOer ) && ( mvOccupied->BrakeCtrlPos < 3 ) ) { - // Ra: uzależnić dźwięk od zmiany stanu EP, nie od klawisza - play_sound( dsbPneumaticSwitch ); - } - } + else { + //turn off + if( Train->mvOccupied->BatterySwitch( false ) ) { + // ewentualnie zablokować z FIZ, np. w samochodach się nie odłącza akumulatora + if( Train->ggBatteryButton.SubModel ) { + Train->ggBatteryButton.UpdateValue( 0 ); } + // audio feedback + Train->play_sound( Train->dsbSwitch ); + // side-effects + Train->mvControlled->PantFront( false ); + Train->mvControlled->PantRear( false ); } - break; } + } +} - case user_command::trainbrakedecrease: { +void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const &Command ) { - if( Command.action != GLFW_RELEASE ) { - - if( mvOccupied->BrakeHandle == FV4a ) { - mvOccupied->BrakeLevelAdd( -0.1 /*-15.0 * Command.time_delta*/ ); - } - else { - // nową wersję dostarczył ZiomalCl ("fixed looped sound in ezt when using NUM_9 key") - if( ( mvOccupied->BrakeCtrlPos > -1 ) - || ( keybrakecount > 1 ) ) { - - if( ( isEztOer ) - && ( mvControlled->Mains ) - && ( mvOccupied->BrakeCtrlPos != -1 ) ) { - // Ra: uzależnić dźwięk od zmiany stanu EP, nie od klawisza - play_sound( dsbPneumaticSwitch ); - } - mvOccupied->BrakeLevelAdd( -Global::fBrakeStep ); - } - else - keybrakecount += 1; - // koniec wersji dostarczonej przez ZiomalCl - } - } - break; - } - - case user_command::trainbrakecharging: { - - if( Command.action != GLFW_RELEASE ) { - - // sound feedback - if( ( isEztOer ) - && ( mvControlled->Mains ) - && ( mvOccupied->BrakeCtrlPos != -1 ) ) { - dsbPneumaticSwitch->Play( 0, 0, 0 ); - } - mvOccupied->BrakeLevelSet( -1 ); - } - break; - } - - case user_command::trainbrakerelease: { - - if( Command.action != GLFW_RELEASE ) { - - // sound feedback - if( ( isEztOer ) - && ( ( mvOccupied->BrakeCtrlPos == 1 ) - || ( mvOccupied->BrakeCtrlPos == -1 ) ) ) { - dsbPneumaticSwitch->Play( 0, 0, 0 ); - } - mvOccupied->BrakeLevelSet( 0 ); - } - break; - } - - case user_command::trainbrakefirstservice: { - - if( Command.action != GLFW_RELEASE ) { - - // sound feedback - if( ( isEztOer ) - && ( mvControlled->Mains ) - && ( mvOccupied->BrakeCtrlPos != 1 ) ) { - dsbPneumaticSwitch->Play( 0, 0, 0 ); - } - mvOccupied->BrakeLevelSet( 1 ); - } - break; - } - - case user_command::trainbrakeservice: { - - if( Command.action != GLFW_RELEASE ) { - - // sound feedback - if( ( isEztOer ) - && ( mvControlled->Mains ) - && ( ( mvOccupied->BrakeCtrlPos == 1 ) - || ( mvOccupied->BrakeCtrlPos == -1 ) ) ) { - dsbPneumaticSwitch->Play( 0, 0, 0 ); - } - mvOccupied->BrakeLevelSet( - mvOccupied->BrakeCtrlPosNo / 2 - + ( mvOccupied->BrakeHandle == FV4a ? - 1 : - 0 ) ); - } - break; - } - - case user_command::trainbrakefullservice: { - - if( Command.action != GLFW_RELEASE ) { - - // sound feedback - if( ( isEztOer ) - && ( mvControlled->Mains ) - && ( ( mvOccupied->BrakeCtrlPos == 1 ) - || ( mvOccupied->BrakeCtrlPos == -1 ) ) ) { - dsbPneumaticSwitch->Play( 0, 0, 0 ); - } - mvOccupied->BrakeLevelSet( mvOccupied->BrakeCtrlPosNo - 1 ); - } - break; - } - - case user_command::trainbrakeemergency: { - - if( Command.action != GLFW_RELEASE ) { - - mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_EB ) ); - if( mvOccupied->BrakeCtrlPosNo <= 0.1 ) { - // hamulec bezpieczeństwa dla wagonów - mvOccupied->EmergencyBrakeFlag = true; - } - } - break; - } - - case user_command::reverserincrease: { - - if( Command.action != GLFW_RELEASE ) { - - if( mvOccupied->DirectionForward() ) { - // sound feedback - play_sound( dsbReverserKey, dsbSwitch ); - // aktualizacja skrajnych pojazdów w składzie - if( ( mvOccupied->ActiveDir ) - && ( DynamicObject->Mechanik ) ) { - - DynamicObject->Mechanik->CheckVehicles( Change_direction ); - } - } - } - break; - } - - case user_command::reverserdecrease: { - - if( Command.action != GLFW_RELEASE ) { - - if( mvOccupied->DirectionBackward() ) { - // sound feedback - play_sound( dsbReverserKey, dsbSwitch ); - // aktualizacja skrajnych pojazdów w składzie - if( ( mvOccupied->ActiveDir ) - && ( DynamicObject->Mechanik ) ) { - - DynamicObject->Mechanik->CheckVehicles( Change_direction ); - } - } - } - break; - } - - case user_command::batterytoggle: { - - if( Command.action == GLFW_PRESS ) { - // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( false == mvOccupied->Battery ) { - // turn on - // wyłącznik jest też w SN61, ewentualnie załączać prąd na stałe z poziomu FIZ - if( mvOccupied->BatterySwitch( true ) ) { - // bateria potrzebna np. do zapalenia świateł - if( ggBatteryButton.SubModel ) { - ggBatteryButton.UpdateValue( 1 ); - } - // audio feedback - play_sound( dsbSwitch ); - // side-effects - if( mvOccupied->LightsPosNo > 0 ) { - SetLights(); - } - if( TestFlag( mvOccupied->SecuritySystem.SystemType, 2 ) ) { - // Ra: znowu w kabinie jest coś, co być nie powinno! - SetFlag( mvOccupied->SecuritySystem.Status, s_active ); - SetFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ); - } - } - } - else { - //turn off - if( mvOccupied->BatterySwitch( false ) ) { - // ewentualnie zablokować z FIZ, np. w samochodach się nie odłącza akumulatora - if( ggBatteryButton.SubModel ) { - ggBatteryButton.UpdateValue( 0 ); - } - // audio feedback - play_sound( dsbSwitch ); - // side-effects - mvControlled->PantFront( false ); - mvControlled->PantRear( false ); - } - } - - } - break; - } - - case user_command::pantographtogglefront: { - - if( Command.action == GLFW_PRESS ) { - // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( false == ( mvOccupied->ActiveCab == 1 ? mvControlled->PantFrontUp : mvControlled->PantRearUp ) ) { - // turn on... - if( mvOccupied->ActiveCab == 1 ) { - // przedni gdy w kabinie 1 - mvControlled->PantFrontSP = false; - if( mvControlled->PantFront( true ) ) { - if( mvControlled->PantFrontStart != 1 ) { - if( ggPantFrontButton.SubModel ) { - ggPantFrontButton.UpdateValue( 1.0 ); - } - play_sound( dsbSwitch ); - } - } - } - else { - // rear otherwise - mvControlled->PantRearSP = false; - if( mvControlled->PantRear( true ) ) { - if( mvControlled->PantRearStart != 1 ) { - if( ggPantRearButton.SubModel ) { - ggPantRearButton.UpdateValue( 1.0 ); - } - play_sound( dsbSwitch ); - } - } - } - } - else { - // ...or turn off - if( mvOccupied->ActiveCab == 1 ) { - // przedni gdy w kabinie 1 - mvControlled->PantFrontSP = false; - if( false == mvControlled->PantFront( false ) ) { - if( mvControlled->PantFrontStart != 0 ) { - if( ggPantFrontButton.SubModel ) { - ggPantFrontButton.UpdateValue( - ( mvOccupied->PantSwitchType != "impulse" ? - 0.0 : - 1.0 ) ); - } - play_sound( dsbSwitch ); - } - } - } - else { - // rear otherwise - mvControlled->PantRearSP = false; - if( false == mvControlled->PantRear( false ) ) { - if( mvControlled->PantRearStart != 0 ) { - if( ggPantRearButton.SubModel ) { - ggPantRearButton.UpdateValue( - ( mvOccupied->PantSwitchType != "impulse" ? - 0.0 : - 1.0 ) ); - } - play_sound( dsbSwitch ); - } - } - } - } - } - else if( Command.action == GLFW_RELEASE ) { - // impulse switches return automatically to neutral position - if( mvOccupied->PantSwitchType == "impulse" ) { - if( mvOccupied->ActiveCab == 1 ) { - // przedni gdy w kabinie 1 - if( ggPantFrontButton.GetValue() > 0.1 ) { - play_sound( dsbSwitch ); - } - if( ggPantFrontButton.SubModel ) { - ggPantFrontButton.UpdateValue( 0.0 ); - } - } - else { - // rear otherwise - if( ggPantRearButton.GetValue() > 0.1 ) { - play_sound( dsbSwitch ); - } - if( ggPantRearButton.SubModel ) { - ggPantRearButton.UpdateValue( 0.0 ); - } - } - } - } - break; - } - - case user_command::pantographtogglerear: { - - if( Command.action == GLFW_PRESS ) { - // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( false == ( mvOccupied->ActiveCab == 1 ? mvControlled->PantRearUp : mvControlled->PantFrontUp ) ) { - // turn on... - if( mvOccupied->ActiveCab == 1 ) { - // rear if in front cab - mvControlled->PantRearSP = false; - if( mvControlled->PantRear( true ) ) { - if( mvControlled->PantRearStart != 1 ) { - if( ggPantRearButton.SubModel ) { - ggPantRearButton.UpdateValue( 1.0 ); - } - play_sound( dsbSwitch ); - } - } - } - else { - // front otherwise - mvControlled->PantFrontSP = false; - if( mvControlled->PantFront( true ) ) { - if( mvControlled->PantFrontStart != 1 ) { - if( ggPantFrontButton.SubModel ) { - ggPantFrontButton.UpdateValue( 1.0 ); - } - play_sound( dsbSwitch ); - } - } - } - } - else { - // ...or turn off - if( mvOccupied->ActiveCab == 1 ) { - // rear if in front cab - mvControlled->PantRearSP = false; - if( false == mvControlled->PantRear( false ) ) { - if( mvControlled->PantRearStart != 0 ) { - if( ggPantRearButton.SubModel ) { - ggPantRearButton.UpdateValue( - ( mvOccupied->PantSwitchType != "impulse" ? - 0.0 : - 1.0 ) ); - } - play_sound( dsbSwitch ); - } - } - } - else { - // front otherwise - mvControlled->PantFrontSP = false; - if( false == mvControlled->PantFront( false ) ) { - if( mvControlled->PantFrontStart != 0 ) { - if( ggPantFrontButton.SubModel ) { - ggPantFrontButton.UpdateValue( - ( mvOccupied->PantSwitchType != "impulse" ? - 0.0 : - 1.0 ) ); - } - play_sound( dsbSwitch ); - } - } - } - } - } - else if( Command.action == GLFW_RELEASE ) { - // impulse switches return automatically to neutral position - if( mvOccupied->PantSwitchType == "impulse" ) { - if( mvOccupied->ActiveCab == 1 ) { - // tylny gdy w kabinie 1 - if( ggPantRearButton.GetValue() > 0.1 ) { - play_sound( dsbSwitch ); - } - if( ggPantRearButton.SubModel ) { - ggPantRearButton.UpdateValue( 0.0 ); - } - } - else { - // front otherwise - if( ggPantFrontButton.GetValue() > 0.1 ) { - play_sound( dsbSwitch ); - } - if( ggPantFrontButton.SubModel ) { - ggPantFrontButton.UpdateValue( 0.0 ); - } - play_sound( dsbSwitch ); - } - } - } - break; - } - - case user_command::linebreakertoggle: { - - if( Command.action != GLFW_RELEASE ) { - // press or hold... - if( false == mvControlled->Mains ) { - // ...to close the circuit - if( false == m_linebreakerclosed ) { - // safety check so we don't close the circuit right after opening - if( ggMainOnButton.SubModel != nullptr ) { - // two separate switches to close and break the circuit - // audio feedback - if( Command.action == GLFW_PRESS ) { - play_sound( dsbSwitch ); - } - // visual feedback - ggMainOnButton.UpdateValue( 1.0 ); - } - else if( ggMainButton.SubModel != nullptr ) { - // single two-state switch - // audio feedback - if( Command.action == GLFW_PRESS ) { - play_sound( dsbSwitch ); - } - // visual feedback - ggMainButton.UpdateValue( 1.0 ); - } - // keep track of period the button is held down, to determine when/if circuit closes - fMainRelayTimer += 0.33; // Command.time_delta * 5.0; - // NOTE: this shouldn't be necessary, what exactly does it fix? - if( mvControlled->Mains != true ) { - // hunter-080812: poprawka - // adjusted further to take into account state of the switch - mvControlled->ConverterSwitch( ggConverterButton.GetValue() > 0.5 ); - mvControlled->CompressorSwitch( ggCompressorButton.GetValue() > 0.5 ); - } - if( fMainRelayTimer > mvControlled->InitialCtrlDelay ) { - // wlaczanie WSa z opoznieniem - if( mvControlled->MainSwitch( true ) ) { - // sound feedback, engine start for diesel vehicle - if( mvControlled->EngineType == DieselEngine ) { - play_sound( dsbDieselIgnition ); - } - } - } - } - } - else { - // ...to open the circuit - if( true == m_linebreakerclosed ) { - // safety check so we don't open the circuit right after closing - if( mvControlled->MainSwitch( false ) ) { - - if( ggMainOffButton.SubModel != nullptr ) { - // two separate switches to close and break the circuit - // audio feedback - if( Command.action == GLFW_PRESS ) { - play_sound( dsbSwitch ); - } - // visual feedback - ggMainOffButton.UpdateValue( 1.0 ); - } - else if( ggMainButton.SubModel != nullptr ) { - // single two-state switch - // NOTE: we don't have switch type definition for the line breaker switch - // so for the time being we have hard coded "impulse" switches for all EMUs - // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz - if( mvControlled->TrainType == dt_EZT ) { - // audio feedback - if( Command.action == GLFW_PRESS ) { - play_sound( dsbSwitch ); - } - // visual feedback - ggMainButton.UpdateValue( 1.0 ); - } - else { - // audio feedback - if( Command.action == GLFW_PRESS ) { - play_sound( dsbSwitch ); - } - // visual feedback - ggMainButton.UpdateValue( 0.0 ); - } - } - // side-effects - mvControlled->ConverterSwitch( ggConverterButton.GetValue() > 0.5 ); - mvControlled->CompressorSwitch( ggCompressorButton.GetValue() > 0.5 ); - } - // play sound immediately when the switch is hit, not after release - if( fMainRelayTimer > 0.0f ) { - play_sound( dsbRelay ); - fMainRelayTimer = 0.0f; + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == ( Train->mvOccupied->ActiveCab == 1 ? Train->mvControlled->PantFrontUp : Train->mvControlled->PantRearUp ) ) { + // turn on... + if( Train->mvOccupied->ActiveCab == 1 ) { + // przedni gdy w kabinie 1 + Train->mvControlled->PantFrontSP = false; + if( Train->mvControlled->PantFront( true ) ) { + if( Train->mvControlled->PantFrontStart != 1 ) { + if( Train->ggPantFrontButton.SubModel ) { + Train->ggPantFrontButton.UpdateValue( 1.0 ); } + Train->play_sound( Train->dsbSwitch ); } } } else { - // release... - if( false == mvControlled->Mains ) { - // ...after opening circuit, or holding for too short time to close it -/* - if( mvControlled->ConverterAllow ) { - // po puszczeniu przycisku od WSa odpalanie potwora - mvControlled->ConverterSwitch( true ); + // rear otherwise + Train->mvControlled->PantRearSP = false; + if( Train->mvControlled->PantRear( true ) ) { + if( Train->mvControlled->PantRearStart != 1 ) { + if( Train->ggPantRearButton.SubModel ) { + Train->ggPantRearButton.UpdateValue( 1.0 ); + } + Train->play_sound( Train->dsbSwitch ); } -*/ - // hunter-091012: przeniesione z mover.pas, zeby dzwiek sie nie zapetlal, - if( fMainRelayTimer > 0.0f ) { - play_sound( dsbRelay ); - fMainRelayTimer = 0.0f; + } + } + } + else { + // ...or turn off + if( Train->mvOccupied->ActiveCab == 1 ) { + // przedni gdy w kabinie 1 + Train->mvControlled->PantFrontSP = false; + if( false == Train->mvControlled->PantFront( false ) ) { + if( Train->mvControlled->PantFrontStart != 0 ) { + if( Train->ggPantFrontButton.SubModel ) { + Train->ggPantFrontButton.UpdateValue( + ( Train->mvOccupied->PantSwitchType != "impulse" ? + 0.0 : + 1.0 ) ); + } + Train->play_sound( Train->dsbSwitch ); } - // we don't exactly know which of the two buttons was used, so reset both - if( ggMainOnButton.SubModel != nullptr ) { - // setup with two separate swiches - ggMainOnButton.UpdateValue( 0.0 ); + } + } + else { + // rear otherwise + Train->mvControlled->PantRearSP = false; + if( false == Train->mvControlled->PantRear( false ) ) { + if( Train->mvControlled->PantRearStart != 0 ) { + if( Train->ggPantRearButton.SubModel ) { + Train->ggPantRearButton.UpdateValue( + ( Train->mvOccupied->PantSwitchType != "impulse" ? + 0.0 : + 1.0 ) ); + } + Train->play_sound( Train->dsbSwitch ); } - if( ggMainOffButton.SubModel != nullptr ) { - // setup with two separate swiches - ggMainOffButton.UpdateValue( 0.0 ); + } + } + } + } + else if( Command.action == GLFW_RELEASE ) { + // impulse switches return automatically to neutral position + if( Train->mvOccupied->PantSwitchType == "impulse" ) { + if( Train->mvOccupied->ActiveCab == 1 ) { + // przedni gdy w kabinie 1 + if( Train->ggPantFrontButton.GetValue() > 0.1 ) { + Train->play_sound( Train->dsbSwitch ); + } + if( Train->ggPantFrontButton.SubModel ) { + Train->ggPantFrontButton.UpdateValue( 0.0 ); + } + } + else { + // rear otherwise + if( Train->ggPantRearButton.GetValue() > 0.1 ) { + Train->play_sound( Train->dsbSwitch ); + } + if( Train->ggPantRearButton.SubModel ) { + Train->ggPantRearButton.UpdateValue( 0.0 ); + } + } + } + } +} + +void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &Command ) { + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == ( Train->mvOccupied->ActiveCab == 1 ? Train->mvControlled->PantRearUp : Train->mvControlled->PantFrontUp ) ) { + // turn on... + if( Train->mvOccupied->ActiveCab == 1 ) { + // rear if in front cab + Train->mvControlled->PantRearSP = false; + if( Train->mvControlled->PantRear( true ) ) { + if( Train->mvControlled->PantRearStart != 1 ) { + if( Train->ggPantRearButton.SubModel ) { + Train->ggPantRearButton.UpdateValue( 1.0 ); + } + Train->play_sound( Train->dsbSwitch ); } - // and the two-state switch too, for good measure - if( ggMainButton.SubModel != nullptr ) { - ggMainButton.UpdateValue( 0.0 ); + } + } + else { + // front otherwise + Train->mvControlled->PantFrontSP = false; + if( Train->mvControlled->PantFront( true ) ) { + if( Train->mvControlled->PantFrontStart != 1 ) { + if( Train->ggPantFrontButton.SubModel ) { + Train->ggPantFrontButton.UpdateValue( 1.0 ); + } + Train->play_sound( Train->dsbSwitch ); + } + } + } + } + else { + // ...or turn off + if( Train->mvOccupied->ActiveCab == 1 ) { + // rear if in front cab + Train->mvControlled->PantRearSP = false; + if( false == Train->mvControlled->PantRear( false ) ) { + if( Train->mvControlled->PantRearStart != 0 ) { + if( Train->ggPantRearButton.SubModel ) { + Train->ggPantRearButton.UpdateValue( + ( Train->mvOccupied->PantSwitchType != "impulse" ? + 0.0 : + 1.0 ) ); + } + Train->play_sound( Train->dsbSwitch ); + } + } + } + else { + // front otherwise + Train->mvControlled->PantFrontSP = false; + if( false == Train->mvControlled->PantFront( false ) ) { + if( Train->mvControlled->PantFrontStart != 0 ) { + if( Train->ggPantFrontButton.SubModel ) { + Train->ggPantFrontButton.UpdateValue( + ( Train->mvOccupied->PantSwitchType != "impulse" ? + 0.0 : + 1.0 ) ); + } + Train->play_sound( Train->dsbSwitch ); + } + } + } + } + } + else if( Command.action == GLFW_RELEASE ) { + // impulse switches return automatically to neutral position + if( Train->mvOccupied->PantSwitchType == "impulse" ) { + if( Train->mvOccupied->ActiveCab == 1 ) { + // tylny gdy w kabinie 1 + if( Train->ggPantRearButton.GetValue() > 0.1 ) { + Train->play_sound( Train->dsbSwitch ); + } + if( Train->ggPantRearButton.SubModel ) { + Train->ggPantRearButton.UpdateValue( 0.0 ); + } + } + else { + // front otherwise + if( Train->ggPantFrontButton.GetValue() > 0.1 ) { + Train->play_sound( Train->dsbSwitch ); + } + if( Train->ggPantFrontButton.SubModel ) { + Train->ggPantFrontButton.UpdateValue( 0.0 ); + } + Train->play_sound( Train->dsbSwitch ); + } + } + } +} + +void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ) { + if( Command.action != GLFW_RELEASE ) { + // press or hold... + if( false == Train->mvControlled->Mains ) { + // ...to close the circuit + if( false == Train->m_linebreakerclosed ) { + // safety check so we don't close the circuit right after opening + if( Train->ggMainOnButton.SubModel != nullptr ) { + // two separate switches to close and break the circuit + // audio feedback + if( Command.action == GLFW_PRESS ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggMainOnButton.UpdateValue( 1.0 ); + } + else if( Train->ggMainButton.SubModel != nullptr ) { + // single two-state switch + // audio feedback + if( Command.action == GLFW_PRESS ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggMainButton.UpdateValue( 1.0 ); + } + // keep track of period the button is held down, to determine when/if circuit closes + Train->fMainRelayTimer += 0.33f; // Command.time_delta * 5.0; + // NOTE: this shouldn't be necessary, what exactly does it fix? + if( Train->mvControlled->Mains != true ) { + // hunter-080812: poprawka + // adjusted further to take into account state of the switch + Train->mvControlled->ConverterSwitch( Train->ggConverterButton.GetValue() > 0.5 ); + Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 ); + } + if( Train->fMainRelayTimer > Train->mvControlled->InitialCtrlDelay ) { + // wlaczanie WSa z opoznieniem + if( Train->mvControlled->MainSwitch( true ) ) { + // sound feedback, engine start for diesel vehicle + if( Train->mvControlled->EngineType == DieselEngine ) { + Train->play_sound( Train->dsbDieselIgnition ); + } + } + } + } + } + else { + // ...to open the circuit + if( true == Train->m_linebreakerclosed ) { + // safety check so we don't open the circuit right after closing + if( Train->mvControlled->MainSwitch( false ) ) { + + if( Train->ggMainOffButton.SubModel != nullptr ) { + // two separate switches to close and break the circuit + // audio feedback + if( Command.action == GLFW_PRESS ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggMainOffButton.UpdateValue( 1.0 ); + } + else if( Train->ggMainButton.SubModel != nullptr ) { + // single two-state switch // NOTE: we don't have switch type definition for the line breaker switch // so for the time being we have hard coded "impulse" switches for all EMUs // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz - if( mvControlled->TrainType == dt_EZT ) { + if( Train->mvControlled->TrainType == dt_EZT ) { // audio feedback - play_sound( dsbSwitch ); + if( Command.action == GLFW_PRESS ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggMainButton.UpdateValue( 1.0 ); + } + else { + // audio feedback + if( Command.action == GLFW_PRESS ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggMainButton.UpdateValue( 0.0 ); } } - m_linebreakerclosed = false; + // side-effects + Train->mvControlled->ConverterSwitch( Train->ggConverterButton.GetValue() > 0.5 ); + Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 ); } - else { - // ...after closing the circuit - if( ggMainOnButton.SubModel != nullptr ) { - // setup with two separate switches - ggMainOnButton.UpdateValue( 0.0 ); - } - // NOTE: we don't have switch type definition for the line breaker switch - // so for the time being we have hard coded "impulse" switches for all EMUs - // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz - if( mvControlled->TrainType == dt_EZT ) { - if( ggMainButton.SubModel != nullptr ) { - ggMainButton.UpdateValue( 0.0 ); - // audio feedback - play_sound( dsbSwitch ); - } - } - m_linebreakerclosed = true; + // play sound immediately when the switch is hit, not after release + if( Train->fMainRelayTimer > 0.0f ) { + Train->play_sound( Train->dsbRelay ); + Train->fMainRelayTimer = 0.0f; } } - break; } - - case user_command::convertertoggle: { - - if( Command.action == GLFW_PRESS ) { - // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( false == mvControlled->ConverterAllow ) { - // turn on - if( ( mvControlled->EnginePowerSource.SourceType != CurrentCollector ) - || ( mvControlled->PantRearVolt != 0.0 ) - || ( mvControlled->PantFrontVolt != 0.0 ) ) { - // visual feedback - ggConverterButton.UpdateValue( 1.0 ); - // sound feedback - if( ggConverterButton.GetValue() < 0.5 ) { - play_sound( dsbSwitch ); - } - // impulse type switch has no effect if there's no power - // NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway - if( ( mvOccupied->ConvSwitchType != "impulse" ) - || ( mvControlled->Mains ) ) { - if( true == mvControlled->ConverterSwitch( true ) ) { - // side effects - // control the compressor, if it's paired with the converter - if( mvControlled->CompressorPower == 2 ) { - // hunter-091012: tak jest poprawnie - mvControlled->CompressorSwitch( true ); - } - } - } - } + } + else { + // release... + if( false == Train->mvControlled->Mains ) { + // ...after opening circuit, or holding for too short time to close it + /* + if( mvControlled->ConverterAllow ) { + // po puszczeniu przycisku od WSa odpalanie potwora + mvControlled->ConverterSwitch( true ); + } + */ + // hunter-091012: przeniesione z mover.pas, zeby dzwiek sie nie zapetlal, + if( Train->fMainRelayTimer > 0.0f ) { + Train->play_sound( Train->dsbRelay ); + Train->fMainRelayTimer = 0.0f; + } + // we don't exactly know which of the two buttons was used, so reset both + if( Train->ggMainOnButton.SubModel != nullptr ) { + // setup with two separate swiches + Train->ggMainOnButton.UpdateValue( 0.0 ); + } + if( Train->ggMainOffButton.SubModel != nullptr ) { + // setup with two separate swiches + Train->ggMainOffButton.UpdateValue( 0.0 ); + } + // and the two-state switch too, for good measure + if( Train->ggMainButton.SubModel != nullptr ) { + Train->ggMainButton.UpdateValue( 0.0 ); + // NOTE: we don't have switch type definition for the line breaker switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz + if( Train->mvControlled->TrainType == dt_EZT ) { + // audio feedback + Train->play_sound( Train->dsbSwitch ); } - else { - //turn off - if( true == mvControlled->ConverterSwitch( false ) ) { - // sound feedback - play_sound( dsbSwitch ); - // visual feedback - ggConverterButton.UpdateValue( 0.0 ); - if( ggConverterOffButton.SubModel != nullptr ) { - ggConverterOffButton.UpdateValue( 1.0 ); - } + } + Train->m_linebreakerclosed = false; + } + else { + // ...after closing the circuit + if( Train->ggMainOnButton.SubModel != nullptr ) { + // setup with two separate switches + Train->ggMainOnButton.UpdateValue( 0.0 ); + } + // NOTE: we don't have switch type definition for the line breaker switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz + if( Train->mvControlled->TrainType == dt_EZT ) { + if( Train->ggMainButton.SubModel != nullptr ) { + Train->ggMainButton.UpdateValue( 0.0 ); + // audio feedback + Train->play_sound( Train->dsbSwitch ); + } + } + Train->m_linebreakerclosed = true; + } + } +} + +void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Command ) { + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == Train->mvControlled->ConverterAllow ) { + // turn on + if( ( Train->mvControlled->EnginePowerSource.SourceType != CurrentCollector ) + || ( Train->mvControlled->PantRearVolt != 0.0 ) + || ( Train->mvControlled->PantFrontVolt != 0.0 ) ) { + // visual feedback + Train->ggConverterButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggConverterButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // impulse type switch has no effect if there's no power + // NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway + if( ( Train->mvOccupied->ConvSwitchType != "impulse" ) + || ( Train->mvControlled->Mains ) ) { + if( true == Train->mvControlled->ConverterSwitch( true ) ) { // side effects // control the compressor, if it's paired with the converter - if( mvControlled->CompressorPower == 2 ) { + if( Train->mvControlled->CompressorPower == 2 ) { // hunter-091012: tak jest poprawnie - mvControlled->CompressorSwitch( false ); - } - if( ( mvControlled->TrainType == dt_EZT ) - && ( !TestFlag( mvControlled->EngDmgFlag, 4 ) ) ) { - mvControlled->ConvOvldFlag = false; + Train->mvControlled->CompressorSwitch( true ); } } } } - else if( Command.action == GLFW_RELEASE ){ - // on button release... - if( mvOccupied->ConvSwitchType == "impulse" ) { - // ...return switches to start position if applicable - if( ( ggConverterButton.GetValue() > 0.0 ) - || ( ggConverterOffButton.GetValue() > 0.0 ) ) { - // sound feedback - play_sound( dsbSwitch ); - } - ggConverterButton.UpdateValue( 0.0 ); - ggConverterOffButton.UpdateValue( 0.0 ); - } - } - break; } - - case user_command::compressortoggle: { - - if( mvControlled->CompressorPower < 2 ) { - - if( Command.action == GLFW_PRESS ) { - // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( false == mvControlled->CompressorAllow ) { - // turn on - // visual feedback - ggCompressorButton.UpdateValue( 1.0 ); - // sound feedback - if( ggCompressorButton.GetValue() < 0.5 ) { - play_sound( dsbSwitch ); - } - // impulse type switch has no effect if there's no power - // NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway - // (we're presuming impulse type switch for all EMUs for the time being) -/* - if( ( mvControlled->TrainType != dt_EZT ) - || ( mvControlled->Mains ) ) { -*/ - mvControlled->CompressorSwitch( true ); -/* - } -*/ - } - else { - //turn off - if( true == mvControlled->CompressorSwitch( false ) ) { - // sound feedback - play_sound( dsbSwitch ); - // NOTE: we don't have switch type definition for the compresor switch - // so for the time being we have hard coded "impulse" switches for all EMUs - // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz -/* - if( mvControlled->TrainType == dt_EZT ) { - // visual feedback - ggCompressorButton.UpdateValue( 1.0 ); - } - else { -*/ - // visual feedback - ggCompressorButton.UpdateValue( 0.0 ); -/* - } -*/ - } - } + else { + //turn off + if( true == Train->mvControlled->ConverterSwitch( false ) ) { + // sound feedback + Train->play_sound( Train->dsbSwitch ); + // visual feedback + Train->ggConverterButton.UpdateValue( 0.0 ); + if( Train->ggConverterOffButton.SubModel != nullptr ) { + Train->ggConverterOffButton.UpdateValue( 1.0 ); } - else if( Command.action == GLFW_RELEASE ) { - // on button release... -/* - // TODO: check if compressor switch is two-state or impulse type - // NOTE: we don't have switch type definition for the compresor switch - // so for the time being we have hard coded "impulse" switches for all EMUs - // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz - if( mvControlled->TrainType == dt_EZT ) { - if( ggCompressorButton.SubModel != nullptr ) { - ggCompressorButton.UpdateValue( 0.0 ); - // audio feedback - play_sound( dsbSwitch ); - } - } -*/ + // side effects + // control the compressor, if it's paired with the converter + if( Train->mvControlled->CompressorPower == 2 ) { + // hunter-091012: tak jest poprawnie + Train->mvControlled->CompressorSwitch( false ); + } + if( ( Train->mvControlled->TrainType == dt_EZT ) + && ( !TestFlag( Train->mvControlled->EngDmgFlag, 4 ) ) ) { + Train->mvControlled->ConvOvldFlag = false; } } - break; } + } + else if( Command.action == GLFW_RELEASE ) { + // on button release... + if( Train->mvOccupied->ConvSwitchType == "impulse" ) { + // ...return switches to start position if applicable + if( ( Train->ggConverterButton.GetValue() > 0.0 ) + || ( Train->ggConverterOffButton.GetValue() > 0.0 ) ) { + // sound feedback + Train->play_sound( Train->dsbSwitch ); + } + Train->ggConverterButton.UpdateValue( 0.0 ); + Train->ggConverterOffButton.UpdateValue( 0.0 ); + } + } +} - default: { - - break; +void TTrain::OnCommand_compressortoggle( TTrain *Train, command_data const &Command ) { + + if( Train->mvControlled->CompressorPower >= 2 ) { + return; + } + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == Train->mvControlled->CompressorAllow ) { + // turn on + // visual feedback + Train->ggCompressorButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggCompressorButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // impulse type switch has no effect if there's no power + // NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway + // (we're presuming impulse type switch for all EMUs for the time being) +// if( ( mvControlled->TrainType != dt_EZT ) +// || ( mvControlled->Mains ) ) { + + Train->mvControlled->CompressorSwitch( true ); +// } + } + else { + //turn off + if( true == Train->mvControlled->CompressorSwitch( false ) ) { + // sound feedback + Train->play_sound( Train->dsbSwitch ); + // NOTE: we don't have switch type definition for the compresor switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz +// if( mvControlled->TrainType == dt_EZT ) { +// // visual feedback +// ggCompressorButton.UpdateValue( 1.0 ); +// } +// else { + // visual feedback + Train->ggCompressorButton.UpdateValue( 0.0 ); +// } + } + } + } +/* + // disabled because EMUs have basic switches. left in case impulse switch code is needed, so we don't have to reinvent the wheel + else if( Command.action == GLFW_RELEASE ) { + // on button release... + // TODO: check if compressor switch is two-state or impulse type + // NOTE: we don't have switch type definition for the compresor switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz + if( mvControlled->TrainType == dt_EZT ) { + if( ggCompressorButton.SubModel != nullptr ) { + ggCompressorButton.UpdateValue( 0.0 ); + // audio feedback + play_sound( dsbSwitch ); + } + } + } +*/ +} + +void TTrain::OnCommand_headlighttoggleleft( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->LightsPosNo > 0 ) { + // lights are controlled by preset selector + return; + } + + int const lightsindex = + ( Train->mvOccupied->ActiveCab == 1 ? + 0 : + 1 ); + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_left ) == 0 ) { + // turn on + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left; + // visual feedback + Train->ggLeftLightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggLeftLightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + //turn off + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left; + // visual feedback + Train->ggLeftLightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggLeftLightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } +} + +void TTrain::OnCommand_headlighttoggleright( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->LightsPosNo > 0 ) { + // lights are controlled by preset selector + return; + } + + int const lightsindex = + ( Train->mvOccupied->ActiveCab == 1 ? + 0 : + 1 ); + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_right ) == 0 ) { + // turn on + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right; + // visual feedback + Train->ggRightLightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggRightLightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + //turn off + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right; + // visual feedback + Train->ggRightLightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggRightLightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } +} + +void TTrain::OnCommand_headlighttoggleupper( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->LightsPosNo > 0 ) { + // lights are controlled by preset selector + return; + } + + int const lightsindex = + ( Train->mvOccupied->ActiveCab == 1 ? + 0 : + 1 ); + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_upper ) == 0 ) { + // turn on + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_upper; + // visual feedback + Train->ggUpperLightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggUpperLightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + //turn off + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_upper; + // visual feedback + Train->ggUpperLightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggUpperLightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } +} + +void TTrain::OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->LightsPosNo > 0 ) { + // lights are controlled by preset selector + return; + } + + int const lightsindex = + ( Train->mvOccupied->ActiveCab == 1 ? + 0 : + 1 ); + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_left ) == 0 ) { + // turn on + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left; + // visual feedback + Train->ggLeftEndLightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggLeftEndLightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + //turn off + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left; + // visual feedback + Train->ggLeftEndLightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggLeftEndLightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } +} + +void TTrain::OnCommand_redmarkertoggleright( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->LightsPosNo > 0 ) { + // lights are controlled by preset selector + return; + } + + int const lightsindex = + ( Train->mvOccupied->ActiveCab == 1 ? + 0 : + 1 ); + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_right ) == 0 ) { + // turn on + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right; + // visual feedback + Train->ggRightEndLightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggRightEndLightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + //turn off + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right; + // visual feedback + Train->ggRightEndLightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggRightEndLightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } +} + +void TTrain::OnCommand_headlighttogglerearleft( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->LightsPosNo > 0 ) { + // lights are controlled by preset selector + return; + } + + int const lightsindex = + ( Train->mvOccupied->ActiveCab == 1 ? + 1 : + 0 ); + + if( Command.action == GLFW_PRESS ) { + // NOTE: we toggle the light on opposite side, as 'rear right' is 'front left' on the rear end etc + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_right ) == 0 ) { + // turn on + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right; + // visual feedback + Train->ggRearLeftLightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggRearLeftLightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + //turn off + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right; + // visual feedback + Train->ggRearLeftLightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggRearLeftLightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } +} + +void TTrain::OnCommand_headlighttogglerearright( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->LightsPosNo > 0 ) { + // lights are controlled by preset selector + return; + } + + int const lightsindex = + ( Train->mvOccupied->ActiveCab == 1 ? + 1 : + 0 ); + + if( Command.action == GLFW_PRESS ) { + // NOTE: we toggle the light on opposite side, as 'rear right' is 'front left' on the rear end etc + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_left ) == 0 ) { + // turn on + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left; + // visual feedback + Train->ggRearRightLightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggRearRightLightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + //turn off + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left; + // visual feedback + Train->ggRearRightLightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggRearRightLightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } +} + +void TTrain::OnCommand_headlighttogglerearupper( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->LightsPosNo > 0 ) { + // lights are controlled by preset selector + return; + } + + int const lightsindex = + ( Train->mvOccupied->ActiveCab == 1 ? + 1 : + 0 ); + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_upper ) == 0 ) { + // turn on + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_upper; + // visual feedback + Train->ggRearUpperLightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggRearUpperLightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + //turn off + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_upper; + // visual feedback + Train->ggRearUpperLightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggRearUpperLightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } +} + +void TTrain::OnCommand_redmarkertogglerearleft( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->LightsPosNo > 0 ) { + // lights are controlled by preset selector + return; + } + + int const lightsindex = + ( Train->mvOccupied->ActiveCab == 1 ? + 1 : + 0 ); + + if( Command.action == GLFW_PRESS ) { + // NOTE: we toggle the light on opposite side, as 'rear right' is 'front left' on the rear end etc + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_right ) == 0 ) { + // turn on + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right; + // visual feedback + Train->ggRearLeftEndLightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggRearLeftEndLightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + //turn off + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right; + // visual feedback + Train->ggRearLeftEndLightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggRearLeftEndLightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } +} + +void TTrain::OnCommand_redmarkertogglerearright( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->LightsPosNo > 0 ) { + // lights are controlled by preset selector + return; + } + + int const lightsindex = + ( Train->mvOccupied->ActiveCab == 1 ? + 1 : + 0 ); + + if( Command.action == GLFW_PRESS ) { + // NOTE: we toggle the light on opposite side, as 'rear right' is 'front left' on the rear end etc + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_left ) == 0 ) { + // turn on + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left; + // visual feedback + Train->ggRearRightEndLightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggRearRightEndLightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + //turn off + Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left; + // visual feedback + Train->ggRearRightEndLightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggRearRightEndLightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } +} + +void TTrain::OnCommand_doortoggleleft( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->DoorOpenCtrl != 1 ) { + return; + } + if( Command.action == GLFW_PRESS ) { + // NOTE: test how the door state check works with consists where the occupied vehicle doesn't have opening doors + if( false == ( + Train->mvOccupied->ActiveCab == 1 ? + Train->mvOccupied->DoorLeftOpened : + Train->mvOccupied->DoorRightOpened ) ) { + // open + if( Train->mvOccupied->ActiveCab == 1 ) { + if( Train->mvOccupied->DoorLeft( true ) ) { + Train->ggDoorLeftButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggDoorLeftButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + Train->play_sound( Train->dsbDoorOpen ); + } + } + else { + // in the rear cab sides are reversed + if( Train->mvOccupied->DoorRight( true ) ) { + Train->ggDoorRightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggDoorRightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + Train->play_sound( Train->dsbDoorOpen ); + } + } + } + else { + // close + if( Train->mvOccupied->ActiveCab == 1 ) { + if( Train->mvOccupied->DoorLeft( false ) ) { + Train->ggDoorLeftButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggDoorLeftButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + Train->play_sound( Train->dsbDoorOpen ); + } + } + else { + // in the rear cab sides are reversed + if( Train->mvOccupied->DoorRight( false ) ) { + Train->ggDoorRightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggDoorRightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + Train->play_sound( Train->dsbDoorOpen ); + } + } + } + } +} + +void TTrain::OnCommand_doortoggleright( TTrain *Train, command_data const &Command ) { + + if( Train->mvOccupied->DoorOpenCtrl != 1 ) { + return; + } + if( Command.action == GLFW_PRESS ) { + // NOTE: test how the door state check works with consists where the occupied vehicle doesn't have opening doors + if( false == ( + Train->mvOccupied->ActiveCab == 1 ? + Train->mvOccupied->DoorRightOpened : + Train->mvOccupied->DoorLeftOpened ) ) { + // open + if( Train->mvOccupied->ActiveCab == 1 ) { + if( Train->mvOccupied->DoorRight( true ) ) { + Train->ggDoorRightButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggDoorRightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + Train->play_sound( Train->dsbDoorOpen ); + } + } + else { + // in the rear cab sides are reversed + if( Train->mvOccupied->DoorLeft( true ) ) { + Train->ggDoorLeftButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggDoorLeftButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + Train->play_sound( Train->dsbDoorOpen ); + } + } + } + else { + // close + if( Train->mvOccupied->ActiveCab == 1 ) { + if( Train->mvOccupied->DoorRight( false ) ) { + Train->ggDoorRightButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggDoorRightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + Train->play_sound( Train->dsbDoorOpen ); + } + } + else { + // in the rear cab sides are reversed + if( Train->mvOccupied->DoorLeft( false ) ) { + Train->ggDoorLeftButton.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggDoorLeftButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + Train->play_sound( Train->dsbDoorOpen ); + } + } } } } @@ -1315,8 +1854,7 @@ void TTrain::OnKeyDown(int cKey) if (mvOccupied->Radio == false) if (Global::ctrlState) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); mvOccupied->Radio = true; } } @@ -1405,7 +1943,7 @@ void TTrain::OnKeyDown(int cKey) { if ((mvControlled->Signalling == false)) { - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); mvControlled->Signalling = true; } } @@ -1419,7 +1957,7 @@ void TTrain::OnKeyDown(int cKey) if (!mvControlled->DoorSignalling) { mvOccupied->DoorBlocked = true; - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); mvControlled->DoorSignalling = true; } } @@ -1457,15 +1995,13 @@ void TTrain::OnKeyDown(int cKey) if (Global::ctrlState) if (mvOccupied->BrakeDelaySwitch(bdelay_R + bdelay_M)) { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); + play_sound( dsbPneumaticRelay ); } else ; else if (mvOccupied->BrakeDelaySwitch(bdelay_P)) { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); + play_sound( dsbPneumaticRelay ); } } else @@ -1484,15 +2020,13 @@ void TTrain::OnKeyDown(int cKey) if (Global::ctrlState) if (temp->MoverParameters->BrakeDelaySwitch(bdelay_R + bdelay_M)) { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); + play_sound( dsbPneumaticRelay ); } else ; else if (temp->MoverParameters->BrakeDelaySwitch(bdelay_P)) { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); + play_sound( dsbPneumaticRelay ); } } } @@ -1534,8 +2068,7 @@ void TTrain::OnKeyDown(int cKey) if (mvControlled->PantPress < 4.8) // piszą, że to tak nie działa { mvControlled->PantCompFlag = true; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); // dźwięk tylko po naciśnięciu klawisza + play_sound( dsbSwitch ); // dźwięk tylko po naciśnięciu klawisza } } else if (cKey == GLFW_KEY_Q) // ze Shiftem - włączenie AI @@ -1561,8 +2094,7 @@ void TTrain::OnKeyDown(int cKey) } if (mvControlled->CurrentSwitch(true)) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } /* Ra: przeniesione do Mover.cpp if (mvControlled->TrainType!=dt_EZT) //to powinno być w fizyce, a @@ -1579,8 +2111,7 @@ void TTrain::OnKeyDown(int cKey) { if (mvControlled->AutoRelaySwitch(true)) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } } else if (cKey == Global::Keys[k_FailedEngineCutOff]) // McZapkie-060103: E @@ -1589,11 +2120,11 @@ void TTrain::OnKeyDown(int cKey) { if (mvControlled->CutOffEngine()) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } } - else if (cKey == Global::Keys[k_OpenLeft]) // NBMX 17-09-2003: otwieranie drzwi +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + else if( cKey == Global::Keys[ k_OpenLeft ] ) // NBMX 17-09-2003: otwieranie drzwi { if (mvOccupied->DoorOpenCtrl == 1) if (mvOccupied->CabNo < 0 ? mvOccupied->DoorRight(true) : mvOccupied->DoorLeft(true)) @@ -1621,6 +2152,7 @@ void TTrain::OnKeyDown(int cKey) } } } +#endif //----------- // hunter-131211: dzwiek dla przelacznika universala podniesionego // hunter-091012: ubajerowanie swiatla w kabinie (wyrzucenie @@ -1631,16 +2163,14 @@ void TTrain::OnKeyDown(int cKey) { if (bCabLight == false) //(ggCabLightButton.GetValue()==0) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } } else { if (ggUniversal3Button.GetValue() == 0) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } /* if (Global::ctrlState) @@ -1659,8 +2189,7 @@ void TTrain::OnKeyDown(int cKey) { if (bCabLightDim == false) //(ggCabLightDimButton.GetValue()==0) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } } } @@ -1749,12 +2278,12 @@ void TTrain::OnKeyDown(int cKey) (mvControlled->ConverterFlag))) { mvControlled->Heating = true; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } } } - else if (cKey == Global::Keys[k_LeftSign]) // lewe swiatlo - włączenie +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + else if( cKey == Global::Keys[ k_LeftSign ] ) // lewe swiatlo - włączenie // ABu 060205: dzielo Wingera po malutkim liftingu: { if (false == (mvOccupied->LightsPosNo > 0)) @@ -1862,6 +2391,7 @@ void TTrain::OnKeyDown(int cKey) } //----------- } } +#endif else if (cKey == Global::Keys[k_UpperSign]) // ABu 060205: światło górne - // włączenie { @@ -1874,11 +2404,11 @@ void TTrain::OnKeyDown(int cKey) { mvOccupied->LightsPos = 1; } - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); SetLights(); } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if ((Global::ctrlState) && (ggRearUpperLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu { @@ -1927,8 +2457,10 @@ void TTrain::OnKeyDown(int cKey) } } } +#endif } - else if (cKey == Global::Keys[k_RightSign]) // Winger 070304: swiatla +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + else if( cKey == Global::Keys[ k_RightSign ] ) // Winger 070304: swiatla // tylne (koncowki) - // wlaczenie { @@ -2029,6 +2561,7 @@ void TTrain::OnKeyDown(int cKey) } } } +#endif } else // McZapkie-240302 - klawisze bez shifta { @@ -2282,7 +2815,6 @@ void TTrain::OnKeyDown(int cKey) // while (mvOccupied->BrakeCtrlPos<-1 && mvOccupied->IncBrakeLevel()); mvOccupied->BrakeLevelSet(-1); } -#endif else if (cKey == Global::Keys[k_Czuwak]) //--------------- // hunter-131211: zbicie czuwaka przeniesione do TTrain::Update() @@ -2296,7 +2828,8 @@ void TTrain::OnKeyDown(int cKey) } // ggSecurityResetButton.PutValue(1); } - else if (cKey == Global::Keys[k_AntiSlipping]) +#endif + else if( cKey == Global::Keys[ k_AntiSlipping ] ) //--------------- // hunter-221211: hamulec przeciwposlizgowy przeniesiony do // TTrain::Update() @@ -2308,8 +2841,7 @@ void TTrain::OnKeyDown(int cKey) { // Dlaczego bylo '-50'??? // dsbSwitch->SetVolume(-50); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } // ggAntiSlipButton.PutValue(1); } @@ -2364,8 +2896,7 @@ void TTrain::OnKeyDown(int cKey) { // wciśnięty [Ctrl] if (mvOccupied->Radio == true) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); mvOccupied->Radio = false; } } @@ -2448,15 +2979,13 @@ void TTrain::OnKeyDown(int cKey) if (Global::ctrlState) if (mvOccupied->BrakeDelaySwitch(bdelay_R)) { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); + play_sound( dsbPneumaticRelay ); } else ; else if (mvOccupied->BrakeDelaySwitch(bdelay_G)) { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); + play_sound( dsbPneumaticRelay ); } } else @@ -2475,15 +3004,13 @@ void TTrain::OnKeyDown(int cKey) if (Global::ctrlState) if (temp->MoverParameters->BrakeDelaySwitch(bdelay_R)) { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); + play_sound( dsbPneumaticRelay ); } else ; else if (temp->MoverParameters->BrakeDelaySwitch(bdelay_G)) { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); + play_sound( dsbPneumaticRelay ); } } } @@ -2547,8 +3074,7 @@ void TTrain::OnKeyDown(int cKey) if (mvControlled->PantPress < 4.8) // piszą, że to tak nie działa { mvControlled->PantCompFlag = true; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); // dźwięk tylko po naciśnięciu klawisza + play_sound( dsbSwitch ); // dźwięk tylko po naciśnięciu klawisza } } // McZapkie-240302 - wylaczanie automatycznego pilota (w trybie ~debugmode @@ -2567,8 +3093,7 @@ void TTrain::OnKeyDown(int cKey) } if (mvControlled->CurrentSwitch(false)) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } /* Ra: przeniesione do Mover.cpp if (mvControlled->TrainType!=dt_EZT) @@ -2584,8 +3109,7 @@ void TTrain::OnKeyDown(int cKey) { if (mvControlled->AutoRelaySwitch(false)) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } } @@ -2611,7 +3135,7 @@ void TTrain::OnKeyDown(int cKey) if (mvControlled->DoorSignalling) { mvOccupied->DoorBlocked = false; - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); mvControlled->DoorSignalling = false; } } @@ -2703,8 +3227,7 @@ if // //podłączony sprzęg będzie widoczny if (DynamicObject->Mechanik) // na wszelki wypadek DynamicObject->Mechanik->CheckVehicles(Connect); // aktualizacja flag kierunku w składzie - dsbCouplerAttach->SetVolume(DSBVOLUME_MAX); - dsbCouplerAttach->Play(0, 0, 0); + play_sound( dsbCouplerAttach ); } else WriteLog("Mechanical coupling failed."); @@ -2735,8 +3258,7 @@ if (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_scndpneumatic))) { // rsHiss.Play(1,DSBPLAY_LOOPING,true,tmp->GetPosition()); - dsbCouplerDetach->SetVolume(DSBVOLUME_MAX); - dsbCouplerDetach->Play(0, 0, 0); + play_sound( dsbCouplerDetach ); DynamicObject->SetPneumatic(CouplNr != 0, false); // Ra: to mi się nie podoba !!!! tmp->SetPneumatic(CouplNr != 0, false); } @@ -2753,8 +3275,7 @@ if tmp->MoverParameters->Couplers[CouplNr].Connected, (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_controll))) { - dsbCouplerAttach->SetVolume(DSBVOLUME_MAX); - dsbCouplerAttach->Play(0, 0, 0); + play_sound( dsbCouplerAttach ); } } else if (!TestFlag(tmp->MoverParameters->Couplers[CouplNr].CouplingFlag, ctrain_passenger)) // mostek @@ -2770,8 +3291,7 @@ if (tmp->MoverParameters->Couplers[CouplNr].CouplingFlag | ctrain_passenger))) { // rsHiss.Play(1,DSBPLAY_LOOPING,true,tmp->GetPosition()); - dsbCouplerDetach->SetVolume(DSBVOLUME_MAX); - dsbCouplerDetach->Play(0, 0, 0); + play_sound( dsbCouplerDetach ); DynamicObject->SetPneumatic(CouplNr != 0, false); tmp->SetPneumatic(CouplNr != 0, false); } @@ -2791,8 +3311,7 @@ if if (DynamicObject->DettachStatus(iCabn - 1) < 0) // jeśli jest co odczepić if (DynamicObject->Dettach(iCabn - 1)) // iCab==1:przód,iCab==2:tył { - dsbCouplerDetach->SetVolume(DSBVOLUME_MAX); // w kabinie ten dźwięk? - dsbCouplerDetach->Play(0, 0, 0); + play_sound( dsbCouplerDetach ); // w kabinie ten dźwięk? } } else @@ -2808,8 +3327,7 @@ if if (tmp->DettachStatus(CouplNr) < 0) // jeśli jest co odczepić i się da if (!tmp->Dettach(CouplNr)) { // dźwięk odczepiania - dsbCouplerDetach->SetVolume(DSBVOLUME_MAX); - dsbCouplerDetach->Play(0, 0, 0); + play_sound( dsbCouplerDetach ); } } } @@ -2818,6 +3336,7 @@ if Disconnect); // aktualizacja skrajnych pojazdów w składzie } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_CloseLeft]) // NBMX 17-09-2003: zamykanie drzwi { if( mvOccupied->DoorCloseCtrl == 1 ) { @@ -2844,7 +3363,7 @@ if } } } - +#endif //----------- // hunter-131211: dzwiek dla przelacznika universala // hunter-091012: ubajerowanie swiatla w kabinie (wyrzucenie @@ -2855,16 +3374,14 @@ if { if (bCabLight == true) //(ggCabLightButton.GetValue()!=0) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } } else { if (ggUniversal3Button.GetValue() != 0) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } /* if (Global::ctrlState) @@ -2882,8 +3399,7 @@ if { if (bCabLightDim == true) //(ggCabLightDimButton.GetValue()!=0) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); } } } @@ -2950,12 +3466,12 @@ if { if (mvControlled->Heating == true) { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); mvControlled->Heating = false; } } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_LeftSign]) // ABu 060205: lewe swiatlo - // wylaczenie { @@ -3057,6 +3573,7 @@ if } } } +#endif else if (cKey == Global::Keys[k_UpperSign]) // ABu 060205: światło górne - // wyłączenie { @@ -3069,11 +3586,11 @@ if { mvOccupied->LightsPos = mvOccupied->LightsPosNo; } - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); SetLights(); } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if ((Global::ctrlState) && (ggRearUpperLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu { @@ -3122,7 +3639,9 @@ if } } } +#endif } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM if (cKey == Global::Keys[k_RightSign]) // Winger 070304: swiatla tylne // (koncowki) - wlaczenie { @@ -3224,6 +3743,7 @@ if } } } +#endif else if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // Winger 110904: wylacznik st. // liniowych { @@ -3231,21 +3751,19 @@ if (mvControlled->TrainType != dt_ET40)) { ggStLinOffButton.PutValue(1); // Ra: było Fuse... - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); if (mvControlled->MainCtrlPosNo > 0) { mvControlled->StLinFlag = false; // yBARC - zmienione na przeciwne, bo true to zalaczone - dsbRelay->SetVolume(DSBVOLUME_MAX); - dsbRelay->Play(0, 0, 0); + play_sound( dsbRelay ); } } if (mvControlled->TrainType == dt_EZT) { if (mvControlled->Signalling == true) { - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); mvControlled->Signalling = false; } } @@ -3367,14 +3885,12 @@ if if( DynamicObject->DimHeadlights && (!Global::shiftState)) { DynamicObject->DimHeadlights = false; // switch sound - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); + play_sound( dsbSwitch ); } else if( (!DynamicObject->DimHeadlights) && (Global::shiftState)) { DynamicObject->DimHeadlights = true; // switch sound - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); + play_sound( dsbSwitch ); } } } @@ -3520,12 +4036,16 @@ bool TTrain::Update( double const Deltatime ) // NOTE: this is a temporary arrangement, for the transition period from old command setup to the new one // eventually commands are going to be retrieved directly by the vehicle, filtered through active control stand // and ultimately executed, provided the stand allows it. - command_data command; + command_data commanddata; // NOTE: currently we're only storing commands for local vehicle and there's no id system in place, // so we're supplying 'default' vehicle id of 0 - while( simulation::Commands.pop( command, static_cast( command_target::vehicle ) | 0 ) ) { + while( simulation::Commands.pop( commanddata, static_cast( command_target::vehicle ) | 0 ) ) { - OnCommand( command ); + auto lookup = m_commandhandlers.find( commanddata.command ); + if( lookup != m_commandhandlers.end() ) { + // pass the command to the assigned handler + lookup->second( this, commanddata ); + } } // update driver's position @@ -4089,30 +4609,32 @@ bool TTrain::Update( double const Deltatime ) if (mvOccupied->EventFlag || TestFlag(mvOccupied->SoundFlag, sound_loud)) { mvOccupied->EventFlag = false; // Ra: w kabinie? - dsbRelay->SetVolume(DSBVOLUME_MAX); + if( dsbRelay != nullptr ) { dsbRelay->SetVolume( DSBVOLUME_MAX ); } } else { - dsbRelay->SetVolume(-40); + if( dsbRelay != nullptr ) { dsbRelay->SetVolume( -40 ); } } if (!TestFlag(mvOccupied->SoundFlag, sound_manyrelay)) - dsbRelay->Play(0, 0, 0); + play_sound( dsbRelay ); else { if (TestFlag(mvOccupied->SoundFlag, sound_loud)) - dsbWejscie_na_bezoporow->Play(0, 0, 0); + play_sound( dsbWejscie_na_bezoporow ); else - dsbWejscie_na_drugi_uklad->Play(0, 0, 0); + play_sound( dsbWejscie_na_drugi_uklad ); } } - if (TestFlag(mvOccupied->SoundFlag, sound_bufferclamp)) // zderzaki uderzaja o siebie - { - if (TestFlag(mvOccupied->SoundFlag, sound_loud)) - dsbBufferClamp->SetVolume(DSBVOLUME_MAX); - else - dsbBufferClamp->SetVolume(-20); - dsbBufferClamp->Play(0, 0, 0); + if( dsbBufferClamp != nullptr ) { + if( TestFlag( mvOccupied->SoundFlag, sound_bufferclamp ) ) // zderzaki uderzaja o siebie + { + if( TestFlag( mvOccupied->SoundFlag, sound_loud ) ) + dsbBufferClamp->SetVolume( DSBVOLUME_MAX ); + else + dsbBufferClamp->SetVolume( -20 ); + play_sound( dsbBufferClamp ); + } } if (dsbCouplerStretch) if (TestFlag(mvOccupied->SoundFlag, sound_couplerstretch)) // sprzegi sie rozciagaja @@ -4121,7 +4643,7 @@ bool TTrain::Update( double const Deltatime ) dsbCouplerStretch->SetVolume(DSBVOLUME_MAX); else dsbCouplerStretch->SetVolume(-20); - dsbCouplerStretch->Play(0, 0, 0); + play_sound( dsbCouplerStretch ); } if (mvOccupied->SoundFlag == 0) @@ -4358,19 +4880,16 @@ bool TTrain::Update( double const Deltatime ) { if (fabs(mvControlled->Im) > 10.0) btLampkaPoslizg.TurnOn(); - rsSlippery.Play(-rsSlippery.AM * veldiff + rsSlippery.AA, DSBPLAY_LOOPING, true, - DynamicObject->GetPosition()); - if (mvControlled->TrainType == - dt_181) // alarm przy poslizgu dla 181/182 - BOMBARDIER + rsSlippery.Play(-rsSlippery.AM * veldiff + rsSlippery.AA, DSBPLAY_LOOPING, true, DynamicObject->GetPosition()); + if (mvControlled->TrainType == dt_181) // alarm przy poslizgu dla 181/182 - BOMBARDIER if (dsbSlipAlarm) - dsbSlipAlarm->Play(0, 0, DSBPLAY_LOOPING); + play_sound( dsbSlipAlarm, DSBPLAY_LOOPING ); } else { if ((mvOccupied->UnitBrakeForce > 100.0) && (DynamicObject->GetVelocity() > 1.0)) { - rsSlippery.Play(rsSlippery.AM * veldiff + rsSlippery.AA, DSBPLAY_LOOPING, true, - DynamicObject->GetPosition()); + rsSlippery.Play(rsSlippery.AM * veldiff + rsSlippery.AA, DSBPLAY_LOOPING, true, DynamicObject->GetPosition()); if (mvControlled->TrainType == dt_181) if (dsbSlipAlarm) dsbSlipAlarm->Stop(); @@ -4446,8 +4965,7 @@ bool TTrain::Update( double const Deltatime ) else btLampkaBoczniki.TurnOff(); - btLampkaNapNastHam.Turn(mvControlled->ActiveDir != - 0); // napiecie na nastawniku hamulcowym + btLampkaNapNastHam.Turn(mvControlled->ActiveDir != 0); // napiecie na nastawniku hamulcowym btLampkaSprezarka.Turn(mvControlled->CompressorFlag); // mutopsitka dziala // boczniki unsigned char scp; // Ra: dopisałem "unsigned" @@ -4716,8 +5234,6 @@ bool TTrain::Update( double const Deltatime ) // ggBrakeCtrl.UpdateValue(double(mvOccupied->BrakeCtrlPos)); ggBrakeCtrl.UpdateValue(mvOccupied->fBrakeCtrlPos); ggBrakeCtrl.Update(); - - } if (ggLocalBrake.SubModel) { @@ -4774,12 +5290,16 @@ bool TTrain::Update( double const Deltatime ) // NBMX wrzesien 2003 - drzwi if (ggDoorLeftButton.SubModel) { - ggDoorLeftButton.PutValue(mvOccupied->DoorLeftOpened ? 1 : 0); +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + ggDoorLeftButton.PutValue( mvOccupied->DoorLeftOpened ? 1 : 0 ); +#endif ggDoorLeftButton.Update(); } if (ggDoorRightButton.SubModel) { - ggDoorRightButton.PutValue(mvOccupied->DoorRightOpened ? 1 : 0); +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + ggDoorRightButton.PutValue( mvOccupied->DoorRightOpened ? 1 : 0 ); +#endif ggDoorRightButton.Update(); } if (ggDepartureSignalButton.SubModel) @@ -4803,7 +5323,8 @@ bool TTrain::Update( double const Deltatime ) if (ggConverterOffButton.SubModel) ggConverterOffButton.Update(); - if (((DynamicObject->iLights[0]) == 0) && ((DynamicObject->iLights[1]) == 0)) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( ( ( DynamicObject->iLights[ 0 ] ) == 0 ) && ( ( DynamicObject->iLights[ 1 ] ) == 0 ) ) { ggRightLightButton.PutValue(0); ggLeftLightButton.PutValue(0); @@ -4813,7 +5334,6 @@ bool TTrain::Update( double const Deltatime ) } // hunter-230112 - // REFLEKTOR LEWY // glowne oswietlenie if ((DynamicObject->iLights[0] & 1) == 1) @@ -4944,6 +5464,7 @@ bool TTrain::Update( double const Deltatime ) else ggRearRightLightButton.PutValue(-1); } +#endif if (ggLightsButton.SubModel) { ggLightsButton.PutValue(mvOccupied->LightsPos - 1); @@ -4958,32 +5479,13 @@ bool TTrain::Update( double const Deltatime ) //--------- // Winger 010304 - pantografy // NOTE: shouldn't the pantograph updates check whether it's front or rear cabin? - if (ggPantFrontButton.SubModel ) - { - if( mvOccupied->PantSwitchType != "impulse" ) { - ggPantFrontButton.UpdateValue( - ( mvOccupied->ActiveCab == 1 ? - mvControlled->PantFrontUp : - mvControlled->PantRearUp ) ? - 1.0 : - 0.0 ); - } + if (ggPantFrontButton.SubModel ) { ggPantFrontButton.Update(); } - if (ggPantRearButton.SubModel) - { - if( mvOccupied->PantSwitchType != "impulse" ) { - ggPantRearButton.UpdateValue( - ( mvOccupied->ActiveCab == 1 ? - mvControlled->PantRearUp : - mvControlled->PantFrontUp ) ? - 1.0 : - 0.0 ); - } + if (ggPantRearButton.SubModel) { ggPantRearButton.Update(); } - if (ggPantFrontButtonOff.SubModel) - { + if (ggPantFrontButtonOff.SubModel) { ggPantFrontButtonOff.Update(); } // Winger 020304 - ogrzewanie @@ -5063,7 +5565,7 @@ bool TTrain::Update( double const Deltatime ) dsbBuzzer->GetStatus(&stat); if (!(stat & DSBSTATUS_PLAYING)) { - dsbBuzzer->Play(0, 0, DSBPLAY_LOOPING); + play_sound( dsbBuzzer, DSBVOLUME_MAX, DSBPLAY_LOOPING ); Console::BitsSet(1 << 14); // ustawienie bitu 16 na PoKeys } } @@ -5200,7 +5702,7 @@ bool TTrain::Update( double const Deltatime ) } } else */ - +#ifdef EU07_USE_OLD_COMMAND_SYSTEM //---------------- // hunter-131211: czuwak przeniesiony z OnKeyPress // hunter-091012: zrobiony test czuwaka @@ -5233,6 +5735,7 @@ bool TTrain::Update( double const Deltatime ) } CAflag = false; } +#endif /* if ( Console::Pressed(Global::Keys[k_Czuwak]) ) { @@ -5611,8 +6114,7 @@ bool TTrain::Update( double const Deltatime ) if ((mvOccupied->TrainType == dt_EZT) && (mvControlled->Mains) && (mvControlled->ActiveDir != 0)) { - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); + play_sound( dsbPneumaticSwitch ); } } @@ -5697,16 +6199,14 @@ bool TTrain::Update( double const Deltatime ) ggAntiSlipButton.UpdateValue(1); if (mvOccupied->SwitchEPBrake(1)) { - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); + play_sound( dsbPneumaticSwitch ); } } else { if (mvOccupied->SwitchEPBrake(0)) { - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); + play_sound( dsbPneumaticSwitch ); } } @@ -5743,8 +6243,7 @@ bool TTrain::Update( double const Deltatime ) if (ggNextCurrentButton.SubModel) { ggNextCurrentButton.UpdateValue(1); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); ShowNextCurrent = true; } } @@ -5757,8 +6256,7 @@ bool TTrain::Update( double const Deltatime ) { // Ra: było pod GLFW_KEY_F3 if ((mvOccupied->EpFuseSwitch(true))) { - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); + play_sound( dsbPneumaticSwitch ); } } } @@ -5770,8 +6268,7 @@ bool TTrain::Update( double const Deltatime ) { if ((mvOccupied->EpFuseSwitch(false))) { - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); + play_sound( dsbPneumaticSwitch ); } } } @@ -5785,8 +6282,7 @@ bool TTrain::Update( double const Deltatime ) if (ggNextCurrentButton.SubModel) { ggNextCurrentButton.UpdateValue(0); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); + play_sound( dsbSwitch ); ShowNextCurrent = false; } } @@ -5854,19 +6350,18 @@ bool TTrain::Update( double const Deltatime ) */ // if (fabs(DynamicObject->GetVelocity())>0.5) - if (FreeFlyModeFlag ? false : fTachoCount > maxtacho) - { - dsbHasler->GetStatus(&stat); - if (!(stat & DSBSTATUS_PLAYING)) - dsbHasler->Play(0, 0, DSBPLAY_LOOPING); - } - else - { - if (FreeFlyModeFlag ? true : fTachoCount < 1) - { - dsbHasler->GetStatus(&stat); - if (stat & DSBSTATUS_PLAYING) - dsbHasler->Stop(); + if( dsbHasler != nullptr ) { + if( ( false == FreeFlyModeFlag ) && ( fTachoCount > maxtacho ) ) { + dsbHasler->GetStatus( &stat ); + if( !( stat & DSBSTATUS_PLAYING ) ) + play_sound( dsbHasler, DSBVOLUME_MAX, DSBPLAY_LOOPING ); + } + else { + if( ( true == FreeFlyModeFlag ) || ( fTachoCount < 1 ) ) { + dsbHasler->GetStatus( &stat ); + if( stat & DSBSTATUS_PLAYING ) + dsbHasler->Stop(); + } } } @@ -5919,14 +6414,12 @@ bool TTrain::Update( double const Deltatime ) ggUniversal4Button.PermIncValue(dt); ggUniversal4Button.Update(); -/* +#ifdef EU07_USE_OLD_COMMAND_SYSTEM ggMainOffButton.UpdateValue(0); ggMainOnButton.UpdateValue(0); -*/ ggSecurityResetButton.UpdateValue(0); -/* ggReleaserButton.UpdateValue(0); -*/ +#endif ggSandButton.UpdateValue(0); ggAntiSlipButton.UpdateValue(0); ggDepartureSignalButton.UpdateValue(0); @@ -6473,8 +6966,8 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName) pyScreens.start(); if (DynamicObject->mdKabina) { - DynamicObject->mdKabina->Init(); // obrócenie modelu oraz optymalizacja, - // również zapisanie binarnego + DynamicObject->mdKabina->Init(); // obrócenie modelu oraz optymalizacja, również zapisanie binarnego + set_cab_controls(); return true; } return (token == "none"); @@ -6790,6 +7283,70 @@ void TTrain::clear_cab_controls() btHaslerCurrent.Clear(13); // prąd na silnikach do odbijania na haslerze } +// NOTE: we can get rid of this function once we have per-cab persistent state +void TTrain::set_cab_controls() { + + // switches + // pantographs + if( mvOccupied->PantSwitchType != "impulse" ) { + ggPantFrontButton.PutValue( + ( mvOccupied->ActiveCab == 1 ? + mvControlled->PantFrontUp : + mvControlled->PantRearUp ) ? + 1.0 : + 0.0 ); + } + + if( mvOccupied->PantSwitchType != "impulse" ) { + ggPantRearButton.PutValue( + ( mvOccupied->ActiveCab == 1 ? + mvControlled->PantRearUp : + mvControlled->PantFrontUp ) ? + 1.0 : + 0.0 ); + } + + // converter + if( mvOccupied->ConvSwitchType != "impulse" ) { + ggConverterButton.PutValue( + mvControlled->ConverterAllow ? + 1.0 : + 0.0 ); + } + + // compressor + if( true == mvControlled->CompressorAllow ) { + ggCompressorButton.PutValue( 1.0 ); + } + + // lights + int const lightsindex = + ( mvOccupied->ActiveCab == 1 ? + 0 : + 1 ); + + if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_left ) != 0 ) { + ggLeftLightButton.PutValue( 1.0 ); + } + if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_right ) != 0 ) { + ggRightLightButton.PutValue( 1.0 ); + } + if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_upper ) != 0 ) { + ggUpperLightButton.PutValue( 1.0 ); + } + if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_left ) != 0 ) { + ggLeftEndLightButton.PutValue( 1.0 ); + } + if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_right ) != 0 ) { + ggRightEndLightButton.PutValue( 1.0 ); + } + + // doors + // NOTE: we're relying on the cab models to have switches reversed for the rear cab(?) + ggDoorLeftButton.PutValue( mvOccupied->DoorLeftOpened ? 1.0 : 0.0 ); + ggDoorRightButton.PutValue( mvOccupied->DoorRightOpened ? 1.0 : 0.0 ); +} + // initializes a button matching provided label. returns: true if the label was found, false // otherwise // NOTE: this is temporary work-around for compiler else-if limit @@ -7534,20 +8091,28 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con } void -TTrain::play_sound( PSound Sound, PSound Fallbacksound ) { +TTrain::play_sound( PSound Sound, int const Volume, DWORD const Flags ) { if( Sound ) { Sound->SetCurrentPosition( 0 ); - Sound->SetVolume( DSBVOLUME_MAX ); - Sound->Play( 0, 0, 0 ); - return; - } - if( Fallbacksound ) { - - Fallbacksound->SetCurrentPosition( 0 ); - Fallbacksound->SetVolume( DSBVOLUME_MAX ); - Fallbacksound->Play( 0, 0, 0 ); + Sound->SetVolume( Volume ); + Sound->Play( 0, 0, Flags ); + return; + } +} + +void +TTrain::play_sound( PSound Sound, PSound Fallbacksound, int const Volume, DWORD const Flags ) { + + if( Sound ) { + + play_sound( Sound, Volume, Flags ); + return; + } + if( Fallbacksound ) { + + play_sound( Fallbacksound, Volume, Flags ); return; } } diff --git a/Train.h b/Train.h index 11366a7d..a14dacad 100644 --- a/Train.h +++ b/Train.h @@ -70,37 +70,32 @@ class TTrain bool InitializeCab(int NewCabNo, std::string const &asFileName); TTrain(); ~TTrain(); - // bool Init(TTrack *Track); // McZapkie-010302 bool Init(TDynamicObject *NewDynamicObject, bool e3d = false); void OnKeyDown(int cKey); void OnKeyUp(int cKey); - void OnCommand( command_data const &Command ); - // bool SHP() { fShpTimer= 0; }; - - inline vector3 GetDirection() - { - return DynamicObject->VectorFront(); - }; - inline vector3 GetUp() - { - return DynamicObject->VectorUp(); - }; + inline vector3 GetDirection() { return DynamicObject->VectorFront(); }; + inline vector3 GetUp() { return DynamicObject->VectorUp(); }; void UpdateMechPosition(double dt); vector3 GetWorldMechPosition(); bool Update( double const Deltatime ); bool m_updated = false; void MechStop(); void SetLights(); - // virtual bool RenderAlpha(); // McZapkie-310302: ladowanie parametrow z pliku bool LoadMMediaFile(std::string const &asFileName); PyObject *GetTrainState(); private: +// types + typedef void( *command_handler )( TTrain *Train, command_data const &Command ); + typedef std::unordered_map commandhandler_map; // clears state of all cabin controls void clear_cab_controls(); + // sets cabin controls based on current state of the vehicle + // NOTE: we can get rid of this function once we have per-cab persistent state + void set_cab_controls(); // initializes a gauge matching provided label. returns: true if the label was found, false // otherwise bool initialize_gauge(cParser &Parser, std::string const &Label, int const Cabindex); @@ -109,20 +104,67 @@ class TTrain bool initialize_button(cParser &Parser, std::string const &Label, int const Cabindex); // plays specified sound, or fallback sound if the primary sound isn't presend // NOTE: temporary routine until sound system is sorted out and paired with switches - void play_sound( PSound Sound, PSound Fallbacksound = nullptr ); + void play_sound( PSound Sound, int const Volume = DSBVOLUME_MAX, DWORD const Flags = 0 ); + void play_sound( PSound Sound, PSound Fallbacksound, int const Volume, DWORD const Flags ); + // helper, returns true for EMU with oerlikon brake + bool is_eztoer() 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_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 ); + static void OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data const &Command ); + static void OnCommand_secondcontrollerincrease( TTrain *Train, command_data const &Command ); + static void OnCommand_secondcontrollerincreasefast( TTrain *Train, command_data const &Command ); + static void OnCommand_secondcontrollerdecrease( TTrain *Train, command_data const &Command ); + static void OnCommand_secondcontrollerdecreasefast( TTrain *Train, command_data const &Command ); + static void OnCommand_independentbrakeincrease( TTrain *Train, command_data const &Command ); + static void OnCommand_independentbrakeincreasefast( TTrain *Train, command_data const &Command ); + static void OnCommand_independentbrakedecrease( TTrain *Train, command_data const &Command ); + static void OnCommand_independentbrakedecreasefast( TTrain *Train, command_data const &Command ); + static void OnCommand_independentbrakebailoff( TTrain *Train, command_data const &Command ); + static void OnCommand_trainbrakeincrease( TTrain *Train, command_data const &Command ); + static void OnCommand_trainbrakedecrease( TTrain *Train, command_data const &Command ); + static void OnCommand_trainbrakecharging( TTrain *Train, command_data const &Command ); + static void OnCommand_trainbrakerelease( TTrain *Train, command_data const &Command ); + 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_trainbrakeemergency( 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 ); + static void OnCommand_alerteracknowledge( TTrain *Train, command_data const &Command ); + static void OnCommand_batterytoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_pantographtogglefront( TTrain *Train, command_data const &Command ); + static void OnCommand_pantographtogglerear( TTrain *Train, command_data const &Command ); + static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_compressortoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_headlighttoggleleft( TTrain *Train, command_data const &Command ); + static void OnCommand_headlighttoggleright( TTrain *Train, command_data const &Command ); + static void OnCommand_headlighttoggleupper( TTrain *Train, command_data const &Command ); + static void OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &Command ); + static void OnCommand_redmarkertoggleright( TTrain *Train, command_data const &Command ); + static void OnCommand_headlighttogglerearleft( TTrain *Train, command_data const &Command ); + static void OnCommand_headlighttogglerearright( TTrain *Train, command_data const &Command ); + 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_doortoggleleft( TTrain *Train, command_data const &Command ); + static void OnCommand_doortoggleright( TTrain *Train, command_data const &Command ); - // helper variable, to prevent immediate switch between closing and opening line breaker circuit - bool m_linebreakerclosed{ false }; - - private: //żeby go nic z zewnątrz nie przestawiało +// members TDynamicObject *DynamicObject; // przestawia zmiana pojazdu [F5] - private: //żeby go nic z zewnątrz nie przestawiało TMoverParameters *mvControlled; // człon, w którym sterujemy silnikiem TMoverParameters *mvOccupied; // człon, w którym sterujemy hamulcem TMoverParameters *mvSecond; // drugi człon (ET40, ET41, ET42, ukrotnienia) TMoverParameters *mvThird; // trzeci człon (SN61) - public: // reszta może by?publiczna - // AnsiString asMessage; + // helper variable, to prevent immediate switch between closing and opening line breaker circuit + bool m_linebreakerclosed{ false }; + static const commandhandler_map m_commandhandlers; + +public: // reszta może by?publiczna // McZapkie: definicje wskaźników // Ra 2014-08: częsciowo przeniesione do tablicy w TCab @@ -220,7 +262,6 @@ class TTrain TGauge ggTrainHeatingButton; TGauge ggSignallingButton; TGauge ggDoorSignallingButton; - // TModel3d *mdKabina; McZapkie-030303: to do dynobj // TGauge ggDistCounter; //Ra 2014-07: licznik kilometrów // TGauge ggVelocityDgt; //i od razu prędkościomierz @@ -422,18 +463,9 @@ class TTrain public: float fPress[20][3]; // cisnienia dla wszystkich czlonow float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych - int RadioChannel() - { - return iRadioChannel; - }; - inline TDynamicObject *Dynamic() - { - return DynamicObject; - }; - inline TMoverParameters *Controlled() - { - return mvControlled; - }; + int RadioChannel() { return iRadioChannel; }; + inline TDynamicObject *Dynamic() { return DynamicObject; }; + inline TMoverParameters *Controlled() { return mvControlled; }; void DynamicSet(TDynamicObject *d); void Silence(); }; diff --git a/World.cpp b/World.cpp index d42f7cfd..5dc73095 100644 --- a/World.cpp +++ b/World.cpp @@ -1692,13 +1692,18 @@ TWorld::Update_UI() { // timetable TDynamicObject *tmp = ( FreeFlyModeFlag ? - Ground.DynamicNearest( Camera.Pos ) : - Controlled ); // w trybie latania lokalizujemy wg mapy + Ground.DynamicNearest( Camera.Pos ) : + Controlled ); // w trybie latania lokalizujemy wg mapy if( tmp == nullptr ) { break; } - if( tmp->Mechanik == nullptr ) { break; } + // if the nearest located vehicle doesn't have a direct driver, try to query its owner + auto const owner = ( + tmp->Mechanik != nullptr ? + tmp->Mechanik : + tmp->ctOwner ); + if( owner == nullptr ){ break; } - auto const table = tmp->Mechanik->Timetable(); + auto const table = owner->Timetable(); if( table == nullptr ) { break; } auto const &time = simulation::Time.data(); @@ -1711,14 +1716,12 @@ TWorld::Update_UI() { uitextline1 += " (paused)"; } - if( Controlled - && Controlled->Mechanik ) { - uitextline2 = Global::Bezogonkow( Controlled->Mechanik->Relation(), true ) + " (" + tmp->Mechanik->Timetable()->TrainName + ")"; - if( !uitextline2.empty() ) { - // jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania - uitextline3 = " -> " + Global::Bezogonkow( Controlled->Mechanik->NextStop(), true ); - } - } + uitextline2 = Global::Bezogonkow( owner->Relation(), true ) + " (" + owner->Timetable()->TrainName + ")"; + auto const nextstation = Global::Bezogonkow( owner->NextStop(), true ); + if( !nextstation.empty() ) { + // jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania + uitextline3 = " -> " + nextstation; + } if( Global::iScreenMode[ Global::iTextMode - GLFW_KEY_F1 ] == 1 ) { @@ -1731,7 +1734,7 @@ TWorld::Update_UI() { UITable->text_lines.emplace_back( "+----------------------------+-------+-------+-----+", Global::UITextColor ); TMTableLine *tableline; - for( int i = tmp->Mechanik->iStationStart; i <= std::min( tmp->Mechanik->iStationStart + 15, table->StationCount ); ++i ) { + for( int i = owner->iStationStart; i <= std::min( owner->iStationStart + 15, table->StationCount ); ++i ) { // wyświetlenie pozycji z rozkładu tableline = table->TimeTable + i; // linijka rozkładu @@ -1752,7 +1755,7 @@ TWorld::Update_UI() { UITable->text_lines.emplace_back( Global::Bezogonkow( "| " + station + " | " + arrival + " | " + departure + " | " + vmax + " | " + tableline->StationWare, true ), - ( ( tmp->Mechanik->iStationStart < table->StationIndex ) && ( i < table->StationIndex ) ? + ( ( owner->iStationStart < table->StationIndex ) && ( i < table->StationIndex ) ? float4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono Global::UITextColor ) ); diff --git a/command.cpp b/command.cpp index edbb388f..eccb31e9 100644 --- a/command.cpp +++ b/command.cpp @@ -91,6 +91,9 @@ const int k_Fuse = 26; const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; const int k_BrakeProfile = 31; +*/ + { user_command::alerteracknowledge, command_target::vehicle }, +/* const int k_Czuwak = 32; const int k_Horn = 33; const int k_Horn2 = 34; @@ -118,10 +121,10 @@ const int k_DeCouple = 45; const int k_ProgramQuit = 46; // const int k_ProgramPause= 47; const int k_ProgramHelp = 48; -const int k_OpenLeft = 49; -const int k_OpenRight = 50; -const int k_CloseLeft = 51; -const int k_CloseRight = 52; +*/ + { user_command::doortoggleleft, command_target::vehicle }, + { user_command::doortoggleright, command_target::vehicle }, +/* const int k_DepartureSignal = 53; */ { user_command::pantographtogglefront, command_target::vehicle }, @@ -129,9 +132,18 @@ const int k_DepartureSignal = 53; /* const int k_Heating = 58; // const int k_FreeFlyMode= 59; -const int k_LeftSign = 60; -const int k_UpperSign = 61; -const int k_RightSign = 62; +*/ + { user_command::headlighttoggleleft, command_target::vehicle }, + { user_command::headlighttoggleright, command_target::vehicle }, + { user_command::headlighttoggleupper, command_target::vehicle }, + { user_command::redmarkertoggleleft, command_target::vehicle }, + { user_command::redmarkertoggleright, command_target::vehicle }, + { user_command::headlighttogglerearleft, command_target::vehicle }, + { user_command::headlighttogglerearright, command_target::vehicle }, + { user_command::headlighttogglerearupper, command_target::vehicle }, + { user_command::redmarkertogglerearleft, command_target::vehicle }, + { user_command::redmarkertogglerearright, command_target::vehicle }, +/* const int k_SmallCompressor = 63; const int k_StLinOff = 64; const int k_CurrentNext = 65; @@ -189,6 +201,9 @@ const int k_Fuse = 26; const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; const int k_BrakeProfile = 31; +*/ + "alerteracknowledge", +/* const int k_Czuwak = 32; const int k_Horn = 33; const int k_Horn2 = 34; @@ -216,10 +231,10 @@ const int k_DeCouple = 45; const int k_ProgramQuit = 46; // const int k_ProgramPause= 47; const int k_ProgramHelp = 48; -const int k_OpenLeft = 49; -const int k_OpenRight = 50; -const int k_CloseLeft = 51; -const int k_CloseRight = 52; +*/ + "doortoggleleft", + "doortoggleright", +/* const int k_DepartureSignal = 53; */ "pantographtogglefront", @@ -227,9 +242,18 @@ const int k_DepartureSignal = 53; /* const int k_Heating = 58; // const int k_FreeFlyMode= 59; -const int k_LeftSign = 60; -const int k_UpperSign = 61; -const int k_RightSign = 62; +*/ + "headlighttoggleleft", + "headlighttoggleright", + "headlighttoggleupper", + "redmarkertoggleleft", + "redmarkertoggleright", + "headlighttogglerearleft", + "headlighttogglerearright", + "headlighttogglerearupper", + "redmarkertogglerearleft", + "redmarkertogglerearright", +/* const int k_SmallCompressor = 63; const int k_StLinOff = 64; const int k_CurrentNext = 65; @@ -258,8 +282,9 @@ command_relay::post( user_command const Command, std::uint64_t const Param1, std return; } if( ( lookup->second == command_target::vehicle ) - && ( true == FreeFlyModeFlag ) ) { - // don't pass vehicle commands if the user isn't in one + && ( true == FreeFlyModeFlag ) + && ( false == DebugModeFlag ) ) { + // don't pass vehicle commands if the user isn't in one, unless we're in debug mode return; } diff --git a/command.h b/command.h index 313cc5bf..67d9da3d 100644 --- a/command.h +++ b/command.h @@ -51,6 +51,9 @@ const int k_Fuse = 26; const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; const int k_BrakeProfile = 31; +*/ + alerteracknowledge, +/* const int k_Czuwak = 32; const int k_Horn = 33; const int k_Horn2 = 34; @@ -78,10 +81,10 @@ const int k_DeCouple = 45; const int k_ProgramQuit = 46; // const int k_ProgramPause= 47; const int k_ProgramHelp = 48; -const int k_OpenLeft = 49; -const int k_OpenRight = 50; -const int k_CloseLeft = 51; -const int k_CloseRight = 52; +*/ + doortoggleleft, + doortoggleright, +/* const int k_DepartureSignal = 53; */ pantographtogglefront, @@ -89,9 +92,18 @@ const int k_DepartureSignal = 53; /* const int k_Heating = 58; // const int k_FreeFlyMode= 59; -const int k_LeftSign = 60; -const int k_UpperSign = 61; -const int k_RightSign = 62; +*/ + headlighttoggleleft, + headlighttoggleright, + headlighttoggleupper, + redmarkertoggleleft, + redmarkertoggleright, + headlighttogglerearleft, + headlighttogglerearright, + headlighttogglerearupper, + redmarkertogglerearleft, + redmarkertogglerearright, + /* const int k_SmallCompressor = 63; const int k_StLinOff = 64; const int k_CurrentNext = 65; diff --git a/keyboardinput.cpp b/keyboardinput.cpp index 03f48a13..ebf3547f 100644 --- a/keyboardinput.cpp +++ b/keyboardinput.cpp @@ -130,7 +130,9 @@ const int k_Fuse = 26; const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; const int k_BrakeProfile = 31; -const int k_Czuwak = 32; +*/ + { "alerteracknowledge", command_target::vehicle, GLFW_KEY_SPACE }, +/* const int k_Horn = 33; const int k_Horn2 = 34; const int k_FailedEngineCutOff = 35; @@ -157,10 +159,10 @@ const int k_DeCouple = 45; const int k_ProgramQuit = 46; // const int k_ProgramPause= 47; const int k_ProgramHelp = 48; -const int k_OpenLeft = 49; -const int k_OpenRight = 50; -const int k_CloseLeft = 51; -const int k_CloseRight = 52; +*/ + { "doortoggleleft", command_target::vehicle, GLFW_KEY_COMMA }, + { "doortoggleright", command_target::vehicle, GLFW_KEY_PERIOD }, +/* const int k_DepartureSignal = 53; */ { "pantographtogglefront", command_target::vehicle, GLFW_KEY_P }, @@ -168,9 +170,18 @@ const int k_DepartureSignal = 53; /* const int k_Heating = 58; // const int k_FreeFlyMode= 59; -const int k_LeftSign = 60; -const int k_UpperSign = 61; -const int k_RightSign = 62; +*/ + { "headlighttoggleleft", command_target::vehicle, GLFW_KEY_Y }, + { "headlighttoggleright", command_target::vehicle, GLFW_KEY_I }, + { "headlighttoggleupper", command_target::vehicle, GLFW_KEY_U }, + { "redmarkertoggleleft", command_target::vehicle, GLFW_KEY_Y | keymodifier::shift }, + { "redmarkertoggleright", command_target::vehicle, GLFW_KEY_I | keymodifier::shift }, + { "headlighttogglerearleft", command_target::vehicle, GLFW_KEY_Y | keymodifier::control }, + { "headlighttogglerearright", command_target::vehicle, GLFW_KEY_I | keymodifier::control }, + { "headlighttogglerearupper", command_target::vehicle, GLFW_KEY_U | keymodifier::control }, + { "redmarkertogglerearleft", command_target::vehicle, GLFW_KEY_Y | keymodifier::control | keymodifier::shift }, + { "redmarkertogglerearright", command_target::vehicle, GLFW_KEY_I | keymodifier::control | keymodifier::shift }, +/* const int k_SmallCompressor = 63; const int k_StLinOff = 64; const int k_CurrentNext = 65; diff --git a/maszyna.vcxproj.filters b/maszyna.vcxproj.filters index 56dc3ce8..dc09e535 100644 --- a/maszyna.vcxproj.filters +++ b/maszyna.vcxproj.filters @@ -220,7 +220,7 @@ Source Files\input - Source Files + Source Files\input @@ -429,7 +429,7 @@ Header Files\input - Header Files + Header Files\input diff --git a/renderer.cpp b/renderer.cpp index a0a2a24e..8c66ff86 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -282,7 +282,7 @@ bool opengl_renderer::Render( TGround *Ground ) { glDisable( GL_BLEND ); - glAlphaFunc( GL_GREATER, 0.45f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f + glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f glEnable( GL_LIGHTING ); glColor3f( 1.0f, 1.0f, 1.0f ); diff --git a/stdafx.h b/stdafx.h index 1e060f74..4cd20a12 100644 --- a/stdafx.h +++ b/stdafx.h @@ -25,6 +25,7 @@ #include #undef NOMINMAX #include +#include #endif // stl #include From 57c213fd1dd4ce863fc41c136e428c3329d90425 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Fri, 14 Apr 2017 15:17:32 +0200 Subject: [PATCH 05/12] overload relay control, generic brake handles sound fix --- McZapkie/Mover.cpp | 21 ++++-- RealSound.h | 1 + Train.cpp | 156 +++++++++++++++++++++++++++++++-------------- Train.h | 1 + command.cpp | 11 ++-- command.h | 6 +- gamepadinput.cpp | 58 ++++++++++++++--- keyboardinput.cpp | 6 +- 8 files changed, 189 insertions(+), 71 deletions(-) diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index debab692..a9a76bdd 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -676,10 +676,23 @@ bool TMoverParameters::CurrentSwitch(int direction) if (TrainType != dt_EZT) return (MinCurrentSwitch(direction != 0)); } - if (EngineType == DieselEngine) // dla 2Ls150 - if (ShuntModeAllow) - if (ActiveDir == 0) // przed ustawieniem kierunku - ShuntMode = ( direction != 0 ); + // TBD, TODO: split off shunt mode toggle into a separate command? It doesn't make much sense to have these two together like that + // dla 2Ls150 + if( ( EngineType == DieselEngine ) + && ( true == ShuntModeAllow ) + && ( ActiveDir == 0 ) ) { + // przed ustawieniem kierunku + ShuntMode = ( direction != 0 ); + return true; + } + // for SM42/SP42 + if( ( EngineType == DieselElectric ) + && ( true == ShuntModeAllow ) + && ( MainCtrlPos == 0 ) ) { + ShuntMode = ( direction != 0 ); + return true; + } + return false; }; diff --git a/RealSound.h b/RealSound.h index e2312051..1eec3761 100644 --- a/RealSound.h +++ b/RealSound.h @@ -48,6 +48,7 @@ class TRealSound int GetStatus(); void ResetPosition(); // void FreqReset(float f=22050.0) {fFrequency=f;}; + bool Empty() { return ( pSound == nullptr ); } }; class TTextSound : public TRealSound diff --git a/Train.cpp b/Train.cpp index d17783b0..1b5b20ed 100644 --- a/Train.cpp +++ b/Train.cpp @@ -165,6 +165,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle }, { user_command::convertertoggle, &TTrain::OnCommand_convertertoggle }, { user_command::compressortoggle, &TTrain::OnCommand_compressortoggle }, + { user_command::motoroverloadrelaythresholdtoggle, &TTrain::OnCommand_motoroverloadrelaythresholdtoggle }, { user_command::headlighttoggleleft, &TTrain::OnCommand_headlighttoggleleft }, { user_command::headlighttoggleright, &TTrain::OnCommand_headlighttoggleright }, { user_command::headlighttoggleupper, &TTrain::OnCommand_headlighttoggleupper }, @@ -639,14 +640,14 @@ void TTrain::OnCommand_trainbrakeincrease( TTrain *Train, command_data const &Co void TTrain::OnCommand_trainbrakedecrease( TTrain *Train, command_data const &Command ) { if( Command.action != GLFW_RELEASE ) { - + // press or hold if( Train->mvOccupied->BrakeHandle == FV4a ) { Train->mvOccupied->BrakeLevelAdd( -0.1 /*-15.0 * Command.time_delta*/ ); } else { // nową wersję dostarczył ZiomalCl ("fixed looped sound in ezt when using NUM_9 key") if( ( Train->mvOccupied->BrakeCtrlPos > -1 ) - || ( Train->keybrakecount > 1 ) ) { + || ( Train->keybrakecount > 1 ) ) { if( ( Train->is_eztoer() ) && ( Train->mvControlled->Mains ) @@ -661,12 +662,29 @@ void TTrain::OnCommand_trainbrakedecrease( TTrain *Train, command_data const &Co // koniec wersji dostarczonej przez ZiomalCl } } + else { + // release + if( ( Train->mvOccupied->BrakeCtrlPos == -1 ) + && ( Train->mvOccupied->BrakeHandle == FVel6 ) + && ( Train->DynamicObject->Controller != AIdriver ) + && ( Global::iFeedbackMode != 4 ) + && ( !( Global::bMWDmasterEnable && Global::bMWDBreakEnable ) ) ) { + // Odskakiwanie hamulce EP + Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->BrakeCtrlPos + 1 ); + Train->keybrakecount = 0; + if( ( Train->mvOccupied->TrainType == dt_EZT ) + && ( Train->mvControlled->Mains ) + && ( Train->mvControlled->ActiveDir != 0 ) ) { + Train->play_sound( Train->dsbPneumaticSwitch ); + } + } + } } void TTrain::OnCommand_trainbrakecharging( TTrain *Train, command_data const &Command ) { if( Command.action != GLFW_RELEASE ) { - + // press or hold // sound feedback if( ( Train->is_eztoer() ) && ( Train->mvControlled->Mains ) @@ -676,6 +694,23 @@ void TTrain::OnCommand_trainbrakecharging( TTrain *Train, command_data const &Co Train->mvOccupied->BrakeLevelSet( -1 ); } + else { + // release + if( ( Train->mvOccupied->BrakeCtrlPos == -1 ) + && ( Train->mvOccupied->BrakeHandle == FVel6 ) + && ( Train->DynamicObject->Controller != AIdriver ) + && ( Global::iFeedbackMode != 4 ) + && ( !( Global::bMWDmasterEnable && Global::bMWDBreakEnable ) ) ) { + // Odskakiwanie hamulce EP + Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->BrakeCtrlPos + 1 ); + Train->keybrakecount = 0; + if( ( Train->mvOccupied->TrainType == dt_EZT ) + && ( Train->mvControlled->Mains ) + && ( Train->mvControlled->ActiveDir != 0 ) ) { + Train->play_sound( Train->dsbPneumaticSwitch ); + } + } + } } void TTrain::OnCommand_trainbrakerelease( TTrain *Train, command_data const &Command ) { @@ -1330,6 +1365,35 @@ void TTrain::OnCommand_compressortoggle( TTrain *Train, command_data const &Comm */ } +void TTrain::OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command ) { + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( Train->mvControlled->Imax < Train->mvControlled->ImaxHi ) { + // turn on + if( true == Train->mvControlled->CurrentSwitch( true ) ) { + // visual feedback + Train->ggMaxCurrentCtrl.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggMaxCurrentCtrl.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } + else { + //turn off + if( true == Train->mvControlled->CurrentSwitch( false ) ) { + // visual feedback + Train->ggMaxCurrentCtrl.UpdateValue( 0.0 ); + // sound feedback + if( Train->ggMaxCurrentCtrl.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + } + } +} + void TTrain::OnCommand_headlighttoggleleft( TTrain *Train, command_data const &Command ) { if( Train->mvOccupied->LightsPosNo > 0 ) { @@ -2084,9 +2148,9 @@ void TTrain::OnKeyDown(int cKey) DynamicObject->Mechanik->TakeControl(true); } } - else if (cKey == Global::Keys[k_MaxCurrent]) // McZapkie-160502: F - - // wysoki rozruch - { +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + else if (cKey == Global::Keys[k_MaxCurrent]) { + // McZapkie-160502: F - wysoki rozruch if ((mvControlled->EngineType == DieselElectric) && (mvControlled->ShuntModeAllow) && (mvControlled->MainCtrlPos == 0)) { @@ -2096,28 +2160,17 @@ void TTrain::OnKeyDown(int cKey) { play_sound( dsbSwitch ); } - /* Ra: przeniesione do Mover.cpp - if (mvControlled->TrainType!=dt_EZT) //to powinno być w fizyce, a - nie w kabinie! - if (mvControlled->MinCurrentSwitch(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0,0,0); - } - */ } - else if (cKey == Global::Keys[k_CurrentAutoRelay]) // McZapkie-241002: G - - // wlaczanie PSR - { +#endif + else if (cKey == Global::Keys[k_CurrentAutoRelay]) { + // McZapkie-241002: G - wlaczanie PSR if (mvControlled->AutoRelaySwitch(true)) { play_sound( dsbSwitch ); } } - else if (cKey == Global::Keys[k_FailedEngineCutOff]) // McZapkie-060103: E - // - wylaczanie - // sekcji silnikow - { + else if (cKey == Global::Keys[k_FailedEngineCutOff]) { + // McZapkie-060103: E - wylaczanie sekcji silnikow if (mvControlled->CutOffEngine()) { play_sound( dsbSwitch ); @@ -3084,7 +3137,8 @@ void TTrain::OnKeyDown(int cKey) if (DynamicObject->Mechanik) DynamicObject->Mechanik->TakeControl(false); } - else if (cKey == Global::Keys[k_MaxCurrent]) // McZapkie-160502: f - niski rozruch +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + else if( cKey == Global::Keys[ k_MaxCurrent ] ) // McZapkie-160502: f - niski rozruch { if ((mvControlled->EngineType == DieselElectric) && (mvControlled->ShuntModeAllow) && (mvControlled->MainCtrlPos == 0)) @@ -3095,15 +3149,8 @@ void TTrain::OnKeyDown(int cKey) { play_sound( dsbSwitch ); } - /* Ra: przeniesione do Mover.cpp - if (mvControlled->TrainType!=dt_EZT) - if (mvControlled->MinCurrentSwitch(false)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0,0,0); - } - */ } +#endif else if (cKey == Global::Keys[k_CurrentAutoRelay]) // McZapkie-241002: g - // wylaczanie PSR { @@ -4351,7 +4398,7 @@ bool TTrain::Update( double const Deltatime ) fPPress = (1 * fPPress + mvOccupied->Handle->GetSound(s_fv4a_b)) / (2); if (fPPress > 0) { - vol = 2 * rsHiss.AM * fPPress; + vol = 2.0 * rsHiss.AM * fPPress; } if (vol > 0.001) { @@ -4402,7 +4449,7 @@ bool TTrain::Update( double const Deltatime ) rsHissX.Stop(); } } - if (rsHissT.AM != 0) // upuszczanie z czasowego + if (rsHissT.AM != 0) // upuszczanie z czasowego { vol = mvOccupied->Handle->GetSound(s_fv4a_t) * rsHissT.AM; if (vol > 0.001) @@ -4418,13 +4465,12 @@ bool TTrain::Update( double const Deltatime ) } // koniec FV4a else // jesli nie FV4a { - if (rsHiss.AM != 0) // upuszczanie z PG + if (rsHiss.AM != 0.0) // upuszczanie z PG { - fPPress = (4 * fPPress + Max0R(mvOccupied->dpLocalValve, mvOccupied->dpMainValve)) / - (4 + 1); - if (fPPress > 0) + fPPress = (4.0f * fPPress + std::max(mvOccupied->dpLocalValve, mvOccupied->dpMainValve)) / (4.0f + 1.0f); + if (fPPress > 0.0f) { - vol = 2 * rsHiss.AM * fPPress * 0.01; + vol = 2.0 * rsHiss.AM * fPPress; } if (vol > 0.01) { @@ -4435,13 +4481,12 @@ bool TTrain::Update( double const Deltatime ) rsHiss.Stop(); } } - if (rsHissU.AM != 0) // napelnianie PG + if (rsHissU.AM != 0.0) // napelnianie PG { - fNPress = (4 * fNPress + Min0R(mvOccupied->dpLocalValve, mvOccupied->dpMainValve)) / - (4 + 1); - if (fNPress < 0) + fNPress = (4.0f * fNPress + Min0R(mvOccupied->dpLocalValve, mvOccupied->dpMainValve)) / (4.0f + 1.0f); + if (fNPress < 0.0f) { - vol = -2 * rsHissU.AM * fNPress * 0.004; + vol = -1.0 * rsHissU.AM * fNPress; } if (vol > 0.01) { @@ -4956,7 +5001,8 @@ bool TTrain::Update( double const Deltatime ) mvControlled->ResistorsFlagCheck()); //------- - btLampkaWysRozr.Turn(mvControlled->Imax == mvControlled->ImaxHi); + btLampkaWysRozr.Turn(!(mvControlled->Imax < mvControlled->ImaxHi)); + if (((mvControlled->ScndCtrlActualPos > 0) || ((mvControlled->RList[mvControlled->MainCtrlActualPos].ScndAct != 0) && (mvControlled->RList[mvControlled->MainCtrlActualPos].ScndAct != 255))) && @@ -5283,7 +5329,9 @@ bool TTrain::Update( double const Deltatime ) if (ggMaxCurrentCtrl.SubModel) { - ggMaxCurrentCtrl.UpdateValue(double(mvControlled->Imax == mvControlled->ImaxHi)); +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + ggMaxCurrentCtrl.UpdateValue( double( mvControlled->Imax == mvControlled->ImaxHi ) ); +#endif ggMaxCurrentCtrl.Update(); } @@ -6101,6 +6149,7 @@ bool TTrain::Update( double const Deltatime ) } } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM // Odskakiwanie hamulce EP if ((!Console::Pressed(Global::Keys[k_DecBrakeLevel])) && (!Console::Pressed(Global::Keys[k_WaveBrake])) && (mvOccupied->BrakeCtrlPos == -1) && @@ -6117,7 +6166,10 @@ bool TTrain::Update( double const Deltatime ) play_sound( dsbPneumaticSwitch ); } } - +#endif +/* + // NOTE: disabled, as it doesn't seem to be used. + // TODO: get rid of it altogether when we're cleaninng // Ra: przeklejka z SPKS - płynne poruszanie hamulcem // if // ((mvOccupied->BrakeHandle==FV4a)&&(Console::Pressed(Global::Keys[k_IncBrakeLevel]))) @@ -6151,7 +6203,7 @@ bool TTrain::Update( double const Deltatime ) // mvOccupied->BrakeLevelAdd(mvOccupied->fBrakeCtrlPos<-1?0:-dt*2); } } - +*/ if ((mvOccupied->BrakeHandle == FV4a) && (Console::Pressed(Global::Keys[k_IncBrakeLevel]))) { if (Global::ctrlState) @@ -7287,6 +7339,11 @@ void TTrain::clear_cab_controls() void TTrain::set_cab_controls() { // switches + // battery + if( true == mvOccupied->Battery ) { + ggBatteryButton.PutValue( 1.0 ); + } + // pantographs if( mvOccupied->PantSwitchType != "impulse" ) { ggPantFrontButton.PutValue( @@ -7319,6 +7376,11 @@ void TTrain::set_cab_controls() { ggCompressorButton.PutValue( 1.0 ); } + // motor overload relay threshold / shunt mode + if( mvControlled->Imax == mvControlled->ImaxHi ) { + ggMaxCurrentCtrl.PutValue( 1.0 ); + } + // lights int const lightsindex = ( mvOccupied->ActiveCab == 1 ? diff --git a/Train.h b/Train.h index a14dacad..5c5b7be1 100644 --- a/Train.h +++ b/Train.h @@ -141,6 +141,7 @@ class TTrain static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ); static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command ); static void OnCommand_compressortoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttoggleleft( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttoggleright( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttoggleupper( TTrain *Train, command_data const &Command ); diff --git a/command.cpp b/command.cpp index eccb31e9..576580e7 100644 --- a/command.cpp +++ b/command.cpp @@ -79,16 +79,16 @@ command_relay::command_relay() { const int k_AntiSlipping = 21; const int k_Sand = 22; */ - { user_command::linebreakertoggle, command_target::vehicle }, { user_command::reverserincrease, command_target::vehicle }, { user_command::reverserdecrease, command_target::vehicle }, + { user_command::linebreakertoggle, command_target::vehicle }, /* const int k_Fuse = 26; */ - { user_command::compressortoggle, command_target::vehicle }, { user_command::convertertoggle, command_target::vehicle }, + { user_command::compressortoggle, command_target::vehicle }, + { user_command::motoroverloadrelaythresholdtoggle, command_target::vehicle }, /* -const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; const int k_BrakeProfile = 31; */ @@ -189,14 +189,15 @@ int const k_DimHeadlights = 74; const int k_AntiSlipping = 21; const int k_Sand = 22; */ - "linebreakertoggle", "reverserincrease", "reverserdecrease", + "linebreakertoggle", /* const int k_Fuse = 26; */ - "compressortoggle", "convertertoggle", + "compressortoggle", + "motoroverloadrelaythresholdtoggle", /* const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; diff --git a/command.h b/command.h index 67d9da3d..6a92b86d 100644 --- a/command.h +++ b/command.h @@ -39,14 +39,15 @@ enum class user_command { const int k_AntiSlipping = 21; const int k_Sand = 22; */ - linebreakertoggle, reverserincrease, reverserdecrease, + linebreakertoggle, /* const int k_Fuse = 26; */ - compressortoggle, convertertoggle, + compressortoggle, + motoroverloadrelaythresholdtoggle, /* const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; @@ -54,7 +55,6 @@ const int k_BrakeProfile = 31; */ alerteracknowledge, /* -const int k_Czuwak = 32; const int k_Horn = 33; const int k_Horn2 = 34; const int k_FailedEngineCutOff = 35; diff --git a/gamepadinput.cpp b/gamepadinput.cpp index 3240b3cd..7b756e14 100644 --- a/gamepadinput.cpp +++ b/gamepadinput.cpp @@ -87,6 +87,11 @@ gamepad_input::init() { void gamepad_input::poll() { + if( m_deviceid == -1 ) { + // if there's no gamepad we can skip the rest + return; + } + int count; std::size_t idx = 0; // poll button state auto const buttons = glfwGetJoystickButtons( m_deviceid, &count ); @@ -98,8 +103,8 @@ gamepad_input::poll() { on_button( static_cast( idx ), ( buttons[ idx ] == 1 ? - GLFW_PRESS : - GLFW_RELEASE ) ); + GLFW_PRESS : + GLFW_RELEASE ) ); } else { // otherwise we only pass info about button being held down @@ -115,10 +120,6 @@ gamepad_input::poll() { } } - if( m_deviceid == -1 ) { - // if there's no gamepad we can skip the rest - return; - } // poll axes state idx = 0; glm::vec2 leftstick, rightstick, triggers; @@ -167,7 +168,8 @@ gamepad_input::on_button( gamepad_button const Button, int const Action ) { case gamepad_button::y: { if( Action == GLFW_RELEASE ) { - // if the button was released the stick controls movement + // TODO: send GLFW_RELEASE for whatever command could be issued by the mode active until now + // if the button was released the stick switches to control the movement m_mode = control_mode::entity; // zero the stick and the accumulator so the input won't bleed between modes m_leftstick = glm::vec2(); @@ -275,11 +277,20 @@ gamepad_input::process_mode( float const Value, std::uint16_t const Recipient ) if( Value >= 0.0f ) { if( m_modeaccumulator < 0.0f ) { // reset accumulator if we're going in the other direction i.e. issuing opposite control + // this also means we should indicate the previous command no longer applies + // (normally it's handled when the stick enters dead zone, but it's possible there's no actual dead zone) + m_relay.post( + lookup.second, + 0, 0, + GLFW_RELEASE, + Recipient ); m_modeaccumulator = 0.0f; } if( Value > m_deadzone ) { m_modeaccumulator += ( Value - m_deadzone ) / ( 1.0 - m_deadzone ) * deltatime; - while( m_modeaccumulator >= 1.0f ) { + // we're making sure there's always a positive charge left in the accumulator, + // to more reliably decect when the stick goes from active to dead zone, below + while( m_modeaccumulator > 1.0f ) { // send commands if the accumulator(s) was filled m_relay.post( lookup.first, @@ -289,15 +300,34 @@ gamepad_input::process_mode( float const Value, std::uint16_t const Recipient ) m_modeaccumulator -= 1.0f; } } + else { + // if the accumulator isn't empty it's an indicator the stick moved from active to neutral zone + // indicate it with proper RELEASE command + m_relay.post( + lookup.first, + 0, 0, + GLFW_RELEASE, + Recipient ); + m_modeaccumulator = 0.0f; + } } else { if( m_modeaccumulator > 0.0f ) { // reset accumulator if we're going in the other direction i.e. issuing opposite control + // this also means we should indicate the previous command no longer applies + // (normally it's handled when the stick enters dead zone, but it's possible there's no actual dead zone) + m_relay.post( + lookup.first, + 0, 0, + GLFW_RELEASE, + Recipient ); m_modeaccumulator = 0.0f; } if( Value < m_deadzone ) { m_modeaccumulator += ( Value + m_deadzone ) / ( 1.0 - m_deadzone ) * deltatime; - while( m_modeaccumulator <= -1.0f ) { + // we're making sure there's always a negative charge left in the accumulator, + // to more reliably decect when the stick goes from active to dead zone, below + while( m_modeaccumulator < -1.0f ) { // send commands if the accumulator(s) was filled m_relay.post( lookup.second, @@ -307,6 +337,16 @@ gamepad_input::process_mode( float const Value, std::uint16_t const Recipient ) m_modeaccumulator += 1.0f; } } + else { + // if the accumulator isn't empty it's an indicator the stick moved from active to neutral zone + // indicate it with proper RELEASE command + m_relay.post( + lookup.second, + 0, 0, + GLFW_RELEASE, + Recipient ); + m_modeaccumulator = 0.0f; + } } } diff --git a/keyboardinput.cpp b/keyboardinput.cpp index ebf3547f..a2c148eb 100644 --- a/keyboardinput.cpp +++ b/keyboardinput.cpp @@ -118,16 +118,16 @@ keyboard_input::default_bindings() { const int k_AntiSlipping = 21; const int k_Sand = 22; */ - { "linebreakertoggle", command_target::vehicle, GLFW_KEY_M }, { "reverserincrease", command_target::vehicle, GLFW_KEY_D }, { "reverserdecrease", command_target::vehicle, GLFW_KEY_R }, + { "linebreakertoggle", command_target::vehicle, GLFW_KEY_M }, /* const int k_Fuse = 26; */ - { "compressortoggle", command_target::vehicle, GLFW_KEY_C }, { "convertertoggle", command_target::vehicle, GLFW_KEY_X }, + { "compressortoggle", command_target::vehicle, GLFW_KEY_C }, + { "motoroverloadrelaythresholdtoggle", command_target::vehicle, GLFW_KEY_F }, /* -const int k_MaxCurrent = 29; const int k_CurrentAutoRelay = 30; const int k_BrakeProfile = 31; */ From 2fd7bc5a935ad6559de7760a758506214c0ae561 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sun, 16 Apr 2017 17:22:56 +0200 Subject: [PATCH 06/12] control for e-p brake system, brake acting speed, departure signal, heating, door lock. Support for rear pantograph lowering button, all pantographs lowering button. Increased recognition of converter as a valid low voltage power source. --- Button.cpp | 3 + DynObj.cpp | 27 +- Gauge.cpp | 7 +- Globals.cpp | 1 + Globals.h | 6 +- McZapkie/Mover.cpp | 91 +++-- McZapkie/hamulce.h | 1 - Model3d.cpp | 14 +- Model3d.h | 4 +- Timer.cpp | 31 +- Train.cpp | 721 +++++++++++++++++++++++++++++++--------- Train.h | 9 + command.cpp | 356 +++++++------------- command.h | 35 +- keyboardinput.cpp | 193 +++++++---- keyboardinput.h | 2 - lightarray.cpp | 4 +- maszyna.vcxproj.filters | 8 +- 18 files changed, 927 insertions(+), 586 deletions(-) diff --git a/Button.cpp b/Button.cpp index 77016856..b6ed1d3f 100644 --- a/Button.cpp +++ b/Button.cpp @@ -10,6 +10,7 @@ http://mozilla.org/MPL/2.0/. #include "stdafx.h" #include "Button.h" #include "Console.h" +#include "logs.h" //--------------------------------------------------------------------------- @@ -57,6 +58,8 @@ void TButton::Load(cParser &Parser, TModel3d *pModel1, TModel3d *pModel2) { pModelOn = NULL; pModelOff = NULL; + + ErrorLog( "Failed to locate sub-model \"" + token + "\" in 3d model \"" + pModel1->NameGet() + "\"" ); } }; diff --git a/DynObj.cpp b/DynObj.cpp index d25a37af..3ab622d3 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -798,7 +798,7 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist) btnOn = true; } // else btCPass2.TurnOff(); - if (MoverParameters->Battery) + if( ( true == MoverParameters->Battery ) || ( true == MoverParameters->ConverterFlag ) ) { // sygnaly konca pociagu if (btEndSignals1.Active()) { @@ -900,10 +900,9 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist) // Ra: przechyłkę załatwiamy na etapie przesuwania modelu // if (ObjSqrDist<80000) ABuModelRoll(); //przechyłki od 400m } - if (MoverParameters->Battery) - { // sygnały czoła pociagu //Ra: wyświetlamy bez - // ograniczeń odległości, by były widoczne z - // daleka + if( ( true == MoverParameters->Battery ) || ( true == MoverParameters->ConverterFlag ) ) { + // sygnały czoła pociagu + //Ra: wyświetlamy bez ograniczeń odległości, by były widoczne z daleka if (TestFlag(iLights[0], 1)) { btHeadSignals11.TurnOn(); @@ -986,11 +985,8 @@ TDynamicObject * TDynamicObject::ABuFindNearestObject(TTrack *Track, TDynamicObj return nullptr; } -TDynamicObject * TDynamicObject::ABuScanNearestObject(TTrack *Track, double ScanDir, - double ScanDist, int &CouplNr) -{ // skanowanie toru w poszukiwaniu obiektu najblizszego - // kamerze - // double MyScanDir=ScanDir; //Moja orientacja na torze. //Ra: nie używane +TDynamicObject * TDynamicObject::ABuScanNearestObject(TTrack *Track, double ScanDir, double ScanDist, int &CouplNr) +{ // skanowanie toru w poszukiwaniu obiektu najblizszego kamerze if (ABuGetDirection() < 0) ScanDir = -ScanDir; TDynamicObject *FoundedObj; @@ -2914,11 +2910,12 @@ bool TDynamicObject::Update(double dt, double dt1) // fragment "z EXE Kursa" if (MoverParameters->Mains) // nie wchodzić w funkcję bez potrzeby - if ((!MoverParameters->Battery) && (Controller == Humandriver) && - (MoverParameters->EngineType != DieselEngine) && - (MoverParameters->EngineType != WheelsDriven)) - { // jeśli bateria wyłączona, a nie diesel ani drezyna - // reczna + if ( ( false == MoverParameters->Battery) + && ( false == MoverParameters->ConverterFlag ) // added alternative power source. TODO: more generic power check + && ( Controller == Humandriver) + && ( MoverParameters->EngineType != DieselEngine ) + && ( MoverParameters->EngineType != WheelsDriven ) ) + { // jeśli bateria wyłączona, a nie diesel ani drezyna reczna if (MoverParameters->MainSwitch(false)) // wyłączyć zasilanie MoverParameters->EventFlag = true; } diff --git a/Gauge.cpp b/Gauge.cpp index 99b424a0..85ff23c6 100644 --- a/Gauge.cpp +++ b/Gauge.cpp @@ -15,9 +15,10 @@ http://mozilla.org/MPL/2.0/. #include "stdafx.h" #include "Gauge.h" -#include "Timer.h" #include "parser.h" #include "Model3d.h" +#include "Timer.h" +#include "logs.h" TGauge::TGauge() { @@ -90,6 +91,10 @@ bool TGauge::Load(cParser &Parser, TModel3d *md1, TModel3d *md2, double mul) md2 = NULL; // informacja, że znaleziony else if (md2) // a jest podany drugi model (np. zewnętrzny) sm = md2->GetFromName(str1.c_str()); // to może tam będzie, co za różnica gdzie + if( sm == nullptr ) { + ErrorLog( "Failed to locate sub-model \"" + str1 + "\" in 3d model \"" + md1->NameGet() + "\"" ); + } + if (str2 == "mov") Init(sm, gt_Move, val3, val4, val5); else if (str2 == "wip") diff --git a/Globals.cpp b/Globals.cpp index e5cd1de9..afd6a465 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -107,6 +107,7 @@ int Global::iHiddenEvents = 1; // czy łączyć eventy z torami poprzez nazwę t // parametry użytkowe (jak komu pasuje) int Global::Keys[MaxKeys]; +bool Global::RealisticControlMode{ false }; int Global::iWindowWidth = 800; int Global::iWindowHeight = 600; float Global::fDistanceFactor = Global::ScreenHeight / 768.0; // baza do przeliczania odległości dla LoD diff --git a/Globals.h b/Globals.h index d2d48623..ee866146 100644 --- a/Globals.h +++ b/Globals.h @@ -166,6 +166,7 @@ class Global public: // double Global::tSinceStart; static int Keys[MaxKeys]; + static bool RealisticControlMode; // controls ability to steer the vehicle from outside views static Math3D::vector3 pCameraPosition; // pozycja kamery w świecie static double pCameraRotation; // kierunek bezwzględny kamery w świecie: 0=północ, 90°=zachód (-azymut) @@ -207,10 +208,7 @@ class Global static std::string asHumanCtrlVehicle; static void LoadIniFile(std::string asFileName); static void InitKeys(); - inline static Math3D::vector3 GetCameraPosition() - { - return pCameraPosition; - }; + inline static Math3D::vector3 GetCameraPosition() { return pCameraPosition; }; static void SetCameraPosition(Math3D::vector3 pNewCameraPosition); static void SetCameraRotation(double Yaw); static int iWriteLogEnabled; // maska bitowa: 1-zapis do pliku, 2-okienko diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index a9a76bdd..9e7b5d7c 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -4956,48 +4956,37 @@ bool TMoverParameters::AutoRelayCheck(void) // ************************************************************************************************* // Q: 20160713 -// Podnosi / opuszcza przedni pantograf +// Podnosi / opuszcza przedni pantograf. Returns: state of the pantograph after the operation // ************************************************************************************************* bool TMoverParameters::PantFront(bool State) { - double pf1 = 0; - bool PF = false; + if( ( true == Battery ) + || ( true == ConverterFlag ) ) { - if ((Battery == - true) /* and ((TrainType<>dt_ET40)or ((TrainType=dt_ET40) and (EnginePowerSource.CollectorsNo>1)))*/) - { - PF = true; - if (State == true) - pf1 = 1; - else - pf1 = 0; - if (PantFrontUp != State) - { + if( PantFrontUp != State ) { PantFrontUp = State; - if (State == true) - { + if( State == true ) { PantFrontStart = 0; - SendCtrlToNext("PantFront", 1, CabNo); + SendCtrlToNext( "PantFront", 1, CabNo ); } - else - { - PF = false; + else { PantFrontStart = 1; - SendCtrlToNext("PantFront", 0, CabNo); - //{Ra: nie ma potrzeby opuszczać obydwu na raz, jak mozemy każdy osobno - // if (TrainType == dt_EZT) && (ActiveCab == 1) - // { - // PantRearUp = false; - // PantRearStart = 1; - // SendCtrlToNext("PantRear", 0, CabNo); - // } - //} + SendCtrlToNext( "PantFront", 0, CabNo ); } } - else - SendCtrlToNext("PantFront", pf1, CabNo); } - return PF; + else { + // no power, drop the pantograph + // NOTE: this is a simplification as it should just drop on its own with loss of pressure without resupply from (dead) compressor + PantFrontStart = ( + PantFrontUp ? + 1 : + 0 ); + PantFrontUp = false; + SendCtrlToNext( "PantFront", 0, CabNo ); + } + + return PantFrontUp; } // ************************************************************************************************* @@ -5006,35 +4995,33 @@ bool TMoverParameters::PantFront(bool State) // ************************************************************************************************* bool TMoverParameters::PantRear(bool State) { - double pf1; - bool PR = false; + if( ( true == Battery ) + || ( true == ConverterFlag ) ) { - if (Battery == true) - { - PR = true; - if (State == true) - pf1 = 1; - else - pf1 = 0; - if (PantRearUp != State) - { + if( PantRearUp != State ) { PantRearUp = State; - if (State == true) - { + if( State == true ) { PantRearStart = 0; - SendCtrlToNext("PantRear", 1, CabNo); + SendCtrlToNext( "PantRear", 1, CabNo ); } - else - { - PR = false; + else { PantRearStart = 1; - SendCtrlToNext("PantRear", 0, CabNo); + SendCtrlToNext( "PantRear", 0, CabNo ); } } - else - SendCtrlToNext("PantRear", pf1, CabNo); } - return PR; + else { + // no power, drop the pantograph + // NOTE: this is a simplification as it should just drop on its own with loss of pressure without resupply from (dead) compressor + PantRearStart = ( + PantRearUp ? + 1 : + 0 ); + PantRearUp = false; + SendCtrlToNext( "PantRear", 0, CabNo ); + } + + return PantRearUp; } // ************************************************************************************************* diff --git a/McZapkie/hamulce.h b/McZapkie/hamulce.h index d9cb56da..661bfc7a 100644 --- a/McZapkie/hamulce.h +++ b/McZapkie/hamulce.h @@ -45,7 +45,6 @@ static int const bdelay_G = 1; //G static int const bdelay_P = 2; //P static int const bdelay_R = 4; //R static int const bdelay_M = 8; //Mg -static int const bdelay_GR = 128; //G-R /*stan hamulca*/ diff --git a/Model3d.cpp b/Model3d.cpp index 297232a5..c3f39b80 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -1649,15 +1649,21 @@ bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic) LoadFromBinFile(asBinary, dynamic); asBinary = ""; // wyłączenie zapisu Init(); - } + // cache the file name, in case someone wants it later + m_filename = name + ".e3d"; + } else { if (FileExists(name + ".t3d")) { LoadFromTextFile(FileName, dynamic); // wczytanie tekstowego - if (!dynamic) // pojazdy dopiero po ustawieniu animacji - Init(); // generowanie siatek i zapis E3D - } + if( !dynamic ) { + // pojazdy dopiero po ustawieniu animacji + Init(); // generowanie siatek i zapis E3D + } + // cache the file name, in case someone wants it later + m_filename = name + ".t3d"; + } } bool const result = Root ? (iSubModelsCount > 0) : false; // brak pliku albo problem z wczytaniem diff --git a/Model3d.h b/Model3d.h index cdca7c29..f3942b56 100644 --- a/Model3d.h +++ b/Model3d.h @@ -342,6 +342,7 @@ private: int *iModel; // zawartość pliku binarnego int iSubModelsCount; // Ra: używane do tworzenia binarnych std::string asBinary; // nazwa pod którą zapisać model binarny + std::string m_filename; public: inline TSubModel * GetSMRoot() { @@ -382,7 +383,8 @@ public: void Init(); std::string NameGet() { - return Root ? Root->pName : NULL; +// return Root ? Root->pName : NULL; + return m_filename; }; int TerrainCount(); TSubModel * TerrainSquare(int n); diff --git a/Timer.cpp b/Timer.cpp index d6934f65..21934834 100644 --- a/Timer.cpp +++ b/Timer.cpp @@ -15,12 +15,12 @@ namespace Timer { double DeltaTime, DeltaRenderTime; -double fFPS = 0.0f; -double fLastTime = 0.0f; -DWORD dwFrames = 0L; -double fSimulationTime = 0; -double fSoundTimer = 0; -double fSinceStart = 0; +double fFPS{ 0.0f }; +double fLastTime{ 0.0f }; +DWORD dwFrames{ 0 }; +double fSimulationTime{ 0.0 }; +double fSoundTimer{ 0.0 }; +double fSinceStart{ 0.0 }; double GetTime() { @@ -69,15 +69,10 @@ double GetFPS() void ResetTimers() { - // double CurrentTime= -#if _WIN32_WINNT >= _WIN32_WINNT_VISTA - ::GetTickCount64(); -#else - ::GetTickCount(); -#endif + UpdateTimers( Global::iPause != 0 ); DeltaTime = 0.1; - DeltaRenderTime = 0; - fSoundTimer = 0; + DeltaRenderTime = 0.0; + fSoundTimer = 0.0; }; LONGLONG fr, count, oldCount; @@ -92,17 +87,17 @@ void UpdateTimers(bool pause) DeltaTime = Global::fTimeSpeed * DeltaRenderTime; fSoundTimer += DeltaTime; if (fSoundTimer > 0.1) - fSoundTimer = 0; + fSoundTimer = 0.0; /* double CurrentTime= double(count)/double(fr);//GetTickCount(); DeltaTime= (CurrentTime-OldTime); OldTime= CurrentTime; */ - if (DeltaTime > 1) - DeltaTime = 1; + if (DeltaTime > 1.0) + DeltaTime = 1.0; } else - DeltaTime = 0; // wszystko stoi, bo czas nie płynie + DeltaTime = 0.0; // wszystko stoi, bo czas nie płynie oldCount = count; // Keep track of the time lapse and frame count diff --git a/Train.cpp b/Train.cpp index 1b5b20ed..da53bcd1 100644 --- a/Train.cpp +++ b/Train.cpp @@ -143,6 +143,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::secondcontrollerincreasefast, &TTrain::OnCommand_secondcontrollerincreasefast }, { user_command::secondcontrollerdecrease, &TTrain::OnCommand_secondcontrollerdecrease }, { user_command::secondcontrollerdecreasefast, &TTrain::OnCommand_secondcontrollerdecreasefast }, + { user_command::notchingrelaytoggle, &TTrain::OnCommand_notchingrelaytoggle }, { user_command::independentbrakeincrease, &TTrain::OnCommand_independentbrakeincrease }, { user_command::independentbrakeincreasefast, &TTrain::OnCommand_independentbrakeincreasefast }, { user_command::independentbrakedecrease, &TTrain::OnCommand_independentbrakedecrease }, @@ -156,16 +157,21 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::trainbrakeservice, &TTrain::OnCommand_trainbrakeservice }, { user_command::trainbrakefullservice, &TTrain::OnCommand_trainbrakefullservice }, { user_command::trainbrakeemergency, &TTrain::OnCommand_trainbrakeemergency }, + { user_command::epbrakecontroltoggle, &TTrain::OnCommand_epbrakecontroltoggle }, + { user_command::brakeactingspeedincrease, &TTrain::OnCommand_brakeactingspeedincrease }, + { user_command::brakeactingspeeddecrease, &TTrain::OnCommand_brakeactingspeeddecrease }, { user_command::reverserincrease, &TTrain::OnCommand_reverserincrease }, { user_command::reverserdecrease, &TTrain::OnCommand_reverserdecrease }, { user_command::alerteracknowledge, &TTrain::OnCommand_alerteracknowledge }, { user_command::batterytoggle, &TTrain::OnCommand_batterytoggle }, { user_command::pantographtogglefront, &TTrain::OnCommand_pantographtogglefront }, { user_command::pantographtogglerear, &TTrain::OnCommand_pantographtogglerear }, + { user_command::pantographlowerall, &TTrain::OnCommand_pantographlowerall }, { user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle }, { user_command::convertertoggle, &TTrain::OnCommand_convertertoggle }, { user_command::compressortoggle, &TTrain::OnCommand_compressortoggle }, { user_command::motoroverloadrelaythresholdtoggle, &TTrain::OnCommand_motoroverloadrelaythresholdtoggle }, + { user_command::heatingtoggle, &TTrain::OnCommand_heatingtoggle }, { user_command::headlighttoggleleft, &TTrain::OnCommand_headlighttoggleleft }, { user_command::headlighttoggleright, &TTrain::OnCommand_headlighttoggleright }, { user_command::headlighttoggleupper, &TTrain::OnCommand_headlighttoggleupper }, @@ -177,7 +183,9 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::redmarkertogglerearleft, &TTrain::OnCommand_redmarkertogglerearleft }, { user_command::redmarkertogglerearright, &TTrain::OnCommand_redmarkertogglerearright }, { user_command::doortoggleleft, &TTrain::OnCommand_doortoggleleft }, - { user_command::doortoggleright, &TTrain::OnCommand_doortoggleright } + { user_command::doortoggleright, &TTrain::OnCommand_doortoggleright }, + { user_command::departureannounce, &TTrain::OnCommand_departureannounce }, + { user_command::doorlocktoggle, &TTrain::OnCommand_doorlocktoggle } }; TTrain::TTrain() @@ -522,6 +530,33 @@ void TTrain::OnCommand_secondcontrollerincreasefast( TTrain *Train, command_data } } +void TTrain::OnCommand_notchingrelaytoggle( TTrain *Train, command_data const &Command ) { + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == Train->mvOccupied->AutoRelayFlag ) { + // turn on + if( Train->mvOccupied->AutoRelaySwitch( true ) ) { + // audio feedback + Train->play_sound( Train->dsbSwitch ); + // visual feedback + // NOTE: there's no button for notching relay control + // TBD, TODO: add notching relay control button? + } + } + else { + //turn off + if( Train->mvOccupied->AutoRelaySwitch( false ) ) { + // audio feedback + Train->play_sound( Train->dsbSwitch ); + // visual feedback + // NOTE: there's no button for notching relay control + // TBD, TODO: add notching relay control button? + } + } + } +} + void TTrain::OnCommand_secondcontrollerdecrease( TTrain *Train, command_data const &Command ) { if( Command.action != GLFW_RELEASE ) { @@ -790,9 +825,112 @@ void TTrain::OnCommand_trainbrakeemergency( TTrain *Train, command_data const &C } } +void TTrain::OnCommand_epbrakecontroltoggle( TTrain *Train, command_data const &Command ) { + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == Train->mvOccupied->EpFuse ) { + // turn on + if( Train->mvOccupied->EpFuseSwitch( true ) ) { + // audio feedback + Train->play_sound( Train->dsbPneumaticSwitch ); + // visual feedback + // NOTE: there's no button for ep brake control switch + // TBD, TODO: add ep brake control switch? + } + } + else { + //turn off + if( Train->mvOccupied->EpFuseSwitch( false ) ) { + // audio feedback + Train->play_sound( Train->dsbPneumaticSwitch ); + // visual feedback + // NOTE: there's no button for ep brake control switch + // TBD, TODO: add ep brake control switch? + } + } + } +} + +void TTrain::OnCommand_brakeactingspeedincrease( TTrain *Train, command_data const &Command ) { + + if( Command.action == GLFW_PRESS ) { + if( ( Train->mvOccupied->BrakeDelayFlag & bdelay_M ) != 0 ) { + // can't speed it up any more than this + return; + } + auto const fasterbrakesetting = ( + Train->mvOccupied->BrakeDelayFlag < bdelay_R ? + Train->mvOccupied->BrakeDelayFlag << 1 : + Train->mvOccupied->BrakeDelayFlag | bdelay_M ); + if( true == Train->mvOccupied->BrakeDelaySwitch( fasterbrakesetting ) ) { + // audio feedback + Train->play_sound( Train->dsbSwitch ); + Train->play_sound( Train->dsbPneumaticRelay ); + // visual feedback + if( Train->ggBrakeProfileCtrl.SubModel != nullptr ) { + Train->ggBrakeProfileCtrl.UpdateValue( + ( ( Train->mvOccupied->BrakeDelayFlag & bdelay_R ) != 0 ? + 2.0 : + Train->mvOccupied->BrakeDelayFlag - 1 ) ); + } + if( Train->ggBrakeProfileG.SubModel != nullptr ) { + Train->ggBrakeProfileG.UpdateValue( + Train->mvOccupied->BrakeDelayFlag == bdelay_G ? + 1.0 : + 0.0 ); + } + if( Train->ggBrakeProfileR.SubModel != nullptr ) { + Train->ggBrakeProfileR.UpdateValue( + ( Train->mvOccupied->BrakeDelayFlag & bdelay_R ) != 0 ? + 1.0 : + 0.0 ); + } + } + } +} + +void TTrain::OnCommand_brakeactingspeeddecrease( TTrain *Train, command_data const &Command ) { + + if( Command.action == GLFW_PRESS ) { + if( Train->mvOccupied->BrakeDelayFlag == bdelay_G ) { + // can't slow it down any more than this + return; + } + auto const slowerbrakesetting = ( + Train->mvOccupied->BrakeDelayFlag < bdelay_M ? + Train->mvOccupied->BrakeDelayFlag >> 1 : + Train->mvOccupied->BrakeDelayFlag ^ bdelay_M ); + if( true == Train->mvOccupied->BrakeDelaySwitch( slowerbrakesetting ) ) { + // audio feedback + Train->play_sound( Train->dsbSwitch ); + Train->play_sound( Train->dsbPneumaticRelay ); + // visual feedback + if( Train->ggBrakeProfileCtrl.SubModel != nullptr ) { + Train->ggBrakeProfileCtrl.UpdateValue( + ( ( Train->mvOccupied->BrakeDelayFlag & bdelay_R ) != 0 ? + 2.0 : + Train->mvOccupied->BrakeDelayFlag - 1 ) ); + } + if( Train->ggBrakeProfileG.SubModel != nullptr ) { + Train->ggBrakeProfileG.UpdateValue( + Train->mvOccupied->BrakeDelayFlag == bdelay_G ? + 1.0 : + 0.0 ); + } + if( Train->ggBrakeProfileR.SubModel != nullptr ) { + Train->ggBrakeProfileR.UpdateValue( + ( Train->mvOccupied->BrakeDelayFlag & bdelay_R ) != 0 ? + 1.0 : + 0.0 ); + } + } + } +} + void TTrain::OnCommand_reverserincrease( TTrain *Train, command_data const &Command ) { - if( Command.action != GLFW_RELEASE ) { + if( Command.action == GLFW_PRESS ) { if( Train->mvOccupied->DirectionForward() ) { // sound feedback @@ -809,7 +947,7 @@ void TTrain::OnCommand_reverserincrease( TTrain *Train, command_data const &Comm void TTrain::OnCommand_reverserdecrease( TTrain *Train, command_data const &Command ) { - if( Command.action != GLFW_RELEASE ) { + if( Command.action == GLFW_PRESS ) { if( Train->mvOccupied->DirectionBackward() ) { // sound feedback @@ -894,8 +1032,11 @@ void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command // audio feedback Train->play_sound( Train->dsbSwitch ); // side-effects - Train->mvControlled->PantFront( false ); - Train->mvControlled->PantRear( false ); + if( false == Train->mvControlled->ConverterFlag ) { + // if there's no (low voltage) power source left, drop pantographs + Train->mvControlled->PantFront( false ); + Train->mvControlled->PantRear( false ); + } } } } @@ -912,10 +1053,16 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const Train->mvControlled->PantFrontSP = false; if( Train->mvControlled->PantFront( true ) ) { if( Train->mvControlled->PantFrontStart != 1 ) { + // sound feedback + Train->play_sound( Train->dsbSwitch ); + // visual feedback if( Train->ggPantFrontButton.SubModel ) { Train->ggPantFrontButton.UpdateValue( 1.0 ); } - Train->play_sound( Train->dsbSwitch ); + if( Train->ggPantFrontButtonOff.SubModel != nullptr ) { + // pantograph control can have two-button setup + Train->ggPantFrontButtonOff.UpdateValue( 0.0 ); + } } } } @@ -924,28 +1071,41 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const Train->mvControlled->PantRearSP = false; if( Train->mvControlled->PantRear( true ) ) { if( Train->mvControlled->PantRearStart != 1 ) { - if( Train->ggPantRearButton.SubModel ) { - Train->ggPantRearButton.UpdateValue( 1.0 ); - } + // sound feedback Train->play_sound( Train->dsbSwitch ); + // visual feedback + if( Train->ggPantFrontButton.SubModel ) { + Train->ggPantFrontButton.UpdateValue( 1.0 ); + } + if( Train->ggPantFrontButtonOff.SubModel != nullptr ) { + // pantograph control can have two-button setup + Train->ggPantFrontButtonOff.UpdateValue( 0.0 ); + } } } } } else { // ...or turn off + if( ( Train->mvOccupied->PantSwitchType == "impulse" ) + && ( Train->ggPantFrontButtonOff.SubModel == nullptr ) ) { + // with impulse buttons we expect a dedicated switch to lower the pantograph, and if the cabin lacks it + // then another control has to be used (like pantographlowerall) + // TODO: we should have a way to define presense of cab controls without having to bind these to 3d submodels + return; + } + if( Train->mvOccupied->ActiveCab == 1 ) { // przedni gdy w kabinie 1 Train->mvControlled->PantFrontSP = false; if( false == Train->mvControlled->PantFront( false ) ) { if( Train->mvControlled->PantFrontStart != 0 ) { - if( Train->ggPantFrontButton.SubModel ) { - Train->ggPantFrontButton.UpdateValue( - ( Train->mvOccupied->PantSwitchType != "impulse" ? - 0.0 : - 1.0 ) ); - } + // sound feedback Train->play_sound( Train->dsbSwitch ); + // visual feedback + Train->ggPantFrontButton.UpdateValue( 0.0 ); + // pantograph control can have two-button setup + Train->ggPantFrontButtonOff.UpdateValue( 1.0 ); } } } @@ -954,13 +1114,12 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const Train->mvControlled->PantRearSP = false; if( false == Train->mvControlled->PantRear( false ) ) { if( Train->mvControlled->PantRearStart != 0 ) { - if( Train->ggPantRearButton.SubModel ) { - Train->ggPantRearButton.UpdateValue( - ( Train->mvOccupied->PantSwitchType != "impulse" ? - 0.0 : - 1.0 ) ); - } + // sound feedback Train->play_sound( Train->dsbSwitch ); + // visual feedback + Train->ggPantFrontButton.UpdateValue( 0.0 ); + // pantograph control can have two-button setup + Train->ggPantFrontButtonOff.UpdateValue( 1.0 ); } } } @@ -969,23 +1128,18 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const else if( Command.action == GLFW_RELEASE ) { // impulse switches return automatically to neutral position if( Train->mvOccupied->PantSwitchType == "impulse" ) { - if( Train->mvOccupied->ActiveCab == 1 ) { - // przedni gdy w kabinie 1 - if( Train->ggPantFrontButton.GetValue() > 0.1 ) { - Train->play_sound( Train->dsbSwitch ); - } - if( Train->ggPantFrontButton.SubModel ) { - Train->ggPantFrontButton.UpdateValue( 0.0 ); - } + if( Train->ggPantFrontButton.GetValue() > 0.35 ) { + Train->play_sound( Train->dsbSwitch ); } - else { - // rear otherwise - if( Train->ggPantRearButton.GetValue() > 0.1 ) { - Train->play_sound( Train->dsbSwitch ); - } - if( Train->ggPantRearButton.SubModel ) { - Train->ggPantRearButton.UpdateValue( 0.0 ); - } + if( Train->ggPantFrontButton.SubModel ) { + Train->ggPantFrontButton.UpdateValue( 0.0 ); + } + // also the switch off button, in cabs which have it + if( Train->ggPantFrontButtonOff.GetValue() > 0.35 ) { + Train->play_sound( Train->dsbSwitch ); + } + if( Train->ggPantFrontButtonOff.SubModel ) { + Train->ggPantFrontButtonOff.UpdateValue( 0.0 ); } } } @@ -1002,10 +1156,16 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const & Train->mvControlled->PantRearSP = false; if( Train->mvControlled->PantRear( true ) ) { if( Train->mvControlled->PantRearStart != 1 ) { + // sound feedback + Train->play_sound( Train->dsbSwitch ); + // visual feedback if( Train->ggPantRearButton.SubModel ) { Train->ggPantRearButton.UpdateValue( 1.0 ); } - Train->play_sound( Train->dsbSwitch ); + if( Train->ggPantRearButtonOff.SubModel != nullptr ) { + // pantograph control can have two-button setup + Train->ggPantRearButtonOff.UpdateValue( 0.0 ); + } } } } @@ -1014,44 +1174,52 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const & Train->mvControlled->PantFrontSP = false; if( Train->mvControlled->PantFront( true ) ) { if( Train->mvControlled->PantFrontStart != 1 ) { - if( Train->ggPantFrontButton.SubModel ) { - Train->ggPantFrontButton.UpdateValue( 1.0 ); - } + // sound feedback Train->play_sound( Train->dsbSwitch ); + // visual feedback + if( Train->ggPantRearButton.SubModel ) { + Train->ggPantRearButton.UpdateValue( 1.0 ); + } + if( Train->ggPantRearButtonOff.SubModel != nullptr ) { + // pantograph control can have two-button setup + Train->ggPantRearButtonOff.UpdateValue( 0.0 ); + } } } } } else { // ...or turn off + if( ( Train->mvOccupied->PantSwitchType == "impulse" ) + && ( Train->ggPantRearButtonOff.SubModel == nullptr ) ) { + // with impulse buttons we expect a dedicated switch to lower the pantograph, and if the cabin lacks it + // then another control has to be used (like pantographlowerall) + // TODO: we should have a way to define presense of cab controls without having to bind these to 3d submodels + return; + } + if( Train->mvOccupied->ActiveCab == 1 ) { // rear if in front cab Train->mvControlled->PantRearSP = false; if( false == Train->mvControlled->PantRear( false ) ) { - if( Train->mvControlled->PantRearStart != 0 ) { - if( Train->ggPantRearButton.SubModel ) { - Train->ggPantRearButton.UpdateValue( - ( Train->mvOccupied->PantSwitchType != "impulse" ? - 0.0 : - 1.0 ) ); - } - Train->play_sound( Train->dsbSwitch ); - } + // sound feedback + Train->play_sound( Train->dsbSwitch ); + // visual feedback + Train->ggPantRearButton.UpdateValue( 0.0 ); + // pantograph control can have two-button setup + Train->ggPantRearButtonOff.UpdateValue( 1.0 ); } } else { // front otherwise Train->mvControlled->PantFrontSP = false; if( false == Train->mvControlled->PantFront( false ) ) { - if( Train->mvControlled->PantFrontStart != 0 ) { - if( Train->ggPantFrontButton.SubModel ) { - Train->ggPantFrontButton.UpdateValue( - ( Train->mvOccupied->PantSwitchType != "impulse" ? - 0.0 : - 1.0 ) ); - } - Train->play_sound( Train->dsbSwitch ); - } + // sound feedback + Train->play_sound( Train->dsbSwitch ); + // visual feedback + Train->ggPantRearButton.UpdateValue( 0.0 ); + // pantograph control can have two-button setup + Train->ggPantRearButtonOff.UpdateValue( 1.0 ); } } } @@ -1059,29 +1227,61 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const & else if( Command.action == GLFW_RELEASE ) { // impulse switches return automatically to neutral position if( Train->mvOccupied->PantSwitchType == "impulse" ) { - if( Train->mvOccupied->ActiveCab == 1 ) { - // tylny gdy w kabinie 1 - if( Train->ggPantRearButton.GetValue() > 0.1 ) { - Train->play_sound( Train->dsbSwitch ); - } - if( Train->ggPantRearButton.SubModel ) { - Train->ggPantRearButton.UpdateValue( 0.0 ); - } - } - else { - // front otherwise - if( Train->ggPantFrontButton.GetValue() > 0.1 ) { - Train->play_sound( Train->dsbSwitch ); - } - if( Train->ggPantFrontButton.SubModel ) { - Train->ggPantFrontButton.UpdateValue( 0.0 ); - } + if( Train->ggPantRearButton.GetValue() > 0.35 ) { Train->play_sound( Train->dsbSwitch ); } + if( Train->ggPantRearButton.SubModel ) { + Train->ggPantRearButton.UpdateValue( 0.0 ); + } + // also the switch off button, in cabs which have it + if( Train->ggPantRearButtonOff.GetValue() > 0.35 ) { + Train->play_sound( Train->dsbSwitch ); + } + if( Train->ggPantRearButtonOff.SubModel ) { + Train->ggPantRearButtonOff.UpdateValue( 0.0 ); + } } } } +void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Command ) { + + if( Train->ggPantAllDownButton.SubModel == nullptr ) { + // TODO: expand definition of cab controls so we can know if the control is present without testing for presence of 3d switch + return; + } + if( Command.action == GLFW_PRESS ) { + // press the button + // since we're just lowering all potential pantographs we don't need to test for state and effect + // front... + Train->mvControlled->PantFrontSP = false; + Train->mvControlled->PantFront( false ); + // ...and rear + Train->mvControlled->PantRearSP = false; + Train->mvControlled->PantRear( false ); + // sound feedback + // TODO: separate sound effect for pneumatic buttons + if( Train->ggPantAllDownButton.GetValue() < 0.35 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggPantAllDownButton.UpdateValue( 1.0 ); + } + else if( Command.action == GLFW_RELEASE ) { + // release the button + // sound feedback +/* + // NOTE: release sound disabled as this is typically pneumatic button + // TODO: separate sound effect for pneumatic buttons + if( Train->ggPantAllDownButton.GetValue() > 0.65 ) { + Train->play_sound( Train->dsbSwitch ); + } +*/ + // visual feedback + Train->ggPantAllDownButton.UpdateValue( 0.0 ); + } +} + void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ) { if( Command.action != GLFW_RELEASE ) { // press or hold... @@ -1109,12 +1309,10 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com } // keep track of period the button is held down, to determine when/if circuit closes Train->fMainRelayTimer += 0.33f; // Command.time_delta * 5.0; - // NOTE: this shouldn't be necessary, what exactly does it fix? if( Train->mvControlled->Mains != true ) { // hunter-080812: poprawka - // adjusted further to take into account state of the switch - Train->mvControlled->ConverterSwitch( Train->ggConverterButton.GetValue() > 0.5 ); - Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 ); + Train->mvControlled->ConverterSwitch( false ); + Train->mvControlled->CompressorSwitch( false ); } if( Train->fMainRelayTimer > Train->mvControlled->InitialCtrlDelay ) { // wlaczanie WSa z opoznieniem @@ -1131,6 +1329,13 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com // ...to open the circuit if( true == Train->m_linebreakerclosed ) { // safety check so we don't open the circuit right after closing + // NOTE: we don't have switch type definition for the line breaker switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz + if( Train->mvControlled->TrainType == dt_EZT ) { + // a single impulse switch can't open the circuit, only close it + return; + } if( Train->mvControlled->MainSwitch( false ) ) { if( Train->ggMainOffButton.SubModel != nullptr ) { @@ -1144,6 +1349,7 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com } else if( Train->ggMainButton.SubModel != nullptr ) { // single two-state switch +/* // NOTE: we don't have switch type definition for the line breaker switch // so for the time being we have hard coded "impulse" switches for all EMUs // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz @@ -1155,7 +1361,9 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com // visual feedback Train->ggMainButton.UpdateValue( 1.0 ); } - else { + else +*/ + { // audio feedback if( Command.action == GLFW_PRESS ) { Train->play_sound( Train->dsbSwitch ); @@ -1164,9 +1372,6 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com Train->ggMainButton.UpdateValue( 0.0 ); } } - // side-effects - Train->mvControlled->ConverterSwitch( Train->ggConverterButton.GetValue() > 0.5 ); - Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 ); } // play sound immediately when the switch is hit, not after release if( Train->fMainRelayTimer > 0.0f ) { @@ -1202,19 +1407,21 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com } // and the two-state switch too, for good measure if( Train->ggMainButton.SubModel != nullptr ) { - Train->ggMainButton.UpdateValue( 0.0 ); - // NOTE: we don't have switch type definition for the line breaker switch - // so for the time being we have hard coded "impulse" switches for all EMUs - // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz - if( Train->mvControlled->TrainType == dt_EZT ) { - // audio feedback + // audio feedback + if( Train->ggMainButton.GetValue() > 0.5 ) { Train->play_sound( Train->dsbSwitch ); } + // visual feedback + Train->ggMainButton.UpdateValue( 0.0 ); } Train->m_linebreakerclosed = false; } else { // ...after closing the circuit + // side-effects + Train->mvControlled->ConverterSwitch( Train->ggConverterButton.GetValue() > 0.5 ); + Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 ); + // visual feedback if( Train->ggMainOnButton.SubModel != nullptr ) { // setup with two separate switches Train->ggMainOnButton.UpdateValue( 0.0 ); @@ -1224,9 +1431,12 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz if( Train->mvControlled->TrainType == dt_EZT ) { if( Train->ggMainButton.SubModel != nullptr ) { - Train->ggMainButton.UpdateValue( 0.0 ); // audio feedback - Train->play_sound( Train->dsbSwitch ); + if( Train->ggMainButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggMainButton.UpdateValue( 0.0 ); } } Train->m_linebreakerclosed = true; @@ -1238,7 +1448,8 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma if( Command.action == GLFW_PRESS ) { // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( false == Train->mvControlled->ConverterAllow ) { + if( ( false == Train->mvControlled->ConverterAllow ) + && ( Train->ggConverterButton.GetValue() < 0.5 ) ) { // turn on if( ( Train->mvControlled->EnginePowerSource.SourceType != CurrentCollector ) || ( Train->mvControlled->PantRearVolt != 0.0 ) @@ -1253,7 +1464,8 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma // NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway if( ( Train->mvOccupied->ConvSwitchType != "impulse" ) || ( Train->mvControlled->Mains ) ) { - if( true == Train->mvControlled->ConverterSwitch( true ) ) { + if( ( true == Train->m_linebreakerclosed ) // won't start if the line breaker button is still held + && ( true == Train->mvControlled->ConverterSwitch( true ) ) ) { // side effects // control the compressor, if it's paired with the converter if( Train->mvControlled->CompressorPower == 2 ) { @@ -1266,14 +1478,16 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma } else { //turn off - if( true == Train->mvControlled->ConverterSwitch( false ) ) { - // sound feedback + // sound feedback + if( Train->ggConverterButton.GetValue() > 0.5 ) { Train->play_sound( Train->dsbSwitch ); - // visual feedback - Train->ggConverterButton.UpdateValue( 0.0 ); - if( Train->ggConverterOffButton.SubModel != nullptr ) { - Train->ggConverterOffButton.UpdateValue( 1.0 ); - } + } + // visual feedback + Train->ggConverterButton.UpdateValue( 0.0 ); + if( Train->ggConverterOffButton.SubModel != nullptr ) { + Train->ggConverterOffButton.UpdateValue( 1.0 ); + } + if( true == Train->mvControlled->ConverterSwitch( false ) ) { // side effects // control the compressor, if it's paired with the converter if( Train->mvControlled->CompressorPower == 2 ) { @@ -1284,6 +1498,11 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma && ( !TestFlag( Train->mvControlled->EngDmgFlag, 4 ) ) ) { Train->mvControlled->ConvOvldFlag = false; } + // if there's no (low voltage) power source left, drop pantographs + if( false == Train->mvControlled->Battery ) { + Train->mvControlled->PantFront( false ); + Train->mvControlled->PantRear( false ); + } } } } @@ -1768,6 +1987,42 @@ void TTrain::OnCommand_redmarkertogglerearright( TTrain *Train, command_data con } } +void TTrain::OnCommand_heatingtoggle( TTrain *Train, command_data const &Command ) { + + if( Train->ggTrainHeatingButton.SubModel == nullptr ) { + return; + } + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == Train->mvControlled->Heating ) { + // turn on + if( ( ( Train->mvControlled->EngineType == ElectricSeriesMotor ) + && ( Train->mvControlled->Mains == true ) ) + || ( Train->mvControlled->ConverterFlag ) ) { + + Train->mvControlled->Heating = true; + // audio feedback + if( Train->ggTrainHeatingButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggTrainHeatingButton.UpdateValue( 1.0 ); + } + } + else { + //turn off + Train->mvControlled->Heating = false; + // audio feedback + if( Train->ggTrainHeatingButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggTrainHeatingButton.UpdateValue( 0.0 ); + } + } +} + void TTrain::OnCommand_doortoggleleft( TTrain *Train, command_data const &Command ) { if( Train->mvOccupied->DoorOpenCtrl != 1 ) { @@ -1890,6 +2145,72 @@ void TTrain::OnCommand_doortoggleright( TTrain *Train, command_data const &Comma } } +void TTrain::OnCommand_departureannounce( TTrain *Train, command_data const &Command ) { + + if( Train->ggDepartureSignalButton.SubModel == nullptr ) { + return; + } + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the sound can loop uninterrupted + if( false == Train->mvControlled->DepartureSignal ) { + // turn on + Train->mvControlled->DepartureSignal = true; + // audio feedback + if( Train->ggDepartureSignalButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggDepartureSignalButton.UpdateValue( 1.0 ); + } + } + else if( Command.action == GLFW_RELEASE ) { + // turn off + Train->mvControlled->DepartureSignal = false; + // audio feedback + if( Train->ggDepartureSignalButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggDepartureSignalButton.UpdateValue( 0.0 ); + } +} + +void TTrain::OnCommand_doorlocktoggle( TTrain *Train, command_data const &Command ) { + + if( Train->ggDoorSignallingButton.SubModel == nullptr ) { + return; + } + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the sound can loop uninterrupted + if( false == Train->mvControlled->DoorSignalling ) { + // turn on + // TODO: check wheter we really need separate flags for this + Train->mvControlled->DoorSignalling = true; + Train->mvOccupied->DoorBlocked = true; + // audio feedback + if( Train->ggDoorSignallingButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggDoorSignallingButton.UpdateValue( 1.0 ); + } + else { + // turn off + // TODO: check wheter we really need separate flags for this + Train->mvControlled->DoorSignalling = false; + Train->mvOccupied->DoorBlocked = false; + // audio feedback + if( Train->ggDoorSignallingButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggDoorSignallingButton.UpdateValue( 0.0 ); + } + } +} + void TTrain::OnKeyDown(int cKey) { // naciśnięcie klawisza bool isEztOer; @@ -2014,7 +2335,8 @@ void TTrain::OnKeyDown(int cKey) } else if (cKey == Global::Keys[k_Sand]) { - if (mvControlled->TrainType == dt_EZT) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( mvControlled->TrainType == dt_EZT ) { if (ggDoorSignallingButton.SubModel != NULL) { @@ -2027,6 +2349,7 @@ void TTrain::OnKeyDown(int cKey) } } else if (mvControlled->TrainType != dt_EZT) +#endif { if (ggSandButton.SubModel != NULL) { @@ -2054,9 +2377,10 @@ void TTrain::OnKeyDown(int cKey) // hamowania { // yB://ABu: male poprawki, zeby bylo mozna ustawic dowolny wagon int CouplNr = -2; - if (!FreeFlyModeFlag) + if( !FreeFlyModeFlag ) { - if (Global::ctrlState) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( Global::ctrlState ) if (mvOccupied->BrakeDelaySwitch(bdelay_R + bdelay_M)) { play_sound( dsbPneumaticRelay ); @@ -2067,6 +2391,7 @@ void TTrain::OnKeyDown(int cKey) { play_sound( dsbPneumaticRelay ); } +#endif } else { @@ -2161,7 +2486,6 @@ void TTrain::OnKeyDown(int cKey) play_sound( dsbSwitch ); } } -#endif else if (cKey == Global::Keys[k_CurrentAutoRelay]) { // McZapkie-241002: G - wlaczanie PSR if (mvControlled->AutoRelaySwitch(true)) @@ -2169,7 +2493,8 @@ void TTrain::OnKeyDown(int cKey) play_sound( dsbSwitch ); } } - else if (cKey == Global::Keys[k_FailedEngineCutOff]) { +#endif + else if( cKey == Global::Keys[ k_FailedEngineCutOff ] ) { // McZapkie-060103: E - wylaczanie sekcji silnikow if (mvControlled->CutOffEngine()) { @@ -2305,7 +2630,6 @@ void TTrain::OnKeyDown(int cKey) } } } -#endif else if( cKey == Global::Keys[ k_Active ] ) // yB 300407: przelacznik rozrzadu { // Ra 2014-06: uruchomiłem to, aby aktywować czuwak w zajmowanym członie, // a wyłączyć w innych @@ -2320,7 +2644,7 @@ void TTrain::OnKeyDown(int cKey) // dsbSwitch->Play(0,0,0); // } } - else if (cKey == Global::Keys[k_Heating]) // Winger 020304: ogrzewanie + else if( cKey == Global::Keys[ k_Heating ] ) // Winger 020304: ogrzewanie // skladu - wlaczenie { // Ra 2014-09: w trybie latania obsługa jest w World.cpp if (!FreeFlyModeFlag) @@ -2335,7 +2659,6 @@ void TTrain::OnKeyDown(int cKey) } } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if( cKey == Global::Keys[ k_LeftSign ] ) // lewe swiatlo - włączenie // ABu 060205: dzielo Wingera po malutkim liftingu: { @@ -3027,9 +3350,10 @@ void TTrain::OnKeyDown(int cKey) // bylo mozna ustawic dowolny // wagon int CouplNr = -2; - if (!FreeFlyModeFlag) + if( !FreeFlyModeFlag ) { - if (Global::ctrlState) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( Global::ctrlState ) if (mvOccupied->BrakeDelaySwitch(bdelay_R)) { play_sound( dsbPneumaticRelay ); @@ -3040,6 +3364,7 @@ void TTrain::OnKeyDown(int cKey) { play_sound( dsbPneumaticRelay ); } +#endif } else { @@ -3150,7 +3475,6 @@ void TTrain::OnKeyDown(int cKey) play_sound( dsbSwitch ); } } -#endif else if (cKey == Global::Keys[k_CurrentAutoRelay]) // McZapkie-241002: g - // wylaczanie PSR { @@ -3159,10 +3483,11 @@ void TTrain::OnKeyDown(int cKey) play_sound( dsbSwitch ); } } - +#endif // hunter-201211: piasecznica poprawiona oraz przeniesiona do // TTrain::Update() - else if (cKey == Global::Keys[k_Sand]) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + else if( cKey == Global::Keys[ k_Sand ] ) { /* if (mvControlled->TrainType!=dt_EZT) @@ -3188,6 +3513,7 @@ void TTrain::OnKeyDown(int cKey) } } } +#endif else if (cKey == Global::Keys[k_CabForward]) { if (!CabChange(1)) @@ -3505,7 +3831,6 @@ if } } } -#endif else if( cKey == Global::Keys[ k_Heating ] ) // Winger 020304: ogrzewanie - // wylaczenie { // Ra 2014-09: w trybie latania obsługa jest w World.cpp @@ -3518,7 +3843,6 @@ if } } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_LeftSign]) // ABu 060205: lewe swiatlo - // wylaczenie { @@ -4850,10 +5174,16 @@ bool TTrain::Update( double const Deltatime ) // Winger 140404 - woltomierz NN if (ggLVoltage.SubModel) { - if (mvControlled->Battery == true) - ggLVoltage.UpdateValue(mvControlled->BatteryVoltage); - else - ggLVoltage.UpdateValue(0); + // NOTE: since we don't have functional converter object, we're faking it here by simple check whether converter is on + // TODO: implement object-based circuits and power systems model so we can have this working more properly + ggLVoltage.UpdateValue( + std::max( + ( mvControlled->ConverterFlag ? + mvControlled->NominalBatteryVoltage : + 0.0 ), + ( mvControlled->Battery ? + mvControlled->BatteryVoltage : + 0.0 ) ) ); ggLVoltage.Update(); } @@ -4959,11 +5289,21 @@ bool TTrain::Update( double const Deltatime ) btLampkaNadmSil.TurnOff(); } - if (mvControlled->Mains) + if (mvControlled->Battery || mvControlled->ConverterFlag) { - btLampkaWylSzybki.TurnOn(); - btLampkaOpory.Turn(mvControlled->StLinFlag ? mvControlled->ResistorsFlagCheck() : - false); + btLampkaWylSzybki.Turn( mvControlled->Mains ); + + // hunter-261211: jakis stary kod (i niezgodny z prawda), + // zahaszowalem i poprawilem + // youBy-220913: ale przyda sie do lampki samej przetwornicy + btLampkaPrzetw.Turn( !mvControlled->ConverterFlag ); + btLampkaNadmPrzetw.Turn( mvControlled->ConvOvldFlag ); + + btLampkaOpory.Turn( + mvControlled->StLinFlag ? + mvControlled->ResistorsFlagCheck() : + false ); + btLampkaBezoporowa.Turn(mvControlled->ResistorsFlagCheck() || (mvControlled->MainCtrlActualPos == 0)); // do EU04 if ((mvControlled->Itot != 0) || (mvOccupied->BrakePress > 2) || @@ -4981,24 +5321,12 @@ bool TTrain::Update( double const Deltatime ) btLampkaUkrotnienie.TurnOff(); // if - // ((TestFlag(mvControlled->BrakeStatus,+b_Rused+b_Ractive)))//Lampka - // drugiego stopnia hamowania - btLampkaHamPosp.Turn((TestFlag(mvOccupied->BrakeStatus, 1))); // lampka drugiego stopnia - // hamowania //TODO: youBy - // wyciągnąć flagę wysokiego - // stopnia - - // hunter-111211: wylacznik cisnieniowy - Ra: tutaj? w kabinie? //yBARC - - // omujborzegrzesiuzniszczylesmicalydzien - // if (mvControlled->TrainType!=dt_EZT) - // if (((mvOccupied->BrakePress > 2) || ( mvOccupied->PipePress < - // 3.6 )) && ( mvControlled->MainCtrlPos != 0 )) - // mvControlled->StLinFlag=true; - //------- + // ((TestFlag(mvControlled->BrakeStatus,+b_Rused+b_Ractive)))//Lampka drugiego stopnia hamowania + btLampkaHamPosp.Turn((TestFlag(mvOccupied->BrakeStatus, 1))); // lampka drugiego stopnia hamowania + //TODO: youBy wyciągnąć flagę wysokiego stopnia // hunter-121211: lampka zanikowo-pradowego wentylatorow: - btLampkaNadmWent.Turn((mvControlled->RventRot < 5.0) && - mvControlled->ResistorsFlagCheck()); + btLampkaNadmWent.Turn( ( mvControlled->RventRot < 5.0 ) && ( mvControlled->ResistorsFlagCheck() ) ); //------- btLampkaWysRozr.Turn(!(mvControlled->Imax < mvControlled->ImaxHi)); @@ -5050,12 +5378,14 @@ bool TTrain::Update( double const Deltatime ) else // wylaczone { btLampkaWylSzybki.TurnOff(); + btLampkaWysRozr.TurnOff(); btLampkaOpory.TurnOff(); btLampkaStyczn.TurnOff(); btLampkaUkrotnienie.TurnOff(); btLampkaHamPosp.TurnOff(); btLampkaBoczniki.TurnOff(); btLampkaNapNastHam.TurnOff(); + btLampkaPrzetw.TurnOff(); btLampkaSprezarka.TurnOff(); btLampkaBezoporowa.TurnOff(); } @@ -5167,7 +5497,7 @@ bool TTrain::Update( double const Deltatime ) // btLampkaNadmPrzetwB.TurnOn(); } //**************************************************** */ - if (mvControlled->Battery) + if( mvControlled->Battery || mvControlled->ConverterFlag ) { switch (mvControlled->TrainType) { // zależnie od typu lokomotywy @@ -5191,8 +5521,8 @@ bool TTrain::Update( double const Deltatime ) // NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu btLampkaDoorLeft.Turn(mvOccupied->DoorLeftOpened); btLampkaDoorRight.Turn(mvOccupied->DoorRightOpened); - btLampkaNapNastHam.Turn((mvControlled->ActiveDir != 0) && - (mvOccupied->EpFuse)); // napiecie na nastawniku hamulcowym + btLampkaDepartureSignal.Turn( mvControlled->DepartureSignal ); + btLampkaNapNastHam.Turn((mvControlled->ActiveDir != 0) && (mvOccupied->EpFuse)); // napiecie na nastawniku hamulcowym btLampkaForward.Turn(mvControlled->ActiveDir > 0); // jazda do przodu btLampkaBackward.Turn(mvControlled->ActiveDir < 0); // jazda do tyłu btLampkaED.Turn(mvControlled->DynamicBrakeFlag); // hamulec ED @@ -5206,6 +5536,7 @@ bool TTrain::Update( double const Deltatime ) btLampkaHamulecReczny.TurnOff(); btLampkaDoorLeft.TurnOff(); btLampkaDoorRight.TurnOff(); + btLampkaDepartureSignal.TurnOff(); btLampkaNapNastHam.TurnOff(); btLampkaForward.TurnOff(); btLampkaBackward.TurnOff(); @@ -5312,18 +5643,24 @@ bool TTrain::Update( double const Deltatime ) } if (ggBrakeProfileCtrl.SubModel) { +#ifdef EU07_USE_OLD_COMMAND_SYSTEM ggBrakeProfileCtrl.UpdateValue( double(mvOccupied->BrakeDelayFlag == 4 ? 2 : mvOccupied->BrakeDelayFlag - 1)); +#endif ggBrakeProfileCtrl.Update(); } if (ggBrakeProfileG.SubModel) { - ggBrakeProfileG.UpdateValue(double(mvOccupied->BrakeDelayFlag == bdelay_G ? 1 : 0)); +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + ggBrakeProfileG.UpdateValue( double( mvOccupied->BrakeDelayFlag == bdelay_G ? 1 : 0 ) ); +#endif ggBrakeProfileG.Update(); } if (ggBrakeProfileR.SubModel) { - ggBrakeProfileR.UpdateValue(double(mvOccupied->BrakeDelayFlag == bdelay_R ? 1 : 0)); +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + ggBrakeProfileR.UpdateValue( double( mvOccupied->BrakeDelayFlag == bdelay_R ? 1 : 0 ) ); +#endif ggBrakeProfileR.Update(); } @@ -5539,9 +5876,10 @@ bool TTrain::Update( double const Deltatime ) // Winger 020304 - ogrzewanie //---------- // hunter-080812: poprawka na ogrzewanie w elektrykach - usuniete uzaleznienie od przetwornicy - if (ggTrainHeatingButton.SubModel) + if( ggTrainHeatingButton.SubModel ) { - if (mvControlled->Heating) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( mvControlled->Heating ) { ggTrainHeatingButton.PutValue(1); // if (mvControlled->ConverterFlag==true) @@ -5552,16 +5890,19 @@ bool TTrain::Update( double const Deltatime ) ggTrainHeatingButton.PutValue(0); // btLampkaOgrzewanieSkladu.TurnOff(); } +#endif ggTrainHeatingButton.Update(); } - if (ggSignallingButton.SubModel != NULL) + if (ggSignallingButton.SubModel != nullptr) { ggSignallingButton.PutValue(mvControlled->Signalling ? 1 : 0); ggSignallingButton.Update(); } - if (ggDoorSignallingButton.SubModel != NULL) + if (ggDoorSignallingButton.SubModel != nullptr) { - ggDoorSignallingButton.PutValue(mvControlled->DoorSignalling ? 1 : 0); +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + ggDoorSignallingButton.PutValue( mvControlled->DoorSignalling ? 1 : 0 ); +#endif ggDoorSignallingButton.Update(); } // if (ggDistCounter.SubModel) @@ -5578,12 +5919,6 @@ bool TTrain::Update( double const Deltatime ) btLampkaOgrzewanieSkladu.TurnOff(); //---------- - // hunter-261211: jakis stary kod (i niezgodny z prawda), - // zahaszowalem i poprawilem - // youBy-220913: ale przyda sie do lampki samej przetwornicy - btLampkaPrzetw.Turn(!mvControlled->ConverterFlag); - btLampkaNadmPrzetw.Turn(mvControlled->ConvOvldFlag); - //---------- // McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa if (mvOccupied->SecuritySystem.Status > 0) @@ -6262,6 +6597,7 @@ bool TTrain::Update( double const Deltatime ) } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM if (Console::Pressed(Global::Keys[k_DepartureSignal])) { ggDepartureSignalButton.PutValue(1); @@ -6275,7 +6611,6 @@ bool TTrain::Update( double const Deltatime ) if (!DynamicObject->Mechanik->AIControllFlag) // tylko jeśli nie prowadzi AI mvControlled->DepartureSignal = false; } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM if (Console::Pressed(Global::Keys[k_Main])) //[] { if (Global::shiftState) @@ -6300,6 +6635,7 @@ bool TTrain::Update( double const Deltatime ) } } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM else { if (Global::shiftState) @@ -6326,6 +6662,7 @@ bool TTrain::Update( double const Deltatime ) } } } +#endif } else { @@ -6474,8 +6811,10 @@ bool TTrain::Update( double const Deltatime ) #endif ggSandButton.UpdateValue(0); ggAntiSlipButton.UpdateValue(0); - ggDepartureSignalButton.UpdateValue(0); - ggFuseButton.UpdateValue(0); +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + ggDepartureSignalButton.UpdateValue( 0 ); +#endif + ggFuseButton.UpdateValue( 0 ); ggConverterFuseButton.UpdateValue(0); pyScreens.update(); @@ -7352,7 +7691,13 @@ void TTrain::set_cab_controls() { mvControlled->PantRearUp ) ? 1.0 : 0.0 ); - } + ggPantFrontButtonOff.PutValue( + ( mvOccupied->ActiveCab == 1 ? + mvControlled->PantFrontUp : + mvControlled->PantRearUp ) ? + 0.0 : + 1.0 ); + } if( mvOccupied->PantSwitchType != "impulse" ) { ggPantRearButton.PutValue( @@ -7361,7 +7706,13 @@ void TTrain::set_cab_controls() { mvControlled->PantFrontUp ) ? 1.0 : 0.0 ); - } + ggPantRearButtonOff.PutValue( + ( mvOccupied->ActiveCab == 1 ? + mvControlled->PantRearUp : + mvControlled->PantFrontUp ) ? + 0.0 : + 1.0 ); + } // converter if( mvOccupied->ConvSwitchType != "impulse" ) { @@ -7384,8 +7735,8 @@ void TTrain::set_cab_controls() { // lights int const lightsindex = ( mvOccupied->ActiveCab == 1 ? - 0 : - 1 ); + 0 : + 1 ); if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_left ) != 0 ) { ggLeftLightButton.PutValue( 1.0 ); @@ -7405,8 +7756,42 @@ void TTrain::set_cab_controls() { // doors // NOTE: we're relying on the cab models to have switches reversed for the rear cab(?) - ggDoorLeftButton.PutValue( mvOccupied->DoorLeftOpened ? 1.0 : 0.0 ); + ggDoorLeftButton.PutValue( mvOccupied->DoorLeftOpened ? 1.0 : 0.0 ); ggDoorRightButton.PutValue( mvOccupied->DoorRightOpened ? 1.0 : 0.0 ); + // door lock + if( true == mvControlled->DoorSignalling ) { + ggDoorSignallingButton.PutValue( 1.0 ); + } + + // heating + if( true == mvControlled->Heating ) { + ggTrainHeatingButton.PutValue( 1.0 ); + } + + // brake acting time + // visual feedback + if( ggBrakeProfileCtrl.SubModel != nullptr ) { + ggBrakeProfileCtrl.PutValue( + ( ( mvOccupied->BrakeDelayFlag & bdelay_R ) != 0 ? + 2.0 : + mvOccupied->BrakeDelayFlag - 1 ) ); + } + if( ggBrakeProfileG.SubModel != nullptr ) { + ggBrakeProfileG.PutValue( + mvOccupied->BrakeDelayFlag == bdelay_G ? + 1.0 : + 0.0 ); + } + if( ggBrakeProfileR.SubModel != nullptr ) { + ggBrakeProfileR.PutValue( + ( mvOccupied->BrakeDelayFlag & bdelay_R ) != 0 ? + 1.0 : + 0.0 ); + } + + // we reset all indicators, as they're set during the update pass + // TODO: when cleaning up break setting indicator state into a separate function, so we can reuse it + } // initializes a button matching provided label. returns: true if the label was found, false @@ -7882,12 +8267,16 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con // patyk tylny ggPantRearButton.Load(Parser, DynamicObject->mdKabina); } - else if (Label == "pantfrontoff_sw:") + else if( Label == "pantfrontoff_sw:" ) { // patyk przedni w dol ggPantFrontButtonOff.Load(Parser, DynamicObject->mdKabina); } - else if (Label == "pantalloff_sw:") + else if( Label == "pantrearoff_sw:" ) { + // patyk przedni w dol + ggPantRearButtonOff.Load( Parser, DynamicObject->mdKabina ); + } + else if( Label == "pantalloff_sw:" ) { // patyk przedni w dol ggPantAllDownButton.Load(Parser, DynamicObject->mdKabina); diff --git a/Train.h b/Train.h index 5c5b7be1..3bca0aaf 100644 --- a/Train.h +++ b/Train.h @@ -119,6 +119,7 @@ class TTrain static void OnCommand_secondcontrollerincreasefast( TTrain *Train, command_data const &Command ); static void OnCommand_secondcontrollerdecrease( TTrain *Train, command_data const &Command ); static void OnCommand_secondcontrollerdecreasefast( TTrain *Train, command_data const &Command ); + static void OnCommand_notchingrelaytoggle( TTrain *Train, command_data const &Command ); static void OnCommand_independentbrakeincrease( TTrain *Train, command_data const &Command ); static void OnCommand_independentbrakeincreasefast( TTrain *Train, command_data const &Command ); static void OnCommand_independentbrakedecrease( TTrain *Train, command_data const &Command ); @@ -132,16 +133,21 @@ class TTrain static void OnCommand_trainbrakeservice( TTrain *Train, command_data const &Command ); static void OnCommand_trainbrakefullservice( TTrain *Train, command_data const &Command ); static void OnCommand_trainbrakeemergency( TTrain *Train, command_data const &Command ); + 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_reverserincrease( TTrain *Train, command_data const &Command ); static void OnCommand_reverserdecrease( TTrain *Train, command_data const &Command ); static void OnCommand_alerteracknowledge( TTrain *Train, command_data const &Command ); static void OnCommand_batterytoggle( TTrain *Train, command_data const &Command ); static void OnCommand_pantographtogglefront( TTrain *Train, command_data const &Command ); static void OnCommand_pantographtogglerear( TTrain *Train, command_data const &Command ); + static void OnCommand_pantographlowerall( TTrain *Train, command_data const &Command ); static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ); static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command ); static void OnCommand_compressortoggle( TTrain *Train, command_data const &Command ); static void OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_heatingtoggle( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttoggleleft( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttoggleright( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttoggleupper( TTrain *Train, command_data const &Command ); @@ -154,6 +160,8 @@ class TTrain static void OnCommand_redmarkertogglerearright( 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_departureannounce( TTrain *Train, command_data const &Command ); + static void OnCommand_doorlocktoggle( TTrain *Train, command_data const &Command ); // members TDynamicObject *DynamicObject; // przestawia zmiana pojazdu [F5] @@ -258,6 +266,7 @@ public: // reszta może by?publiczna TGauge ggPantFrontButton; TGauge ggPantRearButton; TGauge ggPantFrontButtonOff; // EZT + TGauge ggPantRearButtonOff; TGauge ggPantAllDownButton; // Winger 020304 - wlacznik ogrzewania TGauge ggTrainHeatingButton; diff --git a/command.cpp b/command.cpp index 576580e7..e228ed5f 100644 --- a/command.cpp +++ b/command.cpp @@ -17,6 +17,116 @@ http://mozilla.org/MPL/2.0/. namespace simulation { command_queue Commands; +commanddescription_sequence Commands_descriptions = { + + { "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 }, + { "independentbrakeincrease", command_target::vehicle }, + { "independentbrakeincreasefast", command_target::vehicle }, + { "independentbrakedecrease", command_target::vehicle }, + { "independentbrakedecreasefast", command_target::vehicle }, + { "independentbrakebailoff", command_target::vehicle }, + { "trainbrakeincrease", command_target::vehicle }, + { "trainbrakedecrease", command_target::vehicle }, + { "trainbrakecharging", command_target::vehicle }, + { "trainbrakerelease", command_target::vehicle }, + { "trainbrakefirstservice", command_target::vehicle }, + { "trainbrakeservice", command_target::vehicle }, + { "trainbrakefullservice", command_target::vehicle }, + { "trainbrakeemergency", command_target::vehicle }, +/* +const int k_AntiSlipping = 21; +const int k_Sand = 22; +*/ + { "reverserincrease", command_target::vehicle }, + { "reverserdecrease", command_target::vehicle }, + { "linebreakertoggle", command_target::vehicle }, +/* +const int k_Fuse = 26; +*/ + { "convertertoggle", command_target::vehicle }, + { "compressortoggle", command_target::vehicle }, + { "motoroverloadrelaythresholdtoggle", command_target::vehicle }, + { "notchingrelaytoggle", command_target::vehicle }, + { "epbrakecontroltoggle", command_target::vehicle }, + { "brakeactingspeedincrease", command_target::vehicle }, + { "brakeactingspeeddecrease", command_target::vehicle }, +/* +const int k_BrakeProfile = 31; +*/ + { "alerteracknowledge", command_target::vehicle }, +/* +const int k_Horn = 33; +const int k_Horn2 = 34; +const int k_FailedEngineCutOff = 35; +*/ + { "viewturn", command_target::entity }, + { "movevector", 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 }, + { "moveleftfast", command_target::entity }, + { "moverightfast", command_target::entity }, + { "moveforwardfast", command_target::entity }, + { "movebackfast", command_target::entity }, + { "moveupfast", command_target::entity }, + { "movedownfast", command_target::entity }, +/* +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 }, + { "doortoggleright", command_target::vehicle }, + { "departureannounce", command_target::vehicle }, + { "doorlocktoggle", command_target::vehicle }, + { "pantographtogglefront", command_target::vehicle }, + { "pantographtogglerear", command_target::vehicle }, + { "pantographlowerall", command_target::vehicle }, + { "heatingtoggle", command_target::vehicle }, +/* +// const int k_FreeFlyMode= 59; +*/ + { "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 }, +/* +const int k_SmallCompressor = 63; +const int k_StLinOff = 64; +const int k_CurrentNext = 65; +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; +*/ + { "batterytoggle", command_target::vehicle } +/* +const int k_WalkMode = 73; +int const k_DimHeadlights = 74; +*/ +}; } @@ -50,242 +160,15 @@ command_queue::pop( command_data &Command, std::size_t const Recipient ) { return true; } -command_relay::command_relay() { - - m_targets = commandtarget_map{ - - { user_command::mastercontrollerincrease, command_target::vehicle }, - { user_command::mastercontrollerincreasefast, command_target::vehicle }, - { user_command::mastercontrollerdecrease, command_target::vehicle }, - { user_command::mastercontrollerdecreasefast, command_target::vehicle }, - { user_command::secondcontrollerincrease, command_target::vehicle }, - { user_command::secondcontrollerincreasefast, command_target::vehicle }, - { user_command::secondcontrollerdecrease, command_target::vehicle }, - { user_command::secondcontrollerdecreasefast, command_target::vehicle }, - { user_command::independentbrakeincrease, command_target::vehicle }, - { user_command::independentbrakeincreasefast, command_target::vehicle }, - { user_command::independentbrakedecrease, command_target::vehicle }, - { user_command::independentbrakedecreasefast, command_target::vehicle }, - { user_command::independentbrakebailoff, command_target::vehicle }, - { user_command::trainbrakeincrease, command_target::vehicle }, - { user_command::trainbrakedecrease, command_target::vehicle }, - { user_command::trainbrakecharging, command_target::vehicle }, - { user_command::trainbrakerelease, command_target::vehicle }, - { user_command::trainbrakefirstservice, command_target::vehicle }, - { user_command::trainbrakeservice, command_target::vehicle }, - { user_command::trainbrakefullservice, command_target::vehicle }, - { user_command::trainbrakeemergency, command_target::vehicle }, -/* -const int k_AntiSlipping = 21; -const int k_Sand = 22; -*/ - { user_command::reverserincrease, command_target::vehicle }, - { user_command::reverserdecrease, command_target::vehicle }, - { user_command::linebreakertoggle, command_target::vehicle }, -/* -const int k_Fuse = 26; -*/ - { user_command::convertertoggle, command_target::vehicle }, - { user_command::compressortoggle, command_target::vehicle }, - { user_command::motoroverloadrelaythresholdtoggle, command_target::vehicle }, -/* -const int k_CurrentAutoRelay = 30; -const int k_BrakeProfile = 31; -*/ - { user_command::alerteracknowledge, command_target::vehicle }, -/* -const int k_Czuwak = 32; -const int k_Horn = 33; -const int k_Horn2 = 34; -const int k_FailedEngineCutOff = 35; -*/ - { user_command::viewturn, command_target::entity }, - { user_command::movevector, command_target::entity }, - { user_command::moveleft, command_target::entity }, - { user_command::moveright, command_target::entity }, - { user_command::moveforward, command_target::entity }, - { user_command::moveback, command_target::entity }, - { user_command::moveup, command_target::entity }, - { user_command::movedown, command_target::entity }, - { user_command::moveleftfast, command_target::entity }, - { user_command::moverightfast, command_target::entity }, - { user_command::moveforwardfast, command_target::entity }, - { user_command::movebackfast, command_target::entity }, - { user_command::moveupfast, command_target::entity }, - { user_command::movedownfast, command_target::entity }, -/* -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; -*/ - { user_command::doortoggleleft, command_target::vehicle }, - { user_command::doortoggleright, command_target::vehicle }, -/* -const int k_DepartureSignal = 53; -*/ - { user_command::pantographtogglefront, command_target::vehicle }, - { user_command::pantographtogglerear, command_target::vehicle }, -/* -const int k_Heating = 58; -// const int k_FreeFlyMode= 59; -*/ - { user_command::headlighttoggleleft, command_target::vehicle }, - { user_command::headlighttoggleright, command_target::vehicle }, - { user_command::headlighttoggleupper, command_target::vehicle }, - { user_command::redmarkertoggleleft, command_target::vehicle }, - { user_command::redmarkertoggleright, command_target::vehicle }, - { user_command::headlighttogglerearleft, command_target::vehicle }, - { user_command::headlighttogglerearright, command_target::vehicle }, - { user_command::headlighttogglerearupper, command_target::vehicle }, - { user_command::redmarkertogglerearleft, command_target::vehicle }, - { user_command::redmarkertogglerearright, command_target::vehicle }, -/* -const int k_SmallCompressor = 63; -const int k_StLinOff = 64; -const int k_CurrentNext = 65; -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; -*/ - { user_command::batterytoggle, command_target::vehicle } -/* -const int k_WalkMode = 73; -int const k_DimHeadlights = 74; -*/ - }; - -#ifdef _DEBUG - m_commandnames = { - - "mastercontrollerincrease", - "mastercontrollerincreasefast", - "mastercontrollerdecrease", - "mastercontrollerdecreasefast", - "secondcontrollerincrease", - "secondcontrollerincreasefast", - "secondcontrollerdecrease", - "secondcontrollerdecreasefast", - "independentbrakeincrease", - "independentbrakeincreasefast", - "independentbrakedecrease", - "independentbrakedecreasefast", - "independentbrakebailoff", - "trainbrakeincrease", - "trainbrakedecrease", - "trainbrakecharging", - "trainbrakerelease", - "trainbrakefirstservice", - "trainbrakeservice", - "trainbrakefullservice", - "trainbrakeemergency", -/* -const int k_AntiSlipping = 21; -const int k_Sand = 22; -*/ - "reverserincrease", - "reverserdecrease", - "linebreakertoggle", -/* -const int k_Fuse = 26; -*/ - "convertertoggle", - "compressortoggle", - "motoroverloadrelaythresholdtoggle", -/* -const int k_MaxCurrent = 29; -const int k_CurrentAutoRelay = 30; -const int k_BrakeProfile = 31; -*/ - "alerteracknowledge", -/* -const int k_Czuwak = 32; -const int k_Horn = 33; -const int k_Horn2 = 34; -const int k_FailedEngineCutOff = 35; -*/ - "", //"viewturn", - "", //"movevector", - "", //"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; -*/ - "doortoggleleft", - "doortoggleright", -/* -const int k_DepartureSignal = 53; -*/ - "pantographtogglefront", - "pantographtogglerear", -/* -const int k_Heating = 58; -// const int k_FreeFlyMode= 59; -*/ - "headlighttoggleleft", - "headlighttoggleright", - "headlighttoggleupper", - "redmarkertoggleleft", - "redmarkertoggleright", - "headlighttogglerearleft", - "headlighttogglerearright", - "headlighttogglerearupper", - "redmarkertogglerearleft", - "redmarkertogglerearright", -/* -const int k_SmallCompressor = 63; -const int k_StLinOff = 64; -const int k_CurrentNext = 65; -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; -*/ - "batterytoggle" -/* -const int k_WalkMode = 73; -int const k_DimHeadlights = 74; -*/ - }; -#endif -} - void command_relay::post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2, int const Action, std::uint16_t const Recipient ) const { - auto const &lookup = m_targets.find( Command ); - if( lookup == m_targets.end() ) { - // shouldn't be really needed but, eh - return; - } - if( ( lookup->second == command_target::vehicle ) + auto const &command = simulation::Commands_descriptions[ static_cast( Command ) ]; + if( ( command.target == command_target::vehicle ) && ( true == FreeFlyModeFlag ) - && ( false == DebugModeFlag ) ) { - // don't pass vehicle commands if the user isn't in one, unless we're in debug mode + && ( ( false == DebugModeFlag ) + && ( true == Global::RealisticControlMode ) ) ) { + // in realistic control mode don't pass vehicle commands if the user isn't in one, unless we're in debug mode return; } @@ -296,20 +179,19 @@ command_relay::post( user_command const Command, std::uint64_t const Param1, std Param1, Param2, Timer::GetDeltaTime() }, - static_cast( lookup->second ) | Recipient ); + static_cast( command.target ) | Recipient ); #ifdef _DEBUG if( Action != GLFW_RELEASE ) { // key was pressed or is still held - auto const &commandname = m_commandnames.at( static_cast( Command ) ); - if( false == commandname.empty() ) { - WriteLog( "Command issued: " + commandname ); + if( false == command.name.empty() ) { + WriteLog( "Command issued: " + command.name ); } } /* else { // key was released (but we don't log this) - WriteLog( "Key released: " + m_commandnames.at( static_cast( Command ) ) ); + WriteLog( "Key released: " + m_command.name ); } */ #endif diff --git a/command.h b/command.h index 6a92b86d..a6b9d7ea 100644 --- a/command.h +++ b/command.h @@ -48,11 +48,10 @@ const int k_Fuse = 26; convertertoggle, compressortoggle, motoroverloadrelaythresholdtoggle, -/* -const int k_MaxCurrent = 29; -const int k_CurrentAutoRelay = 30; -const int k_BrakeProfile = 31; -*/ + notchingrelaytoggle, + epbrakecontroltoggle, + brakeactingspeedincrease, + brakeactingspeeddecrease, alerteracknowledge, /* const int k_Horn = 33; @@ -84,13 +83,13 @@ const int k_ProgramHelp = 48; */ doortoggleleft, doortoggleright, -/* -const int k_DepartureSignal = 53; -*/ + departureannounce, + doorlocktoggle, pantographtogglefront, pantographtogglerear, + pantographlowerall, + heatingtoggle, /* -const int k_Heating = 58; // const int k_FreeFlyMode= 59; */ headlighttoggleleft, @@ -103,7 +102,7 @@ const int k_Heating = 58; headlighttogglerearupper, redmarkertogglerearleft, redmarkertogglerearright, - /* +/* const int k_SmallCompressor = 63; const int k_StLinOff = 64; const int k_CurrentNext = 65; @@ -137,6 +136,14 @@ enum class command_target { entity = 0x40000 }; +struct command_description { + + std::string name; + command_target target; +}; + +typedef std::vector commanddescription_sequence; + struct command_data { user_command command; @@ -175,6 +182,8 @@ private: namespace simulation { extern command_queue Commands; +// TODO: add name to command map, and wrap these two into helper object +extern commanddescription_sequence Commands_descriptions; } @@ -184,7 +193,6 @@ class command_relay { public: // constructors - command_relay(); // methods // posts specified command for the specified recipient // TODO: replace uint16_t with recipient handle, based on item id @@ -192,12 +200,7 @@ public: post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2, int const Action, std::uint16_t const Recipient ) const; private: // types - typedef std::unordered_map commandtarget_map; // members - commandtarget_map m_targets; -#ifdef _DEBUG - std::vector m_commandnames; -#endif }; //--------------------------------------------------------------------------- diff --git a/keyboardinput.cpp b/keyboardinput.cpp index a2c148eb..d455bf00 100644 --- a/keyboardinput.cpp +++ b/keyboardinput.cpp @@ -92,65 +92,113 @@ void keyboard_input::default_bindings() { m_commands = { - - { "mastercontrollerincrease", command_target::vehicle, GLFW_KEY_KP_ADD }, - { "mastercontrollerincreasefast", command_target::vehicle, GLFW_KEY_KP_ADD | keymodifier::shift }, - { "mastercontrollerdecrease", command_target::vehicle, GLFW_KEY_KP_SUBTRACT }, - { "mastercontrollerdecreasefast", command_target::vehicle, GLFW_KEY_KP_SUBTRACT | keymodifier::shift }, - { "secondcontrollerincrease", command_target::vehicle, GLFW_KEY_KP_DIVIDE }, - { "secondcontrollerincreasefast", command_target::vehicle, GLFW_KEY_KP_DIVIDE | keymodifier::shift }, - { "secondcontrollerdecrease", command_target::vehicle, GLFW_KEY_KP_MULTIPLY }, - { "secondcontrollerdecreasefast", command_target::vehicle, GLFW_KEY_KP_MULTIPLY | keymodifier::shift }, - { "independentbrakeincrease", command_target::vehicle, GLFW_KEY_KP_1 }, - { "independentbrakeincreasefast", command_target::vehicle, GLFW_KEY_KP_1 | keymodifier::shift }, - { "independentbrakedecrease", command_target::vehicle, GLFW_KEY_KP_7 }, - { "independentbrakedecreasefast", command_target::vehicle, GLFW_KEY_KP_7 | keymodifier::shift }, - { "independentbrakebailoff", command_target::vehicle, GLFW_KEY_KP_4 }, - { "trainbrakeincrease", command_target::vehicle, GLFW_KEY_KP_3 }, - { "trainbrakedecrease", command_target::vehicle, GLFW_KEY_KP_9 }, - { "trainbrakecharging", command_target::vehicle, GLFW_KEY_KP_DECIMAL }, - { "trainbrakerelease", command_target::vehicle, GLFW_KEY_KP_6 }, - { "trainbrakefirstservice", command_target::vehicle, GLFW_KEY_KP_8 }, - { "trainbrakeservice", command_target::vehicle, GLFW_KEY_KP_5 }, - { "trainbrakefullservice", command_target::vehicle, GLFW_KEY_KP_2 }, - { "trainbrakeemergency", command_target::vehicle, GLFW_KEY_KP_0 }, + //"mastercontrollerincrease" + { GLFW_KEY_KP_ADD }, + //"mastercontrollerincreasefast" + { GLFW_KEY_KP_ADD | keymodifier::shift }, + // "mastercontrollerdecrease" + { GLFW_KEY_KP_SUBTRACT }, + // "mastercontrollerdecreasefast" + { GLFW_KEY_KP_SUBTRACT | keymodifier::shift }, + // "secondcontrollerincrease" + { GLFW_KEY_KP_DIVIDE }, + // "secondcontrollerincreasefast" + { GLFW_KEY_KP_DIVIDE | keymodifier::shift }, + // "secondcontrollerdecrease" + { GLFW_KEY_KP_MULTIPLY }, + // "secondcontrollerdecreasefast" + { GLFW_KEY_KP_MULTIPLY | keymodifier::shift }, + // "independentbrakeincrease" + { GLFW_KEY_KP_1 }, + // "independentbrakeincreasefast" + { GLFW_KEY_KP_1 | keymodifier::shift }, + // "independentbrakedecrease" + { GLFW_KEY_KP_7 }, + // "independentbrakedecreasefast" + { GLFW_KEY_KP_7 | keymodifier::shift }, + // "independentbrakebailoff" + { GLFW_KEY_KP_4 }, + // "trainbrakeincrease" + { GLFW_KEY_KP_3 }, + // "trainbrakedecrease" + { GLFW_KEY_KP_9 }, + // "trainbrakecharging" + { GLFW_KEY_KP_DECIMAL }, + // "trainbrakerelease" + { GLFW_KEY_KP_6 }, + // "trainbrakefirstservice" + { GLFW_KEY_KP_8 }, + // "trainbrakeservice" + { GLFW_KEY_KP_5 }, + // "trainbrakefullservice" + { GLFW_KEY_KP_2 }, + // "trainbrakeemergency" + { GLFW_KEY_KP_0 }, /* const int k_AntiSlipping = 21; const int k_Sand = 22; */ - { "reverserincrease", command_target::vehicle, GLFW_KEY_D }, - { "reverserdecrease", command_target::vehicle, GLFW_KEY_R }, - { "linebreakertoggle", command_target::vehicle, GLFW_KEY_M }, + // "reverserincrease" + { GLFW_KEY_D }, + // "reverserdecrease" + { GLFW_KEY_R }, + // "linebreakertoggle" + { GLFW_KEY_M }, /* const int k_Fuse = 26; */ - { "convertertoggle", command_target::vehicle, GLFW_KEY_X }, - { "compressortoggle", command_target::vehicle, GLFW_KEY_C }, - { "motoroverloadrelaythresholdtoggle", command_target::vehicle, GLFW_KEY_F }, + // "convertertoggle" + { GLFW_KEY_X }, + // "compressortoggle" + { GLFW_KEY_C }, + // "motoroverloadrelaythresholdtoggle" + { GLFW_KEY_F }, + // "notchingrelaytoggle" + { GLFW_KEY_G }, + // "epbrakecontroltoggle" + { GLFW_KEY_Z | keymodifier::control }, + // "brakeactingspeedincrease" + { GLFW_KEY_B | keymodifier::shift }, + // "brakeactingspeeddecrease" + { GLFW_KEY_B }, /* -const int k_CurrentAutoRelay = 30; const int k_BrakeProfile = 31; */ - { "alerteracknowledge", command_target::vehicle, GLFW_KEY_SPACE }, + // "alerteracknowledge" + { GLFW_KEY_SPACE }, /* const int k_Horn = 33; const int k_Horn2 = 34; const int k_FailedEngineCutOff = 35; */ - { "viewturn", command_target::entity, -1 }, - { "movevector", command_target::entity, -1 }, - { "moveleft", command_target::entity, GLFW_KEY_LEFT }, - { "moveright", command_target::entity, GLFW_KEY_RIGHT }, - { "moveforward", command_target::entity, GLFW_KEY_UP }, - { "moveback", command_target::entity, GLFW_KEY_DOWN }, - { "moveup", command_target::entity, GLFW_KEY_PAGE_UP }, - { "movedown", command_target::entity, GLFW_KEY_PAGE_DOWN }, - { "moveleftfast", command_target::entity, -1 }, - { "moverightfast", command_target::entity, -1 }, - { "moveforwardfast", command_target::entity, -1 }, - { "movebackfast", command_target::entity, -1 }, - { "moveupfast", command_target::entity, -1 }, - { "movedownfast", command_target::entity, -1 }, + // "viewturn" + { -1 }, + // "movevector" + { -1 }, + // "moveleft" + { GLFW_KEY_LEFT }, + // "moveright" + { GLFW_KEY_RIGHT }, + // "moveforward" + { GLFW_KEY_UP }, + // "moveback" + { GLFW_KEY_DOWN }, + // "moveup" + { GLFW_KEY_PAGE_UP }, + // "movedown" + { GLFW_KEY_PAGE_DOWN }, + // "moveleftfast" + { -1 }, + // "moverightfast" + { -1 }, + // "moveforwardfast" + { -1 }, + // "movebackfast" + { -1 }, + // "moveupfast" + { -1 }, + // "movedownfast" + { -1 }, /* const int k_CabForward = 42; const int k_CabBackward = 43; @@ -160,27 +208,45 @@ const int k_ProgramQuit = 46; // const int k_ProgramPause= 47; const int k_ProgramHelp = 48; */ - { "doortoggleleft", command_target::vehicle, GLFW_KEY_COMMA }, - { "doortoggleright", command_target::vehicle, GLFW_KEY_PERIOD }, + // "doortoggleleft" + { GLFW_KEY_COMMA }, + // "doortoggleright" + { GLFW_KEY_PERIOD }, + // "departureannounce" + { GLFW_KEY_SLASH }, + // "doorlocktoggle" + { GLFW_KEY_S | keymodifier::shift }, + // "pantographtogglefront" + { GLFW_KEY_P }, + // "pantographtogglerear" + { GLFW_KEY_O }, + // "pantographlowerall" + { GLFW_KEY_P | keymodifier::control }, + // "heatingtoggle" + { GLFW_KEY_H }, /* -const int k_DepartureSignal = 53; -*/ - { "pantographtogglefront", command_target::vehicle, GLFW_KEY_P }, - { "pantographtogglerear", command_target::vehicle, GLFW_KEY_O }, -/* -const int k_Heating = 58; // const int k_FreeFlyMode= 59; */ - { "headlighttoggleleft", command_target::vehicle, GLFW_KEY_Y }, - { "headlighttoggleright", command_target::vehicle, GLFW_KEY_I }, - { "headlighttoggleupper", command_target::vehicle, GLFW_KEY_U }, - { "redmarkertoggleleft", command_target::vehicle, GLFW_KEY_Y | keymodifier::shift }, - { "redmarkertoggleright", command_target::vehicle, GLFW_KEY_I | keymodifier::shift }, - { "headlighttogglerearleft", command_target::vehicle, GLFW_KEY_Y | keymodifier::control }, - { "headlighttogglerearright", command_target::vehicle, GLFW_KEY_I | keymodifier::control }, - { "headlighttogglerearupper", command_target::vehicle, GLFW_KEY_U | keymodifier::control }, - { "redmarkertogglerearleft", command_target::vehicle, GLFW_KEY_Y | keymodifier::control | keymodifier::shift }, - { "redmarkertogglerearright", command_target::vehicle, GLFW_KEY_I | keymodifier::control | keymodifier::shift }, + // "headlighttoggleleft" + { GLFW_KEY_Y }, + // "headlighttoggleright" + { GLFW_KEY_I }, + // "headlighttoggleupper" + { GLFW_KEY_U }, + // "redmarkertoggleleft" + { GLFW_KEY_Y | keymodifier::shift }, + // "redmarkertoggleright" + { GLFW_KEY_I | keymodifier::shift }, + // "headlighttogglerearleft" + { GLFW_KEY_Y | keymodifier::control }, + // "headlighttogglerearright" + { GLFW_KEY_I | keymodifier::control }, + // "headlighttogglerearupper" + { GLFW_KEY_U | keymodifier::control }, + // "redmarkertogglerearleft" + { GLFW_KEY_Y | keymodifier::control | keymodifier::shift }, + // "redmarkertogglerearright" + { GLFW_KEY_I | keymodifier::control | keymodifier::shift }, /* const int k_SmallCompressor = 63; const int k_StLinOff = 64; @@ -192,7 +258,8 @@ const int k_Univ4 = 69; const int k_EndSign = 70; const int k_Active = 71; */ - { "batterytoggle", command_target::vehicle, GLFW_KEY_J } + // "batterytoggle" + { GLFW_KEY_J } /* const int k_WalkMode = 73; int const k_DimHeadlights = 74; diff --git a/keyboardinput.h b/keyboardinput.h index 1c92acdf..12301797 100644 --- a/keyboardinput.h +++ b/keyboardinput.h @@ -37,8 +37,6 @@ private: struct command_setup { - std::string name; - command_target target; int binding; }; diff --git a/lightarray.cpp b/lightarray.cpp index 5cc85168..8a9bc1a3 100644 --- a/lightarray.cpp +++ b/lightarray.cpp @@ -57,8 +57,8 @@ light_array::update() { light.direction.z = -light.direction.z; } // determine intensity of this light set - if( true == light.owner->MoverParameters->Battery ) { - // with battery on, the intensity depends on the state of activated switches + if( ( true == light.owner->MoverParameters->Battery ) || ( true == light.owner->MoverParameters->ConverterFlag ) ) { + // with power on, the intensity depends on the state of activated switches auto const &lightbits = light.owner->iLights[ light.index ]; light.count = 0 + ( ( lightbits & 1 ) ? 1 : 0 ) + diff --git a/maszyna.vcxproj.filters b/maszyna.vcxproj.filters index dc09e535..618b4702 100644 --- a/maszyna.vcxproj.filters +++ b/maszyna.vcxproj.filters @@ -213,14 +213,14 @@ Source Files - - Source Files + + Source Files\input Source Files\input - - Source Files\input + + Source Files From 4e516fd8073d533fa80a52ae7ace89ba521c0ccc Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Mon, 17 Apr 2017 13:59:43 +0200 Subject: [PATCH 07/12] support for specifying multiple replaceable skins --- DynObj.cpp | 77 ++++++++++++++++++++++++++++-------------------------- World.cpp | 2 +- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/DynObj.cpp b/DynObj.cpp index 3ab622d3..36b09abb 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -798,7 +798,7 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist) btnOn = true; } // else btCPass2.TurnOff(); - if( ( true == MoverParameters->Battery ) || ( true == MoverParameters->ConverterFlag ) ) + if (MoverParameters->Battery) { // sygnaly konca pociagu if (btEndSignals1.Active()) { @@ -900,9 +900,10 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist) // Ra: przechyłkę załatwiamy na etapie przesuwania modelu // if (ObjSqrDist<80000) ABuModelRoll(); //przechyłki od 400m } - if( ( true == MoverParameters->Battery ) || ( true == MoverParameters->ConverterFlag ) ) { - // sygnały czoła pociagu - //Ra: wyświetlamy bez ograniczeń odległości, by były widoczne z daleka + if (MoverParameters->Battery) + { // sygnały czoła pociagu //Ra: wyświetlamy bez + // ograniczeń odległości, by były widoczne z + // daleka if (TestFlag(iLights[0], 1)) { btHeadSignals11.TurnOn(); @@ -4293,45 +4294,47 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName, } #else { // tekstura wymienna jest raczej jedynie w "dynamic\" - ReplacableSkin = Global::asCurrentTexturePath + ReplacableSkin; // skory tez z dynamic/... - std::string x = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie - if (!x.empty()) - m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + "nowhere", "", 9 ); +// ReplacableSkin = Global::asCurrentTexturePath + ReplacableSkin; // skory tez z dynamic/... + std::string nowheretexture = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie + if( false == nowheretexture.empty() ) { + m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( nowheretexture, "", 9 ); + } - if (m_materialdata.multi_textures > 0) - { // jeśli model ma 4 tekstury - m_materialdata.replacable_skins[ 1 ] = GfxRenderer.GetTextureId( - ReplacableSkin + ",1", "", Global::iDynamicFiltering); - if( m_materialdata.replacable_skins[ 1 ] ) - { // pierwsza z zestawu znaleziona - m_materialdata.replacable_skins[ 2 ] = GfxRenderer.GetTextureId( - ReplacableSkin + ",2", "", Global::iDynamicFiltering); - if( m_materialdata.replacable_skins[ 2 ] ) - { - m_materialdata.multi_textures = 2; // już są dwie - m_materialdata.replacable_skins[ 3 ] = GfxRenderer.GetTextureId( - ReplacableSkin + ",3", "", Global::iDynamicFiltering); - if( m_materialdata.replacable_skins[ 3 ] ) - { - m_materialdata.multi_textures = 3; // a teraz nawet trzy - m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( - ReplacableSkin + ",4", "", Global::iDynamicFiltering); - if( m_materialdata.replacable_skins[ 4 ] ) - m_materialdata.multi_textures = 4; // jak są cztery, to blokujemy podmianę tekstury - // rozkładem - } + if (m_materialdata.multi_textures > 0) { + // jeśli model ma 4 tekstury + // check for the pipe method first + if( ReplacableSkin.find( '|' ) != std::string::npos ) { + cParser nameparser( ReplacableSkin ); + nameparser.getTokens( 4, true, "|" ); + int skinindex = 0; + std::string texturename; nameparser >> texturename; + while( ( texturename != "" ) && ( skinindex < 4 ) ) { + m_materialdata.replacable_skins[ skinindex + 1 ] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + texturename, "" ); + ++skinindex; + texturename = ""; nameparser >> texturename; } + m_materialdata.multi_textures = skinindex; } - else - { // zestaw nie zadziałał, próbujemy normanie - m_materialdata.multi_textures = 0; - m_materialdata.replacable_skins[ 1 ] = GfxRenderer.GetTextureId( - ReplacableSkin, "", Global::iDynamicFiltering); + else { + // otherwise try the basic approach + int skinindex = 0; + do { + texture_manager::size_type texture = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + ReplacableSkin + "," + std::to_string( skinindex + 1 ), "", Global::iDynamicFiltering, true ); + if( false == GfxRenderer.Texture( texture ).is_ready ) { + break; + } + m_materialdata.replacable_skins[ skinindex + 1 ] = texture; + ++skinindex; + } while( skinindex < 4 ); + m_materialdata.multi_textures = skinindex; + if( m_materialdata.multi_textures == 0 ) { + // zestaw nie zadziałał, próbujemy normanie + m_materialdata.replacable_skins[ 1 ] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + ReplacableSkin, "", Global::iDynamicFiltering ); + } } } else - m_materialdata.replacable_skins[ 1 ] = GfxRenderer.GetTextureId( - ReplacableSkin, "", Global::iDynamicFiltering); + m_materialdata.replacable_skins[ 1 ] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + ReplacableSkin, "", Global::iDynamicFiltering ); if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) m_materialdata.textures_alpha = 0x31310031; // tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych else diff --git a/World.cpp b/World.cpp index 5dc73095..da1c2575 100644 --- a/World.cpp +++ b/World.cpp @@ -1716,7 +1716,7 @@ TWorld::Update_UI() { uitextline1 += " (paused)"; } - uitextline2 = Global::Bezogonkow( owner->Relation(), true ) + " (" + owner->Timetable()->TrainName + ")"; + uitextline2 = Global::Bezogonkow( owner->Relation(), true ) + " (" + Global::Bezogonkow( owner->Timetable()->TrainName, true ) + ")"; auto const nextstation = Global::Bezogonkow( owner->NextStop(), true ); if( !nextstation.empty() ) { // jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania From 62520bd4e8a1d8dd0518baee19b477252aee420e Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Tue, 18 Apr 2017 18:41:49 +0200 Subject: [PATCH 08/12] control for motor connectors, instrument and cab lighting. keyboard leds signalling, increased level of detail in zoom mode --- Console.cpp | 57 +++++------ McZapkie/MOVER.h | 3 +- McZapkie/Mover.cpp | 48 ++++++---- Train.cpp | 232 +++++++++++++++++++++++++++++++-------------- Train.h | 4 + command.cpp | 9 +- command.h | 9 +- keyboardinput.cpp | 141 ++++++++++++++------------- renderer.cpp | 4 +- 9 files changed, 316 insertions(+), 191 deletions(-) diff --git a/Console.cpp b/Console.cpp index efaadc5c..076d4332 100644 --- a/Console.cpp +++ b/Console.cpp @@ -82,29 +82,14 @@ public static Int32 GetScreenSaverTimeout() // static class member storage allocation TKeyTrans Console::ktTable[4 * 256]; -// Ra: do poprawienia -void SetLedState(unsigned char Code, bool bOn){ - // Ra: bajer do migania LED-ami w klawiaturze - // NOTE: disabled for the time being - // TODO: find non Borland specific equivalent, or get rid of it - /* if (Win32Platform == VER_PLATFORM_WIN32_NT) - { - // WriteLog(AnsiString(int(GetAsyncKeyState(Code)))); - if (bool(GetAsyncKeyState(Code)) != bOn) - { - keybd_event(Code, MapVirtualKey(Code, 0), KEYEVENTF_EXTENDEDKEY, 0); - keybd_event(Code, MapVirtualKey(Code, 0), KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, - 0); - } - } - else - { - TKeyboardState KBState; - GetKeyboardState(KBState); - KBState[Code] = bOn ? 1 : 0; - SetKeyboardState(KBState); - }; - */ +// Ra: bajer do migania LED-ami w klawiaturze +void SetLedState( unsigned char Code, bool bOn ) { +#ifdef _WINDOWS + if( bOn != ( ::GetKeyState( Code ) != 0 ) ) { + keybd_event( Code, MapVirtualKey( Code, 0 ), KEYEVENTF_EXTENDEDKEY | 0, 0 ); + keybd_event( Code, MapVirtualKey( Code, 0 ), KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0 ); + } +#endif }; //--------------------------------------------------------------------------- @@ -243,22 +228,24 @@ void Console::BitsUpdate(int mask) switch (iMode) { case 1: // sterowanie światełkami klawiatury: CA/SHP+opory - if (mask & 3) // gdy SHP albo CA - SetLedState(VK_CAPITAL, (iBits & 3) != 0); - if (mask & 4) // gdy jazda na oporach - { // Scroll Lock ma jakoś dziwnie... zmiana stanu na przeciwny - SetLedState(VK_SCROLL, true); // przyciśnięty - SetLedState(VK_SCROLL, false); // zwolniony + if( mask & 3 ) { + // gdy SHP albo CA + SetLedState( VK_CAPITAL, ( iBits & 3 ) != 0 ); + } + if (mask & 4) { + // gdy jazda na oporach + SetLedState( VK_SCROLL, ( iBits & 4 ) != 0 ); ++iConfig; // licznik użycia Scroll Lock } break; case 2: // sterowanie światełkami klawiatury: CA+SHP - if (mask & 2) // gdy CA - SetLedState(VK_CAPITAL, (iBits & 2) != 0); - if (mask & 1) // gdy SHP - { // Scroll Lock ma jakoś dziwnie... zmiana stanu na przeciwny - SetLedState(VK_SCROLL, true); // przyciśnięty - SetLedState(VK_SCROLL, false); // zwolniony + if( mask & 2 ) { + // gdy CA + SetLedState( VK_CAPITAL, ( iBits & 2 ) != 0 ); + } + if (mask & 1) { + // gdy SHP + SetLedState( VK_SCROLL, ( iBits & 1 ) != 0 ); ++iConfig; // licznik użycia Scroll Lock } break; diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 448a65b9..75db0f36 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -675,7 +675,7 @@ public: headlight_right = 0x10, redmarker_right = 0x20, }; - bool ScndInMain = false; /*zaleznosc bocznika od nastawnika*/ + int ScndInMain{ 0 }; /*zaleznosc bocznika od nastawnika*/ bool MBrake = false; /*Czy jest hamulec reczny*/ double StopBrakeDecc = 0.0; TSecuritySystem SecuritySystem; @@ -880,6 +880,7 @@ public: bool FuseFlag = false; /*!o bezpiecznik nadmiarowy*/ bool ConvOvldFlag = false; /*! nadmiarowy przetwornicy i ogrzewania*/ bool StLinFlag = false; /*!o styczniki liniowe*/ + bool StLinSwitchOff{ false }; // state of the button forcing motor connectors open bool ResistorsFlag = false; /*!o jazda rezystorowa*/ double RventRot = 0.0; /*!s obroty wentylatorow rozruchowych*/ bool UnBrake = false; /*w EZT - nacisniete odhamowywanie*/ diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 9e7b5d7c..e9966a19 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -129,11 +129,15 @@ double TMoverParameters::current(double n, double U) R = RList[MainCtrlActualPos].R * Bn + CircuitRes; - if ((TrainType != dt_EZT) || (Imin != IminLo) || - (!ScndS)) // yBARC - boczniki na szeregu poprawnie - Mn = RList[MainCtrlActualPos].Mn; // to jest wykonywane dla EU07 - else - Mn = RList[MainCtrlActualPos].Mn * RList[MainCtrlActualPos].Bn; + if( ( TrainType != dt_EZT ) + || ( Imin != IminLo ) + || ( false == ScndS ) ) { + // yBARC - boczniki na szeregu poprawnie + Mn = RList[ MainCtrlActualPos ].Mn; // to jest wykonywane dla EU07 + } + else { + Mn = RList[ MainCtrlActualPos ].Mn * RList[ MainCtrlActualPos ].Bn; + } // writepaslog("#", // "C++-----------------------------------------------------------------------------"); @@ -154,21 +158,25 @@ double TMoverParameters::current(double n, double U) if (DynamicBrakeFlag && (!FuseFlag) && (DynamicBrakeType == dbrake_automatic) && ConverterFlag && Mains) // hamowanie EP09 //TUHEX { + // TODO: zrobic bardziej uniwersalne nie tylko dla EP09 MotorCurrent = - -Max0R(MotorParam[0].fi * (Vadd / (Vadd + MotorParam[0].Isat) - MotorParam[0].fi0), 0) * - n * 2.0 / ep09resED; // TODO: zrobic bardziej uniwersalne nie tylko dla EP09 + -Max0R(MotorParam[0].fi * (Vadd / (Vadd + MotorParam[0].Isat) - MotorParam[0].fi0), 0) * n * 2.0 / ep09resED; + } + else if( ( RList[ MainCtrlActualPos ].Bn == 0 ) + || ( false == StLinFlag ) ) { + // wylaczone + MotorCurrent = 0; } - else if ((RList[MainCtrlActualPos].Bn == 0) || (!StLinFlag)) - MotorCurrent = 0; // wylaczone else { // wlaczone... SP = ScndCtrlActualPos; if (ScndCtrlActualPos < 255) // tak smiesznie bede wylaczal { - if (ScndInMain) - if (!(RList[MainCtrlActualPos].ScndAct == 255)) - SP = RList[MainCtrlActualPos].ScndAct; + if( ( ScndInMain ) + && ( RList[ MainCtrlActualPos ].ScndAct != 255 ) ) { + SP = RList[ MainCtrlActualPos ].ScndAct; + } Rz = Mn * WindingRes + R; @@ -212,10 +220,10 @@ double TMoverParameters::current(double n, double U) { if (U > 0) MotorCurrent = - (U1 - Isf * Rz - Mn * MotorParam[SP].fi * n + sqrt(Delta)) / (2.0 * Rz); + (U1 - Isf * Rz - Mn * MotorParam[SP].fi * n + std::sqrt(Delta)) / (2.0 * Rz); else MotorCurrent = - (U1 - Isf * Rz - Mn * MotorParam[SP].fi * n - sqrt(Delta)) / (2.0 * Rz); + (U1 - Isf * Rz - Mn * MotorParam[SP].fi * n - std::sqrt(Delta)) / (2.0 * Rz); } else MotorCurrent = 0; @@ -1593,7 +1601,7 @@ bool TMoverParameters::IncMainCtrl(int CtrlSpeed) // OK = false; // } //} - } + } if( ( TrainType == dt_ET42 ) && ( true == DynamicBrakeFlag ) ) { if( MainCtrlPos > 20 ) { @@ -4895,7 +4903,8 @@ bool TMoverParameters::AutoRelayCheck(void) (MainCtrlActualPos == 0) && (ActiveDir != 0)) { //^^ TODO: sprawdzic BUG, prawdopodobnie w CreateBrakeSys() DelayCtrlFlag = true; - if (LastRelayTime >= InitialCtrlDelay) + if( (LastRelayTime >= InitialCtrlDelay) + && ( false == StLinSwitchOff ) ) { StLinFlag = true; // ybARC - zalaczenie stycznikow liniowych MainCtrlActualPos = 1; @@ -5975,10 +5984,15 @@ bool TMoverParameters::LoadFIZ(std::string chkpath) continue; } - if( inputline.length() == 0 ) { + if( inputline[ 0 ] == ' ' ) { + // guard against malformed config files with leading spaces + inputline.erase( 0, inputline.find_first_not_of( ' ' ) ); + } + if( inputline.length() == 0 ) { startBPT = false; continue; } + // checking if table parsing should be switched off goes first... if( issection( "END-MPT", inputline ) ) { startBPT = false; diff --git a/Train.cpp b/Train.cpp index da53bcd1..d8f2235d 100644 --- a/Train.cpp +++ b/Train.cpp @@ -170,6 +170,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle }, { user_command::convertertoggle, &TTrain::OnCommand_convertertoggle }, { user_command::compressortoggle, &TTrain::OnCommand_compressortoggle }, + { user_command::motorconnectorsopen, &TTrain::OnCommand_motorconnectorsopen }, { user_command::motoroverloadrelaythresholdtoggle, &TTrain::OnCommand_motoroverloadrelaythresholdtoggle }, { user_command::heatingtoggle, &TTrain::OnCommand_heatingtoggle }, { user_command::headlighttoggleleft, &TTrain::OnCommand_headlighttoggleleft }, @@ -182,6 +183,9 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::headlighttogglerearupper, &TTrain::OnCommand_headlighttogglerearupper }, { user_command::redmarkertogglerearleft, &TTrain::OnCommand_redmarkertogglerearleft }, { user_command::redmarkertogglerearright, &TTrain::OnCommand_redmarkertogglerearright }, + { user_command::interiorlighttoggle, &TTrain::OnCommand_interiorlighttoggle }, + { user_command::interiorlightdimtoggle, &TTrain::OnCommand_interiorlightdimtoggle }, + { user_command::instrumentlighttoggle, &TTrain::OnCommand_instrumentlighttoggle }, { user_command::doortoggleleft, &TTrain::OnCommand_doortoggleleft }, { user_command::doortoggleright, &TTrain::OnCommand_doortoggleright }, { user_command::departureannounce, &TTrain::OnCommand_departureannounce }, @@ -866,7 +870,9 @@ void TTrain::OnCommand_brakeactingspeedincrease( TTrain *Train, command_data con if( true == Train->mvOccupied->BrakeDelaySwitch( fasterbrakesetting ) ) { // audio feedback Train->play_sound( Train->dsbSwitch ); +/* Train->play_sound( Train->dsbPneumaticRelay ); +*/ // visual feedback if( Train->ggBrakeProfileCtrl.SubModel != nullptr ) { Train->ggBrakeProfileCtrl.UpdateValue( @@ -904,7 +910,9 @@ void TTrain::OnCommand_brakeactingspeeddecrease( TTrain *Train, command_data con if( true == Train->mvOccupied->BrakeDelaySwitch( slowerbrakesetting ) ) { // audio feedback Train->play_sound( Train->dsbSwitch ); +/* Train->play_sound( Train->dsbPneumaticRelay ); +*/ // visual feedback if( Train->ggBrakeProfileCtrl.SubModel != nullptr ) { Train->ggBrakeProfileCtrl.UpdateValue( @@ -1584,6 +1592,36 @@ void TTrain::OnCommand_compressortoggle( TTrain *Train, command_data const &Comm */ } +void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ) { + + // TODO: don't rely on presense of 3d model to determine presence of the switch + if( Train->ggStLinOffButton.SubModel == nullptr ) { + return; + } + + if( Command.action != GLFW_RELEASE ) { + // button works while it's held down + if( true == Train->mvControlled->StLinFlag ) { + // yBARC - zmienione na przeciwne, bo true to zalaczone + Train->mvControlled->StLinFlag = false; + Train->play_sound( Train->dsbRelay ); + } + Train->mvControlled->StLinSwitchOff = true; + // visual feedback + Train->ggStLinOffButton.UpdateValue( 1.0 ); + // sound feedback + if( Train->ggStLinOffButton.GetValue() < 0.05 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + // button released + Train->mvControlled->StLinSwitchOff = false; + // visual feedback + Train->ggStLinOffButton.UpdateValue( 0.0 ); + } +} + void TTrain::OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command ) { if( Command.action == GLFW_PRESS ) { @@ -1987,6 +2025,107 @@ void TTrain::OnCommand_redmarkertogglerearright( TTrain *Train, command_data con } } +void TTrain::OnCommand_interiorlighttoggle( TTrain *Train, command_data const &Command ) { + + // NOTE: the check is disabled, as we're presuming light control is present in every vehicle + // TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels + if( Train->ggCabLightButton.SubModel == nullptr ) { + return; + } + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == Train->bCabLight ) { + // turn on + Train->bCabLight = true; + Train->btCabLight.TurnOn(); + // audio feedback + if( Train->ggCabLightButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggCabLightButton.UpdateValue( 1.0 ); + } + else { + //turn off + Train->bCabLight = false; + Train->btCabLight.TurnOff(); + // audio feedback + if( Train->ggCabLightButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggCabLightButton.UpdateValue( 0.0 ); + } + } +} + +void TTrain::OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const &Command ) { + + // TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels + if( Train->ggCabLightDimButton.SubModel == nullptr ) { + return; + } + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == Train->bCabLightDim ) { + // turn on + Train->bCabLightDim = true; + // audio feedback + if( Train->ggCabLightDimButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggCabLightDimButton.UpdateValue( 1.0 ); + } + else { + //turn off + Train->bCabLightDim = false; + // audio feedback + if( Train->ggCabLightDimButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggCabLightDimButton.UpdateValue( 0.0 ); + } + } +} + +void TTrain::OnCommand_instrumentlighttoggle( TTrain *Train, command_data const &Command ) { + + // NOTE: the check is disabled, as we're presuming light control is present in every vehicle + // TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels + if( Train->ggUniversal3Button.SubModel == nullptr ) { + return; + } + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + // NOTE: instrument lighting isn't fully implemented, so we have to rely on the state of the 'button' i.e. light itself + if( false == Train->LampkaUniversal3_st ) { + // turn on + Train->LampkaUniversal3_st = true; + // audio feedback + if( Train->ggUniversal3Button.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggUniversal3Button.UpdateValue( 1.0 ); + } + else { + //turn off + Train->LampkaUniversal3_st = false; + // audio feedback + if( Train->ggUniversal3Button.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggUniversal3Button.UpdateValue( 0.0 ); + } + } +} + void TTrain::OnCommand_heatingtoggle( TTrain *Train, command_data const &Command ) { if( Train->ggTrainHeatingButton.SubModel == nullptr ) { @@ -2530,14 +2669,13 @@ void TTrain::OnKeyDown(int cKey) } } } -#endif //----------- // hunter-131211: dzwiek dla przelacznika universala podniesionego // hunter-091012: ubajerowanie swiatla w kabinie (wyrzucenie // przyciemnienia pod Univ4) else if (cKey == Global::Keys[k_Univ3]) { - if (Global::ctrlState) + if( Global::ctrlState ) { if (bCabLight == false) //(ggCabLightButton.GetValue()==0) { @@ -2571,7 +2709,6 @@ void TTrain::OnKeyDown(int cKey) } } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM //----------- else if (cKey == Global::Keys[k_PantFrontUp]) { // Winger 160204: podn. @@ -3736,7 +3873,6 @@ if } } } -#endif //----------- // hunter-131211: dzwiek dla przelacznika universala // hunter-091012: ubajerowanie swiatla w kabinie (wyrzucenie @@ -3763,7 +3899,6 @@ if } */ } } - //----------- // hunter-091012: dzwiek dla przyciemnienia swiatelka w kabinie else if (cKey == Global::Keys[k_Univ4]) @@ -3777,7 +3912,6 @@ if } } //----------- -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_PantFrontDown]) // Winger 160204: // opuszczanie prz. patyka { @@ -4118,7 +4252,8 @@ if else if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // Winger 110904: wylacznik st. // liniowych { - if ((mvControlled->TrainType != dt_EZT) && (mvControlled->TrainType != dt_EP05) && +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( ( mvControlled->TrainType != dt_EZT ) && ( mvControlled->TrainType != dt_EP05 ) && (mvControlled->TrainType != dt_ET40)) { ggStLinOffButton.PutValue(1); // Ra: było Fuse... @@ -4130,6 +4265,7 @@ if play_sound( dsbRelay ); } } +#endif if (mvControlled->TrainType == dt_EZT) { if (mvControlled->Signalling == true) @@ -4268,7 +4404,8 @@ if void TTrain::OnKeyUp(int cKey) { // zwolnienie klawisza - if (Global::shiftState) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( Global::shiftState ) { // wciśnięty [Shift] } else @@ -4280,6 +4417,7 @@ void TTrain::OnKeyUp(int cKey) ggStLinOffButton.PutValue(0); } } +#endif }; // cab movement update, fixed step part @@ -5347,7 +5485,7 @@ bool TTrain::Update( double const Deltatime ) // - pokićkał ktoś? scp = mvControlled->RList[mvControlled->MainCtrlPos].ScndAct; scp = (scp == 255 ? 0 : scp); // Ra: whatta hella is this? - if ((mvControlled->ScndCtrlPos > 0) || (mvControlled->ScndInMain) && (scp > 0)) + if ((mvControlled->ScndCtrlPos > 0) || (mvControlled->ScndInMain != 0) && (scp > 0)) { // boczniki pojedynczo btLampkaBocznik1.TurnOn(); btLampkaBocznik2.Turn(mvControlled->ScndCtrlPos > 1); @@ -6305,6 +6443,7 @@ bool TTrain::Update( double const Deltatime ) if (DynamicObject->Mechanik ? !DynamicObject->Mechanik->AIControllFlag : false) // nie wyłączać, gdy AI mvControlled->PantCompFlag = false; // wyłączona, gdy nie trzymamy klawisza + if (Console::Pressed(Global::Keys[k_Univ2])) { if (!DebugModeFlag) @@ -6317,6 +6456,7 @@ bool TTrain::Update( double const Deltatime ) } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM // hunter-091012: zrobione z uwzglednieniem przelacznika swiatla if (Console::Pressed(Global::Keys[k_Univ3])) { @@ -6367,47 +6507,7 @@ bool TTrain::Update( double const Deltatime ) } } } - - // hunter-091012: to w ogole jest bez sensu i tak namodzone ze nie wiadomo o - // co chodzi - zakomentowalem i zrobilem po swojemu - /* - if ( Console::Pressed(Global::Keys[k_Univ3]) ) - { - if (ggUniversal3Button.SubModel) - - - if (Global::ctrlState) - {//z [Ctrl] zapalamy albo gasimy światełko w kabinie - //tutaj jest bez sensu, trzeba reagować na wciskanie klawisza! - if (Global::shiftState) - {//zapalenie - if (iCabLightFlag<2) ++iCabLightFlag; - } - else - {//gaszenie - if (iCabLightFlag) --iCabLightFlag; - } - - } - else - {//bez [Ctrl] przełączamy cośtem - if (Global::shiftState) - { - ggUniversal3Button.PutValue(1); //hunter-131211: z UpdateValue na - PutValue - by zachowywal sie jak pozostale przelaczniki - if (btLampkaUniversal3.Active()) - LampkaUniversal3_st=true; - } - else - { - ggUniversal3Button.PutValue(0); //hunter-131211: z UpdateValue na - PutValue - by zachowywal sie jak pozostale przelaczniki - if (btLampkaUniversal3.Active()) - LampkaUniversal3_st=false; - } - } - } */ - +#endif // ABu030405 obsluga lampki uniwersalnej: if (btLampkaUniversal3.Active()) // w ogóle jest if (LampkaUniversal3_st) // załączona @@ -6428,28 +6528,12 @@ bool TTrain::Update( double const Deltatime ) else btLampkaUniversal3.TurnOff(); - /* - if (Console::Pressed(Global::Keys[k_Univ4])) - { - if (ggUniversal4Button.SubModel) - if (Global::shiftState) - { - ActiveUniversal4=true; - //ggUniversal4Button.UpdateValue(1); - } - else - { - ActiveUniversal4=false; - //ggUniversal4Button.UpdateValue(0); - } - } - */ - +#ifdef EU07_USE_OLD_COMMAND_SYSTEM // hunter-091012: przepisanie univ4 i zrobione z uwzglednieniem przelacznika // swiatla if (Console::Pressed(Global::Keys[k_Univ4])) { - if (Global::shiftState) + if( Global::shiftState ) { if (Global::ctrlState) { @@ -6484,7 +6568,6 @@ bool TTrain::Update( double const Deltatime ) } } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM // Odskakiwanie hamulce EP if ((!Console::Pressed(Global::Keys[k_DecBrakeLevel])) && (!Console::Pressed(Global::Keys[k_WaveBrake])) && (mvOccupied->BrakeCtrlPos == -1) && @@ -7754,6 +7837,17 @@ void TTrain::set_cab_controls() { ggRightEndLightButton.PutValue( 1.0 ); } + // cab lights + if( true == bCabLight ) { + ggCabLightButton.PutValue( 1.0 ); + } + if( true == bCabLightDim ) { + ggCabLightDimButton.PutValue( 1.0 ); + } + if( true == LampkaUniversal3_st ) { + ggUniversal3Button.PutValue( 1.0 ); + } + // doors // NOTE: we're relying on the cab models to have switches reversed for the rear cab(?) ggDoorLeftButton.PutValue( mvOccupied->DoorLeftOpened ? 1.0 : 0.0 ); diff --git a/Train.h b/Train.h index 3bca0aaf..875b9f32 100644 --- a/Train.h +++ b/Train.h @@ -146,6 +146,7 @@ class TTrain static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ); static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command ); static void OnCommand_compressortoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ); static void OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command ); static void OnCommand_heatingtoggle( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttoggleleft( TTrain *Train, command_data const &Command ); @@ -158,6 +159,9 @@ 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_interiorlighttoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_instrumentlighttoggle( 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_departureannounce( TTrain *Train, command_data const &Command ); diff --git a/command.cpp b/command.cpp index e228ed5f..cdc811a7 100644 --- a/command.cpp +++ b/command.cpp @@ -112,8 +112,15 @@ const int k_ProgramHelp = 48; { "redmarkertogglerearright", command_target::vehicle }, /* const int k_SmallCompressor = 63; -const int k_StLinOff = 64; +*/ + { "motorconnectorsopen", command_target::vehicle }, +/* const int k_CurrentNext = 65; +*/ + { "interiorlighttoggle", command_target::vehicle }, + { "interiorlightdimtoggle", command_target::vehicle }, + { "instrumentlighttoggle", command_target::vehicle }, +/* const int k_Univ1 = 66; const int k_Univ2 = 67; const int k_Univ3 = 68; diff --git a/command.h b/command.h index a6b9d7ea..5f0e4414 100644 --- a/command.h +++ b/command.h @@ -104,8 +104,15 @@ const int k_ProgramHelp = 48; redmarkertogglerearright, /* const int k_SmallCompressor = 63; -const int k_StLinOff = 64; +*/ + motorconnectorsopen, +/* const int k_CurrentNext = 65; +*/ + interiorlighttoggle, + interiorlightdimtoggle, + instrumentlighttoggle, +/* const int k_Univ1 = 66; const int k_Univ2 = 67; const int k_Univ3 = 68; diff --git a/keyboardinput.cpp b/keyboardinput.cpp index d455bf00..0c447184 100644 --- a/keyboardinput.cpp +++ b/keyboardinput.cpp @@ -92,112 +92,112 @@ void keyboard_input::default_bindings() { m_commands = { - //"mastercontrollerincrease" + // mastercontrollerincrease { GLFW_KEY_KP_ADD }, - //"mastercontrollerincreasefast" + // mastercontrollerincreasefast { GLFW_KEY_KP_ADD | keymodifier::shift }, - // "mastercontrollerdecrease" + // mastercontrollerdecrease { GLFW_KEY_KP_SUBTRACT }, - // "mastercontrollerdecreasefast" + // mastercontrollerdecreasefast { GLFW_KEY_KP_SUBTRACT | keymodifier::shift }, - // "secondcontrollerincrease" + // secondcontrollerincrease { GLFW_KEY_KP_DIVIDE }, - // "secondcontrollerincreasefast" + // secondcontrollerincreasefast { GLFW_KEY_KP_DIVIDE | keymodifier::shift }, - // "secondcontrollerdecrease" + // secondcontrollerdecrease { GLFW_KEY_KP_MULTIPLY }, - // "secondcontrollerdecreasefast" + // secondcontrollerdecreasefast { GLFW_KEY_KP_MULTIPLY | keymodifier::shift }, - // "independentbrakeincrease" + // independentbrakeincrease { GLFW_KEY_KP_1 }, - // "independentbrakeincreasefast" + // independentbrakeincreasefast { GLFW_KEY_KP_1 | keymodifier::shift }, - // "independentbrakedecrease" + // independentbrakedecrease { GLFW_KEY_KP_7 }, - // "independentbrakedecreasefast" + // independentbrakedecreasefast { GLFW_KEY_KP_7 | keymodifier::shift }, - // "independentbrakebailoff" + // independentbrakebailoff { GLFW_KEY_KP_4 }, - // "trainbrakeincrease" + // trainbrakeincrease { GLFW_KEY_KP_3 }, - // "trainbrakedecrease" + // trainbrakedecrease { GLFW_KEY_KP_9 }, - // "trainbrakecharging" + // trainbrakecharging { GLFW_KEY_KP_DECIMAL }, - // "trainbrakerelease" + // trainbrakerelease { GLFW_KEY_KP_6 }, - // "trainbrakefirstservice" + // trainbrakefirstservice { GLFW_KEY_KP_8 }, - // "trainbrakeservice" + // trainbrakeservice { GLFW_KEY_KP_5 }, - // "trainbrakefullservice" + // trainbrakefullservice { GLFW_KEY_KP_2 }, - // "trainbrakeemergency" + // trainbrakeemergency { GLFW_KEY_KP_0 }, /* const int k_AntiSlipping = 21; const int k_Sand = 22; */ - // "reverserincrease" + // reverserincrease { GLFW_KEY_D }, - // "reverserdecrease" + // reverserdecrease { GLFW_KEY_R }, - // "linebreakertoggle" + // linebreakertoggle { GLFW_KEY_M }, /* const int k_Fuse = 26; */ - // "convertertoggle" + // convertertoggle { GLFW_KEY_X }, - // "compressortoggle" + // compressortoggle { GLFW_KEY_C }, - // "motoroverloadrelaythresholdtoggle" + // motoroverloadrelaythresholdtoggle { GLFW_KEY_F }, - // "notchingrelaytoggle" + // notchingrelaytoggle { GLFW_KEY_G }, - // "epbrakecontroltoggle" + // epbrakecontroltoggle { GLFW_KEY_Z | keymodifier::control }, - // "brakeactingspeedincrease" + // brakeactingspeedincrease { GLFW_KEY_B | keymodifier::shift }, - // "brakeactingspeeddecrease" + // brakeactingspeeddecrease { GLFW_KEY_B }, /* const int k_BrakeProfile = 31; */ - // "alerteracknowledge" + // alerteracknowledge { GLFW_KEY_SPACE }, /* const int k_Horn = 33; const int k_Horn2 = 34; const int k_FailedEngineCutOff = 35; */ - // "viewturn" + // viewturn { -1 }, - // "movevector" + // movevector { -1 }, - // "moveleft" + // moveleft { GLFW_KEY_LEFT }, - // "moveright" + // moveright { GLFW_KEY_RIGHT }, - // "moveforward" + // moveforward { GLFW_KEY_UP }, - // "moveback" + // moveback { GLFW_KEY_DOWN }, - // "moveup" + // moveup { GLFW_KEY_PAGE_UP }, - // "movedown" + // movedown { GLFW_KEY_PAGE_DOWN }, - // "moveleftfast" + // moveleftfast { -1 }, - // "moverightfast" + // moverightfast { -1 }, - // "moveforwardfast" + // moveforwardfast { -1 }, - // "movebackfast" + // movebackfast { -1 }, - // "moveupfast" + // moveupfast { -1 }, - // "movedownfast" + // movedownfast { -1 }, /* const int k_CabForward = 42; @@ -208,49 +208,60 @@ const int k_ProgramQuit = 46; // const int k_ProgramPause= 47; const int k_ProgramHelp = 48; */ - // "doortoggleleft" + // doortoggleleft { GLFW_KEY_COMMA }, - // "doortoggleright" + // doortoggleright { GLFW_KEY_PERIOD }, - // "departureannounce" + // departureannounce { GLFW_KEY_SLASH }, - // "doorlocktoggle" + // doorlocktoggle { GLFW_KEY_S | keymodifier::shift }, - // "pantographtogglefront" + // pantographtogglefront { GLFW_KEY_P }, - // "pantographtogglerear" + // pantographtogglerear { GLFW_KEY_O }, - // "pantographlowerall" + // pantographlowerall { GLFW_KEY_P | keymodifier::control }, - // "heatingtoggle" + // heatingtoggle { GLFW_KEY_H }, /* // const int k_FreeFlyMode= 59; */ - // "headlighttoggleleft" + // headlighttoggleleft { GLFW_KEY_Y }, - // "headlighttoggleright" + // headlighttoggleright { GLFW_KEY_I }, - // "headlighttoggleupper" + // headlighttoggleupper { GLFW_KEY_U }, - // "redmarkertoggleleft" + // redmarkertoggleleft { GLFW_KEY_Y | keymodifier::shift }, - // "redmarkertoggleright" + // redmarkertoggleright { GLFW_KEY_I | keymodifier::shift }, - // "headlighttogglerearleft" + // headlighttogglerearleft { GLFW_KEY_Y | keymodifier::control }, - // "headlighttogglerearright" + // headlighttogglerearright { GLFW_KEY_I | keymodifier::control }, - // "headlighttogglerearupper" + // headlighttogglerearupper { GLFW_KEY_U | keymodifier::control }, - // "redmarkertogglerearleft" + // redmarkertogglerearleft { GLFW_KEY_Y | keymodifier::control | keymodifier::shift }, - // "redmarkertogglerearright" + // redmarkertogglerearright { GLFW_KEY_I | keymodifier::control | keymodifier::shift }, /* const int k_SmallCompressor = 63; -const int k_StLinOff = 64; +*/ + // motorconnectorsopen + { GLFW_KEY_L }, +/* const int k_CurrentNext = 65; +*/ + // interiorlighttoggle + { GLFW_KEY_APOSTROPHE }, + // interiorlightdimtoggle + { GLFW_KEY_APOSTROPHE | keymodifier::control }, + // instrumentlighttoggle + { GLFW_KEY_SEMICOLON }, +/* const int k_Univ1 = 66; const int k_Univ2 = 67; const int k_Univ3 = 68; diff --git a/renderer.cpp b/renderer.cpp index 8c66ff86..afa09dfc 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -319,7 +319,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) { // setup TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji - double squaredistance = SquareMagnitude( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor; + double squaredistance = SquareMagnitude( ( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor ); Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu ::glPushMatrix(); @@ -591,7 +591,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) { // setup TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji - double squaredistance = SquareMagnitude( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor; + double squaredistance = SquareMagnitude( ( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor ); Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu ::glPushMatrix(); From c43ac777f4707116b93634a5eae6d118927108c7 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sat, 22 Apr 2017 15:48:02 +0200 Subject: [PATCH 09/12] control for overload relays, wheelspin brakes and sander, horns, radio, pantograph compressor. added basic air leaks for braking system --- Gauge.cpp | 4 + Logs.cpp | 2 +- McZapkie/Mover.cpp | 27 +- Train.cpp | 748 +++++++++++++++++++++++++++++++++++++-------- Train.h | 17 +- command.cpp | 49 +-- command.h | 28 +- keyboardinput.cpp | 43 +-- windows.cpp | 2 +- 9 files changed, 723 insertions(+), 197 deletions(-) diff --git a/Gauge.cpp b/Gauge.cpp index 85ff23c6..ef0c1efa 100644 --- a/Gauge.cpp +++ b/Gauge.cpp @@ -87,6 +87,10 @@ bool TGauge::Load(cParser &Parser, TModel3d *md1, TModel3d *md2, double mul) >> val5; val3 *= mul; TSubModel *sm = md1->GetFromName( str1.c_str() ); + if( val3 == 0.0 ) { + ErrorLog( "Scale of 0.0 defined for sub-model \"" + str1 + "\" in 3d model \"" + md1->NameGet() + "\". Forcing scale of 1.0 to prevent division by 0" ); + val3 = 1.0; + } if (sm) // jeśli nie znaleziony md2 = NULL; // informacja, że znaleziony else if (md2) // a jest podany drugi model (np. zewnętrzny) diff --git a/Logs.cpp b/Logs.cpp index a4a22fb0..6b1bd677 100644 --- a/Logs.cpp +++ b/Logs.cpp @@ -21,7 +21,7 @@ char endstring[10] = "\n"; std::string filename_date() { ::SYSTEMTIME st; - ::GetSystemTime( &st ); + ::GetLocalTime( &st ); char buffer[ 256 ]; sprintf( buffer, "%d%02d%02d_%02d%02d", diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index e9966a19..98a48ea5 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -2843,6 +2843,9 @@ void TMoverParameters::UpdateBrakePressure(double dt) // ************************************************************************************************* void TMoverParameters::CompressorCheck(double dt) { + // TODO: expose leak rate as a parameter to the .fiz file + CompressedVolume = std::max( 0.0, CompressedVolume - dt * 0.001 ); // nieszczelności: 0.001=1l/s + // if (CompressorSpeed>0.0) then //ten warunek został sprawdzony przy wywołaniu funkcji if (VeselVolume > 0) { @@ -2965,6 +2968,9 @@ void TMoverParameters::CompressorCheck(double dt) // ************************************************************************************************* void TMoverParameters::UpdatePipePressure(double dt) { + // TODO: expose leak rate as a parameter to the .fiz file + PipePress = std::max( 0.0, PipePress - dt * 0.001 ); // nieszczelności: 0.001=1l/s + const double LBDelay = 100; const double kL = 0.5; //double dV; @@ -3139,7 +3145,7 @@ void TMoverParameters::UpdatePipePressure(double dt) // temp = (Handle as TFVel6).GetCP temp = Handle->GetCP(); else - temp = 0; + temp = 0.0; Hamulec->SetEPS(temp); SendCtrlToNext("Brake", temp, CabNo); // Ra 2014-11: na tym się wysypuje, ale nie wiem, w jakich warunkach @@ -3148,9 +3154,9 @@ void TMoverParameters::UpdatePipePressure(double dt) Pipe->Act(); PipePress = Pipe->P(); if ((BrakeStatus & 128) == 128) // jesli hamulec wyłączony - temp = 0; // odetnij + temp = 0.0; // odetnij else - temp = 1; // połącz + temp = 1.0; // połącz Pipe->Flow(temp * Hamulec->GetPF(temp * PipePress, dt, Vel) + GetDVc(dt)); if (ASBType == 128) @@ -3162,17 +3168,17 @@ void TMoverParameters::UpdatePipePressure(double dt) Pipe->Act(); PipePress = Pipe->P(); - dpMainValve = dpMainValve / (100 * dt); // normalizacja po czasie do syczenia; + dpMainValve = dpMainValve / (100.0 * dt); // normalizacja po czasie do syczenia; - if (PipePress < -1) + if (PipePress < -1.0) { - PipePress = -1; - Pipe->CreatePress(-1); + PipePress = -1.0; + Pipe->CreatePress(-1.0); Pipe->Act(); } - if (CompressedVolume < 0) - CompressedVolume = 0; + if (CompressedVolume < 0.0) + CompressedVolume = 0.0; } // ************************************************************************************************* @@ -3181,6 +3187,9 @@ void TMoverParameters::UpdatePipePressure(double dt) // ************************************************************************************************* void TMoverParameters::UpdateScndPipePressure(double dt) { + // TODO: expose leak rate as a parameter to the .fiz file + ScndPipePress = std::max( 0.0, ScndPipePress - dt * 0.001 ); // nieszczelności: 0.001=0.1l/s + const double Spz = 0.5067; TMoverParameters *c; double dv1, dv2, dV; diff --git a/Train.cpp b/Train.cpp index d8f2235d..fdea2409 100644 --- a/Train.cpp +++ b/Train.cpp @@ -144,6 +144,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::secondcontrollerdecrease, &TTrain::OnCommand_secondcontrollerdecrease }, { user_command::secondcontrollerdecreasefast, &TTrain::OnCommand_secondcontrollerdecreasefast }, { user_command::notchingrelaytoggle, &TTrain::OnCommand_notchingrelaytoggle }, + { user_command::mucurrentindicatorsourcetoggle, &TTrain::OnCommand_mucurrentindicatorsourcetoggle }, { user_command::independentbrakeincrease, &TTrain::OnCommand_independentbrakeincrease }, { user_command::independentbrakeincreasefast, &TTrain::OnCommand_independentbrakeincreasefast }, { user_command::independentbrakedecrease, &TTrain::OnCommand_independentbrakedecrease }, @@ -157,21 +158,28 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::trainbrakeservice, &TTrain::OnCommand_trainbrakeservice }, { user_command::trainbrakefullservice, &TTrain::OnCommand_trainbrakefullservice }, { user_command::trainbrakeemergency, &TTrain::OnCommand_trainbrakeemergency }, + { user_command::wheelspinbrakeactivate, &TTrain::OnCommand_wheelspinbrakeactivate }, + { user_command::sandboxactivate, &TTrain::OnCommand_sandboxactivate }, { user_command::epbrakecontroltoggle, &TTrain::OnCommand_epbrakecontroltoggle }, { user_command::brakeactingspeedincrease, &TTrain::OnCommand_brakeactingspeedincrease }, { user_command::brakeactingspeeddecrease, &TTrain::OnCommand_brakeactingspeeddecrease }, + { user_command::mubrakingindicatortoggle, &TTrain::OnCommand_mubrakingindicatortoggle }, { user_command::reverserincrease, &TTrain::OnCommand_reverserincrease }, { user_command::reverserdecrease, &TTrain::OnCommand_reverserdecrease }, { user_command::alerteracknowledge, &TTrain::OnCommand_alerteracknowledge }, { user_command::batterytoggle, &TTrain::OnCommand_batterytoggle }, + { user_command::pantographcompressorvalvetoggle, &TTrain::OnCommand_pantographcompressorvalvetoggle }, + { user_command::pantographcompressoractivate, &TTrain::OnCommand_pantographcompressoractivate }, { user_command::pantographtogglefront, &TTrain::OnCommand_pantographtogglefront }, { user_command::pantographtogglerear, &TTrain::OnCommand_pantographtogglerear }, { user_command::pantographlowerall, &TTrain::OnCommand_pantographlowerall }, { user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle }, { user_command::convertertoggle, &TTrain::OnCommand_convertertoggle }, + { user_command::converteroverloadrelayreset, &TTrain::OnCommand_converteroverloadrelayreset }, { user_command::compressortoggle, &TTrain::OnCommand_compressortoggle }, { user_command::motorconnectorsopen, &TTrain::OnCommand_motorconnectorsopen }, { user_command::motoroverloadrelaythresholdtoggle, &TTrain::OnCommand_motoroverloadrelaythresholdtoggle }, + { user_command::motoroverloadrelayreset, &TTrain::OnCommand_motoroverloadrelayreset }, { user_command::heatingtoggle, &TTrain::OnCommand_heatingtoggle }, { user_command::headlighttoggleleft, &TTrain::OnCommand_headlighttoggleleft }, { user_command::headlighttoggleright, &TTrain::OnCommand_headlighttoggleright }, @@ -183,13 +191,17 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::headlighttogglerearupper, &TTrain::OnCommand_headlighttogglerearupper }, { user_command::redmarkertogglerearleft, &TTrain::OnCommand_redmarkertogglerearleft }, { user_command::redmarkertogglerearright, &TTrain::OnCommand_redmarkertogglerearright }, + { user_command::headlightsdimtoggle, &TTrain::OnCommand_headlightsdimtoggle }, { user_command::interiorlighttoggle, &TTrain::OnCommand_interiorlighttoggle }, { user_command::interiorlightdimtoggle, &TTrain::OnCommand_interiorlightdimtoggle }, { user_command::instrumentlighttoggle, &TTrain::OnCommand_instrumentlighttoggle }, + { user_command::doorlocktoggle, &TTrain::OnCommand_doorlocktoggle }, { user_command::doortoggleleft, &TTrain::OnCommand_doortoggleleft }, { user_command::doortoggleright, &TTrain::OnCommand_doortoggleright }, { user_command::departureannounce, &TTrain::OnCommand_departureannounce }, - { user_command::doorlocktoggle, &TTrain::OnCommand_doorlocktoggle } + { user_command::hornlowactivate, &TTrain::OnCommand_hornlowactivate }, + { user_command::hornhighactivate, &TTrain::OnCommand_hornhighactivate }, + { user_command::radiotoggle, &TTrain::OnCommand_radiotoggle } }; TTrain::TTrain() @@ -561,6 +573,40 @@ void TTrain::OnCommand_notchingrelaytoggle( TTrain *Train, command_data const &C } } +void TTrain::OnCommand_mucurrentindicatorsourcetoggle( TTrain *Train, command_data const &Command ) { + + if( Train->ggNextCurrentButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Current Indicator Source switch is missing, or wasn't defined" ); + } + return; + } + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == Train->ShowNextCurrent ) { + // turn on + Train->ShowNextCurrent = true; + // audio feedback + if( Train->ggNextCurrentButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggNextCurrentButton.UpdateValue( 1.0 ); + } + else { + //turn off + Train->ShowNextCurrent = false; + // audio feedback + if( Train->ggNextCurrentButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggNextCurrentButton.UpdateValue( 0.0 ); + } + } +} + void TTrain::OnCommand_secondcontrollerdecrease( TTrain *Train, command_data const &Command ) { if( Command.action != GLFW_RELEASE ) { @@ -645,13 +691,19 @@ void TTrain::OnCommand_independentbrakebailoff( TTrain *Train, command_data cons if( Command.action != GLFW_RELEASE ) { // press or hold - Train->ggReleaserButton.UpdateValue( 1 ); Train->mvOccupied->BrakeReleaser( 1 ); + // audio feedback + if( Train->ggReleaserButton.GetValue() < 0.05 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggReleaserButton.UpdateValue( 1.0 ); } else { // release - Train->ggReleaserButton.UpdateValue( 0 ); Train->mvOccupied->BrakeReleaser( 0 ); + // visual feedback + Train->ggReleaserButton.UpdateValue( 0.0 ); } } } @@ -829,6 +881,76 @@ void TTrain::OnCommand_trainbrakeemergency( TTrain *Train, command_data const &C } } +void TTrain::OnCommand_wheelspinbrakeactivate( TTrain *Train, command_data const &Command ) { + + // TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels + if( Train->ggAntiSlipButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Wheelspin Brake button is missing, or wasn't defined" ); + } + return; + } + if( Train->mvOccupied->BrakeSystem == ElectroPneumatic ) { + return; + } + + if( Command.action != GLFW_RELEASE ) { + // press or hold + Train->mvControlled->AntiSlippingBrake(); + // audio feedback + if( Train->ggAntiSlipButton.GetValue() < 0.05 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggAntiSlipButton.UpdateValue( 1.0 ); + } + else { + // release +/* + // audio feedback + if( Train->ggAntiSlipButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } +*/ + // visual feedback + Train->ggAntiSlipButton.UpdateValue( 0.0 ); + } +} + +void TTrain::OnCommand_sandboxactivate( TTrain *Train, command_data const &Command ) { + + // TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels + if( Train->ggSandButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Wheelspin Brake button is missing, or wasn't defined" ); + } + return; + } + + if( Command.action != GLFW_RELEASE ) { + // press or hold + Train->mvControlled->SandDose = true; + // audio feedback + if( Train->ggSandButton.GetValue() < 0.05 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggSandButton.UpdateValue( 1.0 ); + } + else { + // release + Train->mvControlled->SandDose = false; +/* + // audio feedback + if( Train->ggAntiSlipButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } +*/ + // visual feedback + Train->ggSandButton.UpdateValue( 0.0 ); + } +} + void TTrain::OnCommand_epbrakecontroltoggle( TTrain *Train, command_data const &Command ) { if( Command.action == GLFW_PRESS ) { @@ -936,6 +1058,44 @@ void TTrain::OnCommand_brakeactingspeeddecrease( TTrain *Train, command_data con } } +void TTrain::OnCommand_mubrakingindicatortoggle( TTrain *Train, command_data const &Command ) { + + if( Train->ggSignallingButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Braking Indicator switch is missing, or wasn't defined" ); + } + return; + } + if( Train->mvControlled->TrainType != dt_EZT ) { + // + return; + } + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == Train->mvControlled->Signalling) { + // turn on + Train->mvControlled->Signalling = true; + // audio feedback + if( Train->ggSignallingButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggSignallingButton.UpdateValue( 1.0 ); + } + else { + //turn off + Train->mvControlled->Signalling = false; + // audio feedback + if( Train->ggSignallingButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggSignallingButton.UpdateValue( 0.0 ); + } + } +} + void TTrain::OnCommand_reverserincrease( TTrain *Train, command_data const &Command ) { if( Command.action == GLFW_PRESS ) { @@ -1040,11 +1200,14 @@ void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command // audio feedback Train->play_sound( Train->dsbSwitch ); // side-effects +/* + // NOTE: on second thought, don't and let them drop when the pantograph tank pressure drops below threshold if( false == Train->mvControlled->ConverterFlag ) { // if there's no (low voltage) power source left, drop pantographs Train->mvControlled->PantFront( false ); Train->mvControlled->PantRear( false ); } +*/ } } } @@ -1210,24 +1373,28 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const & // rear if in front cab Train->mvControlled->PantRearSP = false; if( false == Train->mvControlled->PantRear( false ) ) { - // sound feedback - Train->play_sound( Train->dsbSwitch ); - // visual feedback - Train->ggPantRearButton.UpdateValue( 0.0 ); - // pantograph control can have two-button setup - Train->ggPantRearButtonOff.UpdateValue( 1.0 ); + if( Train->mvControlled->PantRearStart != 0 ) { + // sound feedback + Train->play_sound( Train->dsbSwitch ); + // visual feedback + Train->ggPantRearButton.UpdateValue( 0.0 ); + // pantograph control can have two-button setup + Train->ggPantRearButtonOff.UpdateValue( 1.0 ); + } } } else { // front otherwise Train->mvControlled->PantFrontSP = false; if( false == Train->mvControlled->PantFront( false ) ) { - // sound feedback - Train->play_sound( Train->dsbSwitch ); - // visual feedback - Train->ggPantRearButton.UpdateValue( 0.0 ); - // pantograph control can have two-button setup - Train->ggPantRearButtonOff.UpdateValue( 1.0 ); + if( Train->mvControlled->PantFrontStart != 0 ) { + // sound feedback + Train->play_sound( Train->dsbSwitch ); + // visual feedback + Train->ggPantRearButton.UpdateValue( 0.0 ); + // pantograph control can have two-button setup + Train->ggPantRearButtonOff.UpdateValue( 1.0 ); + } } } } @@ -1252,10 +1419,68 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const & } } +void TTrain::OnCommand_pantographcompressorvalvetoggle( TTrain *Train, command_data const &Command ) { + + if( ( Train->mvControlled->TrainType == dt_EZT ? + ( Train->mvControlled != Train->mvOccupied ) : + ( Train->mvOccupied->ActiveCab != 0 ) ) ) { + // tylko w maszynowym + return; + } + + if( Command.action == GLFW_PRESS ) { + // only react to press + if( Train->mvControlled->bPantKurek3 == false ) { + // connect pantographs with primary tank + Train->mvControlled->bPantKurek3 = true; + // audio feedback + Train->play_sound( Train->dsbSwitch ); + } + else { + // connect pantograps with pantograph compressor + Train->mvControlled->bPantKurek3 = false; + // audio feedback + Train->play_sound( Train->dsbSwitch ); + } + } +} + +void TTrain::OnCommand_pantographcompressoractivate( TTrain *Train, command_data const &Command ) { + + if( ( Train->mvControlled->TrainType == dt_EZT ? + ( Train->mvControlled != Train->mvOccupied ) : + ( Train->mvOccupied->ActiveCab != 0 ) ) ) { + // tylko w maszynowym + return; + } + + if( ( Train->mvControlled->PantPress > 4.8 ) + || ( false == Train->mvControlled->Battery ) ) { + // needs live power source and low enough pressure to work + return; + } + + if( Command.action != GLFW_RELEASE ) { + // press or hold to activate + Train->mvControlled->PantCompFlag = true; + // audio feedback + if( Command.action == GLFW_PRESS ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + // release to disable + Train->mvControlled->PantCompFlag = false; + } +} + void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Command ) { if( Train->ggPantAllDownButton.SubModel == nullptr ) { // TODO: expand definition of cab controls so we can know if the control is present without testing for presence of 3d switch + if( Command.action == GLFW_PRESS ) { + WriteLog( "Lower All Pantographs switch is missing, or wasn't defined" ); + } return; } if( Command.action == GLFW_PRESS ) { @@ -1291,6 +1516,25 @@ void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Co } void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ) { + + if( ( Command.action == GLFW_PRESS ) + && ( true == Train->m_linebreakerclosed ) + && ( false == Train->mvControlled->Mains ) + && ( Train->ggMainButton.GetValue() < 0.05 ) ) { + // crude way to catch cases where the main was knocked out and the user is trying to restart it + // because the state of the line breaker isn't changed to match, we need to do it here manually + Train->m_linebreakerclosed = false; + } + // NOTE: we don't have switch type definition for the line breaker switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz + if( ( true == Train->m_linebreakerclosed ) + && ( Train->mvControlled->TrainType == dt_EZT ) ) { + // a single impulse switch can't open the circuit, only close it + return; + } + + if( Command.action != GLFW_RELEASE ) { // press or hold... if( false == Train->mvControlled->Mains ) { @@ -1337,13 +1581,6 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com // ...to open the circuit if( true == Train->m_linebreakerclosed ) { // safety check so we don't open the circuit right after closing - // NOTE: we don't have switch type definition for the line breaker switch - // so for the time being we have hard coded "impulse" switches for all EMUs - // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz - if( Train->mvControlled->TrainType == dt_EZT ) { - // a single impulse switch can't open the circuit, only close it - return; - } if( Train->mvControlled->MainSwitch( false ) ) { if( Train->ggMainOffButton.SubModel != nullptr ) { @@ -1393,24 +1630,21 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com // release... if( false == Train->mvControlled->Mains ) { // ...after opening circuit, or holding for too short time to close it - /* - if( mvControlled->ConverterAllow ) { - // po puszczeniu przycisku od WSa odpalanie potwora - mvControlled->ConverterSwitch( true ); - } - */ // hunter-091012: przeniesione z mover.pas, zeby dzwiek sie nie zapetlal, if( Train->fMainRelayTimer > 0.0f ) { Train->play_sound( Train->dsbRelay ); Train->fMainRelayTimer = 0.0f; } // we don't exactly know which of the two buttons was used, so reset both + // for setup with two separate swiches if( Train->ggMainOnButton.SubModel != nullptr ) { - // setup with two separate swiches Train->ggMainOnButton.UpdateValue( 0.0 ); + // audio feedback + if( Train->ggMainOnButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } } if( Train->ggMainOffButton.SubModel != nullptr ) { - // setup with two separate swiches Train->ggMainOffButton.UpdateValue( 0.0 ); } // and the two-state switch too, for good measure @@ -1429,6 +1663,10 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com // side-effects Train->mvControlled->ConverterSwitch( Train->ggConverterButton.GetValue() > 0.5 ); Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 ); + // audio feedback + if( Train->ggMainOnButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } // visual feedback if( Train->ggMainOnButton.SubModel != nullptr ) { // setup with two separate switches @@ -1487,8 +1725,15 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma else { //turn off // sound feedback - if( Train->ggConverterButton.GetValue() > 0.5 ) { - Train->play_sound( Train->dsbSwitch ); + if( Train->mvOccupied->ConvSwitchType == "impulse" ) { + if( Train->ggConverterOffButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + } + else { + if( Train->ggConverterButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } } // visual feedback Train->ggConverterButton.UpdateValue( 0.0 ); @@ -1507,10 +1752,13 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma Train->mvControlled->ConvOvldFlag = false; } // if there's no (low voltage) power source left, drop pantographs +/* + // NOTE: on second thought, don't and let them drop when the pantograph tank pressure drops below threshold if( false == Train->mvControlled->Battery ) { Train->mvControlled->PantFront( false ); Train->mvControlled->PantRear( false ); } +*/ } } } @@ -1529,6 +1777,40 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma } } +void TTrain::OnCommand_converteroverloadrelayreset( TTrain *Train, command_data const &Command ) { + + if( Train->ggConverterFuseButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Converter Overload Relay Reset button is missing, or wasn't defined" ); + } +// return; + } + + if( Command.action == GLFW_PRESS ) { + // press + if( ( Train->mvControlled->Mains == false ) + && ( Train->ggConverterButton.GetValue() < 0.05 ) + && ( Train->mvControlled->TrainType != dt_EZT ) ) { + Train->mvControlled->ConvOvldFlag = false; + } + // sound feedback + if( Train->ggConverterFuseButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggConverterFuseButton.UpdateValue( 1.0 ); + } + else if( Command.action == GLFW_RELEASE ) { + // release + // sound feedback + if( Train->ggConverterFuseButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggConverterFuseButton.UpdateValue( 0.0 ); + } +} + void TTrain::OnCommand_compressortoggle( TTrain *Train, command_data const &Command ) { if( Train->mvControlled->CompressorPower >= 2 ) { @@ -1596,6 +1878,9 @@ void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &C // TODO: don't rely on presense of 3d model to determine presence of the switch if( Train->ggStLinOffButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Open Motor Power Connectors button is missing, or wasn't defined" ); + } return; } @@ -1607,16 +1892,20 @@ void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &C Train->play_sound( Train->dsbRelay ); } Train->mvControlled->StLinSwitchOff = true; - // visual feedback - Train->ggStLinOffButton.UpdateValue( 1.0 ); // sound feedback if( Train->ggStLinOffButton.GetValue() < 0.05 ) { Train->play_sound( Train->dsbSwitch ); } + // visual feedback + Train->ggStLinOffButton.UpdateValue( 1.0 ); } else { // button released Train->mvControlled->StLinSwitchOff = false; + // sound feedback + if( Train->ggStLinOffButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } // visual feedback Train->ggStLinOffButton.UpdateValue( 0.0 ); } @@ -1651,6 +1940,36 @@ void TTrain::OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command } } +void TTrain::OnCommand_motoroverloadrelayreset( TTrain *Train, command_data const &Command ) { + + if( Train->ggFuseButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Motor Overload Relay Reset button is missing, or wasn't defined" ); + } +// return; + } + + if( Command.action == GLFW_PRESS ) { + // press + Train->mvControlled->FuseOn(); + // sound feedback + if( Train->ggFuseButton.GetValue() < 0.05 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggFuseButton.UpdateValue( 1.0 ); + } + else if( Command.action == GLFW_RELEASE ) { + // release + // sound feedback + if( Train->ggFuseButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggFuseButton.UpdateValue( 0.0 ); + } +} + void TTrain::OnCommand_headlighttoggleleft( TTrain *Train, command_data const &Command ) { if( Train->mvOccupied->LightsPosNo > 0 ) { @@ -2025,11 +2344,50 @@ void TTrain::OnCommand_redmarkertogglerearright( TTrain *Train, command_data con } } +void TTrain::OnCommand_headlightsdimtoggle( TTrain *Train, command_data const &Command ) { + + // NOTE: the check is disabled, as we're presuming light control is present in every vehicle + // TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels + if( Train->ggDimHeadlightsButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Dim Headlights switch is missing, or wasn't defined" ); + } + return; + } + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the switch doesn't flip back and forth if key is held down + if( false == Train->DynamicObject->DimHeadlights ) { + // turn on + Train->DynamicObject->DimHeadlights = true; + // audio feedback + if( Train->ggDimHeadlightsButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggDimHeadlightsButton.UpdateValue( 1.0 ); + } + else { + //turn off + Train->DynamicObject->DimHeadlights = false; + // audio feedback + if( Train->ggDimHeadlightsButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggDimHeadlightsButton.UpdateValue( 0.0 ); + } + } +} + void TTrain::OnCommand_interiorlighttoggle( TTrain *Train, command_data const &Command ) { // NOTE: the check is disabled, as we're presuming light control is present in every vehicle // TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels if( Train->ggCabLightButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Interior Light switch is missing, or wasn't defined" ); + } return; } @@ -2064,6 +2422,9 @@ void TTrain::OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const // TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels if( Train->ggCabLightDimButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Dim Interior Light switch is missing, or wasn't defined" ); + } return; } @@ -2097,6 +2458,9 @@ void TTrain::OnCommand_instrumentlighttoggle( TTrain *Train, command_data const // NOTE: the check is disabled, as we're presuming light control is present in every vehicle // TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels if( Train->ggUniversal3Button.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Universal3 switch is missing, or wasn't defined" ); + } return; } @@ -2129,6 +2493,9 @@ void TTrain::OnCommand_instrumentlighttoggle( TTrain *Train, command_data const void TTrain::OnCommand_heatingtoggle( TTrain *Train, command_data const &Command ) { if( Train->ggTrainHeatingButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Train Heating switch is missing, or wasn't defined" ); + } return; } @@ -2136,18 +2503,13 @@ void TTrain::OnCommand_heatingtoggle( TTrain *Train, command_data const &Command // only reacting to press, so the switch doesn't flip back and forth if key is held down if( false == Train->mvControlled->Heating ) { // turn on - if( ( ( Train->mvControlled->EngineType == ElectricSeriesMotor ) - && ( Train->mvControlled->Mains == true ) ) - || ( Train->mvControlled->ConverterFlag ) ) { - - Train->mvControlled->Heating = true; - // audio feedback - if( Train->ggTrainHeatingButton.GetValue() < 0.5 ) { - Train->play_sound( Train->dsbSwitch ); - } - // visual feedback - Train->ggTrainHeatingButton.UpdateValue( 1.0 ); + Train->mvControlled->Heating = true; + // audio feedback + if( Train->ggTrainHeatingButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); } + // visual feedback + Train->ggTrainHeatingButton.UpdateValue( 1.0 ); } else { //turn off @@ -2162,6 +2524,44 @@ void TTrain::OnCommand_heatingtoggle( TTrain *Train, command_data const &Command } } +void TTrain::OnCommand_doorlocktoggle( TTrain *Train, command_data const &Command ) { + + if( Train->ggDoorSignallingButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Door Lock switch is missing, or wasn't defined" ); + } + return; + } + + if( Command.action == GLFW_PRESS ) { + // only reacting to press, so the sound can loop uninterrupted + if( false == Train->mvControlled->DoorSignalling ) { + // turn on + // TODO: check wheter we really need separate flags for this + Train->mvControlled->DoorSignalling = true; + Train->mvOccupied->DoorBlocked = true; + // audio feedback + if( Train->ggDoorSignallingButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggDoorSignallingButton.UpdateValue( 1.0 ); + } + else { + // turn off + // TODO: check wheter we really need separate flags for this + Train->mvControlled->DoorSignalling = false; + Train->mvOccupied->DoorBlocked = false; + // audio feedback + if( Train->ggDoorSignallingButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggDoorSignallingButton.UpdateValue( 0.0 ); + } + } +} + void TTrain::OnCommand_doortoggleleft( TTrain *Train, command_data const &Command ) { if( Train->mvOccupied->DoorOpenCtrl != 1 ) { @@ -2287,6 +2687,9 @@ void TTrain::OnCommand_doortoggleright( TTrain *Train, command_data const &Comma void TTrain::OnCommand_departureannounce( TTrain *Train, command_data const &Command ) { if( Train->ggDepartureSignalButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Departure Signal button is missing, or wasn't defined" ); + } return; } @@ -2315,37 +2718,114 @@ void TTrain::OnCommand_departureannounce( TTrain *Train, command_data const &Com } } -void TTrain::OnCommand_doorlocktoggle( TTrain *Train, command_data const &Command ) { +void TTrain::OnCommand_hornlowactivate( TTrain *Train, command_data const &Command ) { - if( Train->ggDoorSignallingButton.SubModel == nullptr ) { + if( Train->ggHornButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Horn button is missing, or wasn't defined" ); + } + return; + } + + if( Command.action == GLFW_PRESS ) { + // only need to react to press, sound will continue until stopped + if( false == TestFlag( Train->mvOccupied->WarningSignal, 1 ) ) { + // turn on + Train->mvOccupied->WarningSignal |= 1; + if( true == TestFlag( Train->mvOccupied->WarningSignal, 2 ) ) { + // low and high horn are treated as mutually exclusive + Train->mvControlled->WarningSignal &= ~2; + } + // audio feedback + if( Train->ggHornButton.GetValue() > -0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggHornButton.UpdateValue( -1.0 ); + } + } + else if( Command.action == GLFW_RELEASE ) { + // turn off + // NOTE: we turn off both low and high horn, due to unreliability of release event when shift key is involved + Train->mvControlled->WarningSignal &= ~( 1 | 2 ); + // audio feedback + if( Train->ggHornButton.GetValue() < -0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggHornButton.UpdateValue( 0.0 ); + } +} + +void TTrain::OnCommand_hornhighactivate( TTrain *Train, command_data const &Command ) { + + if( Train->ggHornButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Horn button is missing, or wasn't defined" ); + } + return; + } + + if( Command.action == GLFW_PRESS ) { + // only need to react to press, sound will continue until stopped + if( false == TestFlag( Train->mvOccupied->WarningSignal, 2 ) ) { + // turn on + Train->mvOccupied->WarningSignal |= 2; + if( true == TestFlag( Train->mvOccupied->WarningSignal, 1 ) ) { + // low and high horn are treated as mutually exclusive + Train->mvControlled->WarningSignal &= ~1; + } + // audio feedback + if( Train->ggHornButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggHornButton.UpdateValue( 1.0 ); + } + } + else if( Command.action == GLFW_RELEASE ) { + // turn off + // NOTE: we turn off both low and high horn, due to unreliability of release event when shift key is involved + Train->mvControlled->WarningSignal &= ~( 1 | 2 ); + // audio feedback + if( Train->ggHornButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggHornButton.UpdateValue( 0.0 ); + } +} + +void TTrain::OnCommand_radiotoggle( TTrain *Train, command_data const &Command ) { + + if( Train->ggRadioButton.SubModel == nullptr ) { + if( Command.action == GLFW_PRESS ) { + WriteLog( "Radio switch is missing, or wasn't defined" ); + } return; } if( Command.action == GLFW_PRESS ) { // only reacting to press, so the sound can loop uninterrupted - if( false == Train->mvControlled->DoorSignalling ) { + if( false == Train->mvOccupied->Radio ) { // turn on - // TODO: check wheter we really need separate flags for this - Train->mvControlled->DoorSignalling = true; - Train->mvOccupied->DoorBlocked = true; + Train->mvOccupied->Radio = true; // audio feedback - if( Train->ggDoorSignallingButton.GetValue() < 0.5 ) { + if( Train->ggRadioButton.GetValue() < 0.5 ) { Train->play_sound( Train->dsbSwitch ); } // visual feedback - Train->ggDoorSignallingButton.UpdateValue( 1.0 ); + Train->ggRadioButton.UpdateValue( 1.0 ); } else { // turn off - // TODO: check wheter we really need separate flags for this - Train->mvControlled->DoorSignalling = false; - Train->mvOccupied->DoorBlocked = false; + Train->mvOccupied->Radio = false; // audio feedback - if( Train->ggDoorSignallingButton.GetValue() > 0.5 ) { + if( Train->ggRadioButton.GetValue() > 0.5 ) { Train->play_sound( Train->dsbSwitch ); } // visual feedback - Train->ggDoorSignallingButton.UpdateValue( 0.0 ); + Train->ggRadioButton.UpdateValue( 0.0 ); } } } @@ -2372,7 +2852,6 @@ void TTrain::OnKeyDown(int cKey) dsbNastawnikJazdy->Play(0, 0, 0); } } -#endif if (cKey == Global::Keys[k_DirectionBackward]) { if (mvOccupied->Radio == false) @@ -2382,7 +2861,6 @@ void TTrain::OnKeyDown(int cKey) mvOccupied->Radio = true; } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_DecMainCtrlFAST]) if (mvControlled->DecMainCtrl(2)) { @@ -2460,7 +2938,6 @@ void TTrain::OnKeyDown(int cKey) } } } -#endif if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // shift&ctrl are used for light dimming { if (mvControlled->TrainType == dt_EZT) @@ -2472,9 +2949,9 @@ void TTrain::OnKeyDown(int cKey) } } } - else if (cKey == Global::Keys[k_Sand]) + else + if( cKey == Global::Keys[ k_Sand ] ) { -#ifdef EU07_USE_OLD_COMMAND_SYSTEM if( mvControlled->TrainType == dt_EZT ) { if (ggDoorSignallingButton.SubModel != NULL) @@ -2488,7 +2965,6 @@ void TTrain::OnKeyDown(int cKey) } } else if (mvControlled->TrainType != dt_EZT) -#endif { if (ggSandButton.SubModel != NULL) { @@ -2498,7 +2974,6 @@ void TTrain::OnKeyDown(int cKey) } } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM if( cKey == Global::Keys[ k_Main ] ) { if (fabs(ggMainOnButton.GetValue()) < 0.001) @@ -2508,8 +2983,9 @@ void TTrain::OnKeyDown(int cKey) dsbSwitch->Play(0, 0, 0); } } + else #endif - else if (cKey == Global::Keys[k_BrakeProfile]) // McZapkie-240302-B: + if( cKey == Global::Keys[ k_BrakeProfile ] ) // McZapkie-240302-B: //----------- // przelacznik opoznienia @@ -2535,13 +3011,11 @@ void TTrain::OnKeyDown(int cKey) else { TDynamicObject *temp; - temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, 1500, - CouplNr)); + temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, 1500, CouplNr)); if (temp == NULL) { CouplNr = -2; - temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, - CouplNr)); + temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, CouplNr)); } if (temp) { @@ -2581,7 +3055,6 @@ void TTrain::OnKeyDown(int cKey) dsbSwitch->Play(0, 0, 0); } } -#endif else if( cKey == Global::Keys[ k_SmallCompressor ] ) // Winger 160404: mala // sprezarka wl { // Ra: dźwięk, gdy razem z [Shift] @@ -2589,7 +3062,7 @@ void TTrain::OnKeyDown(int cKey) !mvOccupied->ActiveCab) // tylko w maszynowym if (Global::ctrlState) // z [Ctrl] mvControlled->bPantKurek3 = true; // zbiornik pantografu połączony - // jest ze zbiornikiem głównym + // jest ze zbiornikiem głównym // (pompowanie nie ma sensu) else if (!mvControlled->PantCompFlag) // jeśli wyłączona if (mvControlled->Battery) // jeszcze musi być załączona bateria @@ -2599,7 +3072,8 @@ void TTrain::OnKeyDown(int cKey) play_sound( dsbSwitch ); // dźwięk tylko po naciśnięciu klawisza } } - else if (cKey == GLFW_KEY_Q) // ze Shiftem - włączenie AI +#endif + else if( cKey == GLFW_KEY_Q ) // ze Shiftem - włączenie AI { // McZapkie-240302 - wlaczanie automatycznego pilota (zadziala tylko w // trybie debugmode) if (DynamicObject->Mechanik) @@ -3238,8 +3712,6 @@ void TTrain::OnKeyDown(int cKey) else keybrakecount+=1; */ } -#endif -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if( cKey == Global::Keys[ k_EmergencyBrake ] ) { // while (mvOccupied->IncBrakeLevel()); @@ -3341,7 +3813,6 @@ void TTrain::OnKeyDown(int cKey) } // ggSecurityResetButton.PutValue(1); } -#endif else if( cKey == Global::Keys[ k_AntiSlipping ] ) //--------------- // hunter-221211: hamulec przeciwposlizgowy przeniesiony do @@ -3359,7 +3830,7 @@ void TTrain::OnKeyDown(int cKey) // ggAntiSlipButton.PutValue(1); } } - else if (cKey == Global::Keys[k_Fuse]) + else if( cKey == Global::Keys[ k_Fuse ] ) //--------------- { if (Global::ctrlState) // z controlem @@ -3375,7 +3846,6 @@ void TTrain::OnKeyDown(int cKey) mvControlled->FuseOn(); } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (cKey == Global::Keys[k_DirectionForward]) // McZapkie-240302 - zmiana kierunku: 'd' do przodu, 'r' do tylu { @@ -3402,7 +3872,6 @@ void TTrain::OnKeyDown(int cKey) Change_direction); // aktualizacja skrajnych pojazdów w składzie } } -#endif else if (cKey == Global::Keys[k_DirectionBackward]) // r { if (Global::ctrlState) @@ -3413,7 +3882,6 @@ void TTrain::OnKeyDown(int cKey) mvOccupied->Radio = false; } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (mvOccupied->DirectionBackward()) { //------------ @@ -3436,9 +3904,7 @@ void TTrain::OnKeyDown(int cKey) DynamicObject->Mechanik->CheckVehicles( Change_direction); // aktualizacja skrajnych pojazdów w składzie } -#endif } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if( cKey == Global::Keys[ k_Main ] ) // McZapkie-240302 - wylaczanie glownego obwodu //----------- @@ -3506,13 +3972,11 @@ void TTrain::OnKeyDown(int cKey) else { TDynamicObject *temp; - temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, 1500, - CouplNr)); + temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, 1500, CouplNr)); if (temp == NULL) { CouplNr = -2; - temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, - CouplNr)); + temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, CouplNr)); } if (temp) { @@ -3575,7 +4039,6 @@ void TTrain::OnKeyDown(int cKey) } } } -#endif else if (cKey == Global::Keys[k_SmallCompressor]) // Winger 160404: mala sprezarka wl { // Ra: bez [Shift] też dać dźwięk if ((mvControlled->TrainType & dt_EZT) ? mvControlled == mvOccupied : @@ -3584,7 +4047,7 @@ void TTrain::OnKeyDown(int cKey) mvControlled->bPantKurek3 = false; // zbiornik pantografu połączony jest z małą sprężarką // (pompowanie ma sens, ale potem trzeba przełączyć) - else if (!mvControlled->PantCompFlag) // jeśli wyłączona + else if( !mvControlled->PantCompFlag ) // jeśli wyłączona if (mvControlled->Battery) // jeszcze musi być załączona bateria if (mvControlled->PantPress < 4.8) // piszą, że to tak nie działa { @@ -3592,6 +4055,7 @@ void TTrain::OnKeyDown(int cKey) play_sound( dsbSwitch ); // dźwięk tylko po naciśnięciu klawisza } } +#endif // McZapkie-240302 - wylaczanie automatycznego pilota (w trybie ~debugmode // mozna tylko raz) else if (cKey == GLFW_KEY_Q) // bez Shift @@ -3620,10 +4084,8 @@ void TTrain::OnKeyDown(int cKey) play_sound( dsbSwitch ); } } -#endif // hunter-201211: piasecznica poprawiona oraz przeniesiona do // TTrain::Update() -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if( cKey == Global::Keys[ k_Sand ] ) { /* @@ -3841,9 +4303,10 @@ if } } } - if (DynamicObject->Mechanik) // na wszelki wypadek - DynamicObject->Mechanik->CheckVehicles( - Disconnect); // aktualizacja skrajnych pojazdów w składzie + if( DynamicObject->Mechanik ) { + // aktualizacja skrajnych pojazdów w składzie + DynamicObject->Mechanik->CheckVehicles( Disconnect ); + } } } #ifdef EU07_USE_OLD_COMMAND_SYSTEM @@ -4248,11 +4711,9 @@ if } } } -#endif else if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // Winger 110904: wylacznik st. // liniowych { -#ifdef EU07_USE_OLD_COMMAND_SYSTEM if( ( mvControlled->TrainType != dt_EZT ) && ( mvControlled->TrainType != dt_EP05 ) && (mvControlled->TrainType != dt_ET40)) { @@ -4265,7 +4726,6 @@ if play_sound( dsbRelay ); } } -#endif if (mvControlled->TrainType == dt_EZT) { if (mvControlled->Signalling == true) @@ -4275,6 +4735,7 @@ if } } } +#endif else { // McZapkie: poruszanie sie po kabinie, w updatemechpos zawarte sa wiezy @@ -4379,7 +4840,7 @@ if ++iRadioChannel; // 0=wyłączony } } - +#ifdef EU07_USE_OLD_COMMAND_SYSTEM // TODO: break the mess above into individual command-based routines. // TODO: test for modifiers inside the routines, instead of grouping by the modifier // TODO: do away with the modifier tests, each command should be separate and issued by input processor(s) up the chain @@ -4400,6 +4861,7 @@ if play_sound( dsbSwitch ); } } +#endif } void TTrain::OnKeyUp(int cKey) @@ -4571,7 +5033,23 @@ bool TTrain::Update( double const Deltatime ) DWORD stat; double dt = Deltatime; // Timer::GetDeltaTime(); - +/* + // NOTE: disabled while switch state isn't preserved while moving between compartments + // check whether we should raise the pantographs, based on volume in pantograph tank + if( mvControlled->PantPress > ( + mvControlled->TrainType == dt_EZT ? + 2.4 : + 3.5 ) ) { + if( ( false == mvControlled->PantFrontUp ) + && ( ggPantFrontButton.GetValue() > 0.95 ) ) { + mvControlled->PantFront( true ); + } + if( ( false == mvControlled->PantRearUp ) + && ( ggPantRearButton.GetValue() > 0.95 ) ) { + mvControlled->PantRear( true ); + } + } +*/ if (DynamicObject->mdKabina) { // Ra: TODO: odczyty klawiatury/pulpitu nie // powinny być uzależnione od istnienia modelu @@ -5838,7 +6316,9 @@ bool TTrain::Update( double const Deltatime ) ggMainButton.Update(); if (ggRadioButton.SubModel) { - ggRadioButton.PutValue(mvOccupied->Radio ? 1 : 0); +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + ggRadioButton.PutValue( mvOccupied->Radio ? 1 : 0 ); +#endif ggRadioButton.Update(); } if (ggConverterButton.SubModel) @@ -5994,8 +6474,9 @@ bool TTrain::Update( double const Deltatime ) ggLightsButton.Update(); } if( ggDimHeadlightsButton.SubModel ) { - +#ifdef EU07_USE_OLD_COMMAND_SYSTEM ggDimHeadlightsButton.PutValue( DynamicObject->DimHeadlights ? 1.0 : 0.0 ); +#endif ggDimHeadlightsButton.Update(); } @@ -6033,7 +6514,9 @@ bool TTrain::Update( double const Deltatime ) } if (ggSignallingButton.SubModel != nullptr) { - ggSignallingButton.PutValue(mvControlled->Signalling ? 1 : 0); +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + ggSignallingButton.PutValue( mvControlled->Signalling ? 1 : 0 ); +#endif ggSignallingButton.Update(); } if (ggDoorSignallingButton.SubModel != nullptr) @@ -6122,7 +6605,8 @@ bool TTrain::Update( double const Deltatime ) //****************************************** // przelaczniki - if (Console::Pressed(Global::Keys[k_Horn])) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( Console::Pressed( Global::Keys[ k_Horn ] ) ) { if (Global::shiftState) { @@ -6152,7 +6636,6 @@ bool TTrain::Update( double const Deltatime ) SetFlag(mvOccupied->WarningSignal, 2); } //---------------- -#ifdef EU07_USE_OLD_COMMAND_SYSTEM // hunter-141211: wyl. szybki zalaczony i wylaczony przeniesiony z // OnKeyPress() if (Global::shiftState && Console::Pressed(Global::Keys[k_Main])) @@ -6295,7 +6778,8 @@ bool TTrain::Update( double const Deltatime ) } */ - if (Console::Pressed(Global::Keys[k_Sand])) +#ifdef EU07_USE_OLD_COMMAND_SYSTEM + if( Console::Pressed( Global::Keys[ k_Sand ] ) ) { if (mvControlled->TrainType != dt_EZT && ggSandButton.SubModel != NULL) { @@ -6327,7 +6811,6 @@ bool TTrain::Update( double const Deltatime ) else ggAntiSlipButton.UpdateValue(0); //----------------- -#ifdef EU07_USE_OLD_COMMAND_SYSTEM // hunter-261211: przetwornica i sprezarka if (Global::shiftState && Console::Pressed(Global::Keys[k_Converter])) // NBMX 14-09-2003: przetwornica wl @@ -6438,12 +6921,23 @@ bool TTrain::Update( double const Deltatime ) ggUniversal1Button.DecValue(dt / 2); } } +#ifdef EU07_USE_OLD_COMMAND_SYSTEM if (!Console::Pressed(Global::Keys[k_SmallCompressor])) // Ra: przecieść to na zwolnienie klawisza if (DynamicObject->Mechanik ? !DynamicObject->Mechanik->AIControllFlag : false) // nie wyłączać, gdy AI mvControlled->PantCompFlag = false; // wyłączona, gdy nie trzymamy klawisza - +#else + if( ( ( DynamicObject->Mechanik != nullptr ) + && ( false == DynamicObject->Mechanik->AIControllFlag ) ) + && ( mvControlled->TrainType == dt_EZT ? + ( mvControlled != mvOccupied ) : + ( mvOccupied->ActiveCab != 0 ) ) ) { + // HACK: if we're in one of the cabs we can't be activating pantograph compressor + // NOTE: this will break in multiplayer setups, do a proper tracking of pantograph user then + mvControlled->PantCompFlag = false; + } +#endif if (Console::Pressed(Global::Keys[k_Univ2])) { if (!DebugModeFlag) @@ -6703,7 +7197,6 @@ bool TTrain::Update( double const Deltatime ) } else ggMainButton.PutValue(0); -#endif if (Console::Pressed(Global::Keys[k_CurrentNext])) { if (mvControlled->TrainType != dt_EZT) @@ -6718,7 +7211,6 @@ bool TTrain::Update( double const Deltatime ) } } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else { if (Global::shiftState) @@ -6745,7 +7237,6 @@ bool TTrain::Update( double const Deltatime ) } } } -#endif } else { @@ -6759,7 +7250,6 @@ bool TTrain::Update( double const Deltatime ) } } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM // Winger 010304 PantAllDownButton if (Console::Pressed(Global::Keys[k_PantFrontUp])) { @@ -6855,6 +7345,7 @@ bool TTrain::Update( double const Deltatime ) ggPantFrontButton.Update(); ggPantRearButton.Update(); ggPantFrontButtonOff.Update(); + ggPantRearButtonOff.Update(); ggUpperLightButton.Update(); ggLeftLightButton.Update(); ggRightLightButton.Update(); @@ -6891,15 +7382,12 @@ bool TTrain::Update( double const Deltatime ) ggMainOnButton.UpdateValue(0); ggSecurityResetButton.UpdateValue(0); ggReleaserButton.UpdateValue(0); -#endif ggSandButton.UpdateValue(0); ggAntiSlipButton.UpdateValue(0); -#ifdef EU07_USE_OLD_COMMAND_SYSTEM ggDepartureSignalButton.UpdateValue( 0 ); -#endif ggFuseButton.UpdateValue( 0 ); ggConverterFuseButton.UpdateValue(0); - +#endif pyScreens.update(); } // wyprowadzenie sygnałów dla haslera na PoKeys (zaznaczanie na taśmie) @@ -7759,13 +8247,15 @@ void TTrain::clear_cab_controls() // NOTE: we can get rid of this function once we have per-cab persistent state void TTrain::set_cab_controls() { - // switches // battery if( true == mvOccupied->Battery ) { ggBatteryButton.PutValue( 1.0 ); } - + // radio + if( true == mvOccupied->Radio ) { + ggRadioButton.PutValue( 1.0 ); + } // pantographs if( mvOccupied->PantSwitchType != "impulse" ) { ggPantFrontButton.PutValue( @@ -7781,7 +8271,6 @@ void TTrain::set_cab_controls() { 0.0 : 1.0 ); } - if( mvOccupied->PantSwitchType != "impulse" ) { ggPantRearButton.PutValue( ( mvOccupied->ActiveCab == 1 ? @@ -7796,7 +8285,6 @@ void TTrain::set_cab_controls() { 0.0 : 1.0 ); } - // converter if( mvOccupied->ConvSwitchType != "impulse" ) { ggConverterButton.PutValue( @@ -7804,17 +8292,14 @@ void TTrain::set_cab_controls() { 1.0 : 0.0 ); } - // compressor if( true == mvControlled->CompressorAllow ) { ggCompressorButton.PutValue( 1.0 ); } - // motor overload relay threshold / shunt mode if( mvControlled->Imax == mvControlled->ImaxHi ) { ggMaxCurrentCtrl.PutValue( 1.0 ); } - // lights int const lightsindex = ( mvOccupied->ActiveCab == 1 ? @@ -7836,7 +8321,9 @@ void TTrain::set_cab_controls() { if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_right ) != 0 ) { ggRightEndLightButton.PutValue( 1.0 ); } - + if( true == DynamicObject->DimHeadlights ) { + ggDimHeadlightsButton.PutValue( 1.0 ); + } // cab lights if( true == bCabLight ) { ggCabLightButton.PutValue( 1.0 ); @@ -7847,7 +8334,6 @@ void TTrain::set_cab_controls() { if( true == LampkaUniversal3_st ) { ggUniversal3Button.PutValue( 1.0 ); } - // doors // NOTE: we're relying on the cab models to have switches reversed for the rear cab(?) ggDoorLeftButton.PutValue( mvOccupied->DoorLeftOpened ? 1.0 : 0.0 ); @@ -7856,14 +8342,11 @@ void TTrain::set_cab_controls() { if( true == mvControlled->DoorSignalling ) { ggDoorSignallingButton.PutValue( 1.0 ); } - // heating if( true == mvControlled->Heating ) { ggTrainHeatingButton.PutValue( 1.0 ); } - // brake acting time - // visual feedback if( ggBrakeProfileCtrl.SubModel != nullptr ) { ggBrakeProfileCtrl.PutValue( ( ( mvOccupied->BrakeDelayFlag & bdelay_R ) != 0 ? @@ -7882,10 +8365,19 @@ void TTrain::set_cab_controls() { 1.0 : 0.0 ); } - + // brake signalling + ggSignallingButton.PutValue( + mvControlled->Signalling ? + 1.0 : + 0.0 ); + // multiple-unit current indicator source + ggNextCurrentButton.PutValue( + ShowNextCurrent ? + 1.0 : + 0.0 ); + // we reset all indicators, as they're set during the update pass // TODO: when cleaning up break setting indicator state into a separate function, so we can reuse it - } // initializes a button matching provided label. returns: true if the label was found, false diff --git a/Train.h b/Train.h index 875b9f32..1bce34d6 100644 --- a/Train.h +++ b/Train.h @@ -120,6 +120,7 @@ class TTrain static void OnCommand_secondcontrollerdecrease( TTrain *Train, command_data const &Command ); static void OnCommand_secondcontrollerdecreasefast( TTrain *Train, command_data const &Command ); static void OnCommand_notchingrelaytoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_mucurrentindicatorsourcetoggle( TTrain *Train, command_data const &Command ); static void OnCommand_independentbrakeincrease( TTrain *Train, command_data const &Command ); static void OnCommand_independentbrakeincreasefast( TTrain *Train, command_data const &Command ); static void OnCommand_independentbrakedecrease( TTrain *Train, command_data const &Command ); @@ -133,21 +134,28 @@ class TTrain static void OnCommand_trainbrakeservice( TTrain *Train, command_data const &Command ); static void OnCommand_trainbrakefullservice( TTrain *Train, command_data const &Command ); static void OnCommand_trainbrakeemergency( TTrain *Train, command_data const &Command ); + static void OnCommand_wheelspinbrakeactivate( TTrain *Train, command_data const &Command ); + static void OnCommand_sandboxactivate( TTrain *Train, command_data const &Command ); 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_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 ); static void OnCommand_alerteracknowledge( TTrain *Train, command_data const &Command ); static void OnCommand_batterytoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_pantographcompressorvalvetoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_pantographcompressoractivate( TTrain *Train, command_data const &Command ); static void OnCommand_pantographtogglefront( TTrain *Train, command_data const &Command ); static void OnCommand_pantographtogglerear( TTrain *Train, command_data const &Command ); static void OnCommand_pantographlowerall( TTrain *Train, command_data const &Command ); static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ); static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_converteroverloadrelayreset( TTrain *Train, command_data const &Command ); static void OnCommand_compressortoggle( TTrain *Train, command_data const &Command ); static void OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ); static void OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_motoroverloadrelayreset( TTrain *Train, command_data const &Command ); static void OnCommand_heatingtoggle( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttoggleleft( TTrain *Train, command_data const &Command ); static void OnCommand_headlighttoggleright( TTrain *Train, command_data const &Command ); @@ -159,13 +167,17 @@ 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_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 ); static void OnCommand_instrumentlighttoggle( TTrain *Train, command_data const &Command ); + 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_departureannounce( TTrain *Train, command_data const &Command ); - static void OnCommand_doorlocktoggle( 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 ); // members TDynamicObject *DynamicObject; // przestawia zmiana pojazdu [F5] @@ -222,8 +234,7 @@ public: // reszta może by?publiczna TGauge ggSandButton; // guzik piasecznicy TGauge ggAntiSlipButton; TGauge ggFuseButton; - TGauge ggConverterFuseButton; // hunter-261211: przycisk odblokowania - // nadmiarowego przetwornic i ogrzewania + TGauge ggConverterFuseButton; // hunter-261211: przycisk odblokowania nadmiarowego przetwornic i ogrzewania TGauge ggStLinOffButton; TGauge ggRadioButton; TGauge ggUpperLightButton; diff --git a/command.cpp b/command.cpp index cdc811a7..6d75124e 100644 --- a/command.cpp +++ b/command.cpp @@ -27,6 +27,7 @@ commanddescription_sequence Commands_descriptions = { { "secondcontrollerincreasefast", command_target::vehicle }, { "secondcontrollerdecrease", command_target::vehicle }, { "secondcontrollerdecreasefast", command_target::vehicle }, + { "mucurrentindicatorsourcetoggle", command_target::vehicle }, { "independentbrakeincrease", command_target::vehicle }, { "independentbrakeincreasefast", command_target::vehicle }, { "independentbrakedecrease", command_target::vehicle }, @@ -40,30 +41,26 @@ commanddescription_sequence Commands_descriptions = { { "trainbrakeservice", command_target::vehicle }, { "trainbrakefullservice", command_target::vehicle }, { "trainbrakeemergency", command_target::vehicle }, -/* -const int k_AntiSlipping = 21; -const int k_Sand = 22; -*/ + { "wheelspinbrakeactivate", command_target::vehicle }, + { "sandboxactivate", command_target::vehicle }, { "reverserincrease", command_target::vehicle }, { "reverserdecrease", command_target::vehicle }, { "linebreakertoggle", command_target::vehicle }, -/* -const int k_Fuse = 26; -*/ { "convertertoggle", command_target::vehicle }, + { "converteroverloadrelayreset", command_target::vehicle }, { "compressortoggle", 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 }, -/* -const int k_BrakeProfile = 31; -*/ + { "mubrakingindicatortoggle", command_target::vehicle }, { "alerteracknowledge", command_target::vehicle }, + { "hornlowactivate", command_target::vehicle }, + { "hornhighctivate", command_target::vehicle }, + { "radiotoggle", command_target::vehicle }, /* -const int k_Horn = 33; -const int k_Horn2 = 34; const int k_FailedEngineCutOff = 35; */ { "viewturn", command_target::entity }, @@ -93,6 +90,8 @@ const int k_ProgramHelp = 48; { "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 }, @@ -110,13 +109,8 @@ const int k_ProgramHelp = 48; { "headlighttogglerearupper", command_target::vehicle }, { "redmarkertogglerearleft", command_target::vehicle }, { "redmarkertogglerearright", command_target::vehicle }, -/* -const int k_SmallCompressor = 63; -*/ + { "headlightsdimtoggle", command_target::vehicle }, { "motorconnectorsopen", command_target::vehicle }, -/* -const int k_CurrentNext = 65; -*/ { "interiorlighttoggle", command_target::vehicle }, { "interiorlightdimtoggle", command_target::vehicle }, { "instrumentlighttoggle", command_target::vehicle }, @@ -131,7 +125,6 @@ const int k_Active = 71; { "batterytoggle", command_target::vehicle } /* const int k_WalkMode = 73; -int const k_DimHeadlights = 74; */ }; @@ -192,7 +185,23 @@ command_relay::post( user_command const Command, std::uint64_t const Param1, std if( Action != GLFW_RELEASE ) { // key was pressed or is still held if( false == command.name.empty() ) { - WriteLog( "Command issued: " + command.name ); + if( false == ( + ( Command == user_command::moveleft ) + || ( Command == user_command::moveleftfast ) + || ( Command == user_command::moveright ) + || ( Command == user_command::moverightfast ) + || ( Command == user_command::moveforward ) + || ( Command == user_command::moveforwardfast ) + || ( Command == user_command::moveback ) + || ( Command == user_command::movebackfast ) + || ( Command == user_command::moveup ) + || ( Command == user_command::moveupfast ) + || ( Command == user_command::movedown ) + || ( Command == user_command::movedownfast ) + || ( Command == user_command::movevector ) + || ( Command == user_command::viewturn ) ) ) { + WriteLog( "Command issued: " + command.name ); + } } } /* diff --git a/command.h b/command.h index 5f0e4414..2be03a0c 100644 --- a/command.h +++ b/command.h @@ -22,6 +22,7 @@ enum class user_command { secondcontrollerincreasefast, secondcontrollerdecrease, secondcontrollerdecreasefast, + mucurrentindicatorsourcetoggle, independentbrakeincrease, independentbrakeincreasefast, independentbrakedecrease, @@ -35,27 +36,26 @@ enum class user_command { trainbrakeservice, trainbrakefullservice, trainbrakeemergency, -/* -const int k_AntiSlipping = 21; -const int k_Sand = 22; -*/ + wheelspinbrakeactivate, + sandboxactivate, reverserincrease, reverserdecrease, linebreakertoggle, -/* -const int k_Fuse = 26; -*/ convertertoggle, + converteroverloadrelayreset, compressortoggle, motoroverloadrelaythresholdtoggle, + motoroverloadrelayreset, notchingrelaytoggle, epbrakecontroltoggle, brakeactingspeedincrease, brakeactingspeeddecrease, + mubrakingindicatortoggle, alerteracknowledge, + hornlowactivate, + hornhighactivate, + radiotoggle, /* -const int k_Horn = 33; -const int k_Horn2 = 34; const int k_FailedEngineCutOff = 35; */ viewturn, @@ -85,6 +85,8 @@ const int k_ProgramHelp = 48; doortoggleright, departureannounce, doorlocktoggle, + pantographcompressorvalvetoggle, + pantographcompressoractivate, pantographtogglefront, pantographtogglerear, pantographlowerall, @@ -102,13 +104,8 @@ const int k_ProgramHelp = 48; headlighttogglerearupper, redmarkertogglerearleft, redmarkertogglerearright, -/* -const int k_SmallCompressor = 63; -*/ + headlightsdimtoggle, motorconnectorsopen, -/* -const int k_CurrentNext = 65; -*/ interiorlighttoggle, interiorlightdimtoggle, instrumentlighttoggle, @@ -123,7 +120,6 @@ const int k_Active = 71; batterytoggle /* const int k_WalkMode = 73; -int const k_DimHeadlights = 74; */ }; diff --git a/keyboardinput.cpp b/keyboardinput.cpp index 0c447184..af3e3ef8 100644 --- a/keyboardinput.cpp +++ b/keyboardinput.cpp @@ -108,6 +108,8 @@ keyboard_input::default_bindings() { { GLFW_KEY_KP_MULTIPLY }, // secondcontrollerdecreasefast { GLFW_KEY_KP_MULTIPLY | keymodifier::shift }, + // mucurrentindicatorsourcetoggle + { GLFW_KEY_Z | keymodifier::shift }, // independentbrakeincrease { GLFW_KEY_KP_1 }, // independentbrakeincreasefast @@ -134,25 +136,26 @@ keyboard_input::default_bindings() { { GLFW_KEY_KP_2 }, // trainbrakeemergency { GLFW_KEY_KP_0 }, -/* -const int k_AntiSlipping = 21; -const int k_Sand = 22; -*/ + // wheelspinbrakeactivate, + { GLFW_KEY_KP_ENTER }, + // sandboxactivate, + { GLFW_KEY_S }, // reverserincrease { GLFW_KEY_D }, // reverserdecrease { GLFW_KEY_R }, // linebreakertoggle { GLFW_KEY_M }, -/* -const int k_Fuse = 26; -*/ // convertertoggle { GLFW_KEY_X }, + // converteroverloadrelayreset + { GLFW_KEY_N | keymodifier::control }, // compressortoggle { GLFW_KEY_C }, // motoroverloadrelaythresholdtoggle { GLFW_KEY_F }, + // motoroverloadrelayreset + { GLFW_KEY_N }, // notchingrelaytoggle { GLFW_KEY_G }, // epbrakecontroltoggle @@ -161,14 +164,17 @@ const int k_Fuse = 26; { GLFW_KEY_B | keymodifier::shift }, // brakeactingspeeddecrease { GLFW_KEY_B }, -/* -const int k_BrakeProfile = 31; -*/ + // brakingindicatortoggle + { GLFW_KEY_L | keymodifier::shift }, // alerteracknowledge { GLFW_KEY_SPACE }, + // hornlowactivate + { GLFW_KEY_A }, + // hornhighactivate + { GLFW_KEY_A | keymodifier::shift }, + // radiotoggle + { GLFW_KEY_R | keymodifier::control }, /* -const int k_Horn = 33; -const int k_Horn2 = 34; const int k_FailedEngineCutOff = 35; */ // viewturn @@ -216,6 +222,10 @@ const int k_ProgramHelp = 48; { GLFW_KEY_SLASH }, // doorlocktoggle { GLFW_KEY_S | keymodifier::shift }, + // pantographcompressorvalvetoggle + { GLFW_KEY_V | keymodifier::control }, + // pantographcompressoractivate + { GLFW_KEY_V | keymodifier::shift }, // pantographtogglefront { GLFW_KEY_P }, // pantographtogglerear @@ -247,14 +257,10 @@ const int k_ProgramHelp = 48; { GLFW_KEY_Y | keymodifier::control | keymodifier::shift }, // redmarkertogglerearright { GLFW_KEY_I | keymodifier::control | keymodifier::shift }, -/* -const int k_SmallCompressor = 63; -*/ + // headlightsdimtoggle + { GLFW_KEY_L | keymodifier::control }, // motorconnectorsopen { GLFW_KEY_L }, -/* -const int k_CurrentNext = 65; -*/ // interiorlighttoggle { GLFW_KEY_APOSTROPHE }, // interiorlightdimtoggle @@ -273,7 +279,6 @@ const int k_Active = 71; { GLFW_KEY_J } /* const int k_WalkMode = 73; -int const k_DimHeadlights = 74; */ }; diff --git a/windows.cpp b/windows.cpp index 49ef578b..dd23a74d 100644 --- a/windows.cpp +++ b/windows.cpp @@ -18,7 +18,7 @@ LONG CALLBACK unhandled_handler(::EXCEPTION_POINTERS* e) { auto nameEnd = name + ::GetModuleFileNameA(::GetModuleHandleA(0), name, MAX_PATH); ::SYSTEMTIME t; - ::GetSystemTime(&t); + ::GetLocalTime(&t); wsprintfA(nameEnd - strlen(".exe"), "_crashdump_%4d%02d%02d_%02d%02d%02d.dmp", t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond); From e84f4f53fdcadfd6affe260a5b4b18b51944ca32 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Sun, 23 Apr 2017 13:16:28 +0200 Subject: [PATCH 10/12] added support for redefinition of keyboard bindings. control for engine cutoff, minor changes to line breaker activation --- EU07.cpp | 1 + Train.cpp | 252 ++++++++++++++++++++++++++-------------------- Train.h | 5 +- command.cpp | 12 +-- command.h | 3 +- keyboardinput.cpp | 94 +++++++++++++++-- keyboardinput.h | 4 +- 7 files changed, 245 insertions(+), 126 deletions(-) diff --git a/EU07.cpp b/EU07.cpp index f36b2573..4fbfa0c9 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -345,6 +345,7 @@ int main(int argc, char *argv[]) return -1; } + input::Keyboard.init(); input::Gamepad.init(); Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów diff --git a/Train.cpp b/Train.cpp index fdea2409..70fb0519 100644 --- a/Train.cpp +++ b/Train.cpp @@ -144,7 +144,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::secondcontrollerdecrease, &TTrain::OnCommand_secondcontrollerdecrease }, { user_command::secondcontrollerdecreasefast, &TTrain::OnCommand_secondcontrollerdecreasefast }, { user_command::notchingrelaytoggle, &TTrain::OnCommand_notchingrelaytoggle }, - { user_command::mucurrentindicatorsourcetoggle, &TTrain::OnCommand_mucurrentindicatorsourcetoggle }, + { user_command::mucurrentindicatorothersourceactivate, &TTrain::OnCommand_mucurrentindicatorothersourceactivate }, { user_command::independentbrakeincrease, &TTrain::OnCommand_independentbrakeincrease }, { user_command::independentbrakeincreasefast, &TTrain::OnCommand_independentbrakeincreasefast }, { user_command::independentbrakedecrease, &TTrain::OnCommand_independentbrakedecrease }, @@ -178,6 +178,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::converteroverloadrelayreset, &TTrain::OnCommand_converteroverloadrelayreset }, { user_command::compressortoggle, &TTrain::OnCommand_compressortoggle }, { user_command::motorconnectorsopen, &TTrain::OnCommand_motorconnectorsopen }, + { user_command::motordisconnect, &TTrain::OnCommand_motordisconnect }, { user_command::motoroverloadrelaythresholdtoggle, &TTrain::OnCommand_motoroverloadrelaythresholdtoggle }, { user_command::motoroverloadrelayreset, &TTrain::OnCommand_motoroverloadrelayreset }, { user_command::heatingtoggle, &TTrain::OnCommand_heatingtoggle }, @@ -573,7 +574,7 @@ void TTrain::OnCommand_notchingrelaytoggle( TTrain *Train, command_data const &C } } -void TTrain::OnCommand_mucurrentindicatorsourcetoggle( TTrain *Train, command_data const &Command ) { +void TTrain::OnCommand_mucurrentindicatorothersourceactivate( TTrain *Train, command_data const &Command ) { if( Train->ggNextCurrentButton.SubModel == nullptr ) { if( Command.action == GLFW_PRESS ) { @@ -583,27 +584,24 @@ void TTrain::OnCommand_mucurrentindicatorsourcetoggle( TTrain *Train, command_da } if( Command.action == GLFW_PRESS ) { - // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( false == Train->ShowNextCurrent ) { - // turn on - Train->ShowNextCurrent = true; - // audio feedback - if( Train->ggNextCurrentButton.GetValue() < 0.5 ) { - Train->play_sound( Train->dsbSwitch ); - } - // visual feedback - Train->ggNextCurrentButton.UpdateValue( 1.0 ); + // turn on + Train->ShowNextCurrent = true; + // audio feedback + if( Train->ggNextCurrentButton.GetValue() < 0.5 ) { + Train->play_sound( Train->dsbSwitch ); } - else { - //turn off - Train->ShowNextCurrent = false; - // audio feedback - if( Train->ggNextCurrentButton.GetValue() > 0.5 ) { - Train->play_sound( Train->dsbSwitch ); - } - // visual feedback - Train->ggNextCurrentButton.UpdateValue( 0.0 ); + // visual feedback + Train->ggNextCurrentButton.UpdateValue( 1.0 ); + } + else if( Command.action == GLFW_RELEASE ) { + //turn off + Train->ShowNextCurrent = false; + // audio feedback + if( Train->ggNextCurrentButton.GetValue() > 0.5 ) { + Train->play_sound( Train->dsbSwitch ); } + // visual feedback + Train->ggNextCurrentButton.UpdateValue( 0.0 ); } } @@ -922,7 +920,7 @@ void TTrain::OnCommand_sandboxactivate( TTrain *Train, command_data const &Comma // TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels if( Train->ggSandButton.SubModel == nullptr ) { if( Command.action == GLFW_PRESS ) { - WriteLog( "Wheelspin Brake button is missing, or wasn't defined" ); + WriteLog( "Sandbox activation button is missing, or wasn't defined" ); } return; } @@ -1200,14 +1198,11 @@ void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command // audio feedback Train->play_sound( Train->dsbSwitch ); // side-effects -/* - // NOTE: on second thought, don't and let them drop when the pantograph tank pressure drops below threshold if( false == Train->mvControlled->ConverterFlag ) { // if there's no (low voltage) power source left, drop pantographs Train->mvControlled->PantFront( false ); Train->mvControlled->PantRear( false ); } -*/ } } } @@ -1518,117 +1513,123 @@ void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Co void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ) { if( ( Command.action == GLFW_PRESS ) - && ( true == Train->m_linebreakerclosed ) + && ( Train->m_linebreakerstate == 1 ) && ( false == Train->mvControlled->Mains ) && ( Train->ggMainButton.GetValue() < 0.05 ) ) { // crude way to catch cases where the main was knocked out and the user is trying to restart it // because the state of the line breaker isn't changed to match, we need to do it here manually - Train->m_linebreakerclosed = false; + Train->m_linebreakerstate = 0; } // NOTE: we don't have switch type definition for the line breaker switch // so for the time being we have hard coded "impulse" switches for all EMUs // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz - if( ( true == Train->m_linebreakerclosed ) + if( ( Train->m_linebreakerstate == 1 ) && ( Train->mvControlled->TrainType == dt_EZT ) ) { // a single impulse switch can't open the circuit, only close it return; } - if( Command.action != GLFW_RELEASE ) { // press or hold... - if( false == Train->mvControlled->Mains ) { + if( Train->m_linebreakerstate == 0 ) { // ...to close the circuit - if( false == Train->m_linebreakerclosed ) { - // safety check so we don't close the circuit right after opening - if( Train->ggMainOnButton.SubModel != nullptr ) { + if( Train->ggMainOnButton.SubModel != nullptr ) { + // two separate switches to close and break the circuit + // audio feedback + if( Command.action == GLFW_PRESS ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggMainOnButton.UpdateValue( 1.0 ); + } + else if( Train->ggMainButton.SubModel != nullptr ) { + // single two-state switch + // audio feedback + if( Command.action == GLFW_PRESS ) { + Train->play_sound( Train->dsbSwitch ); + } + // visual feedback + Train->ggMainButton.UpdateValue( 1.0 ); + } + // keep track of period the button is held down, to determine when/if circuit closes + if( ( false == ( Train->mvControlled->EnginePowerSource.PowerType == ElectricSeriesMotor ) || ( Train->mvControlled->EngineType == ElectricInductionMotor ) ) + || ( Train->fHVoltage > 0.0f ) ) { + // prevent the switch from working if there's no power + // TODO: consider whether it makes sense for diesel engines and such + Train->fMainRelayTimer += 0.33f; // Command.time_delta * 5.0; + } + if( Train->mvControlled->Mains != true ) { + // hunter-080812: poprawka + Train->mvControlled->ConverterSwitch( false ); + Train->mvControlled->CompressorSwitch( false ); + } + if( Train->fMainRelayTimer > Train->mvControlled->InitialCtrlDelay ) { + // wlaczanie WSa z opoznieniem + Train->m_linebreakerstate = 2; + // for diesels, we complete the engine start here + // TODO: consider arranging a better way to start the diesel engines + if( Train->mvControlled->EngineType == DieselEngine ) { + if( Train->mvControlled->MainSwitch( true ) ) { + // sound feedback, engine start for diesel vehicle + Train->play_sound( Train->dsbDieselIgnition ); + // side-effects + Train->mvControlled->ConverterSwitch( Train->ggConverterButton.GetValue() > 0.5 ); + Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 ); + } + } + } + } + else if( Train->m_linebreakerstate == 1 ) { + // ...to open the circuit + if( true == Train->mvControlled->MainSwitch( false ) ) { + + Train->m_linebreakerstate = -1; + + if( Train->ggMainOffButton.SubModel != nullptr ) { // two separate switches to close and break the circuit // audio feedback if( Command.action == GLFW_PRESS ) { Train->play_sound( Train->dsbSwitch ); } // visual feedback - Train->ggMainOnButton.UpdateValue( 1.0 ); + Train->ggMainOffButton.UpdateValue( 1.0 ); } else if( Train->ggMainButton.SubModel != nullptr ) { // single two-state switch - // audio feedback - if( Command.action == GLFW_PRESS ) { - Train->play_sound( Train->dsbSwitch ); - } - // visual feedback - Train->ggMainButton.UpdateValue( 1.0 ); - } - // keep track of period the button is held down, to determine when/if circuit closes - Train->fMainRelayTimer += 0.33f; // Command.time_delta * 5.0; - if( Train->mvControlled->Mains != true ) { - // hunter-080812: poprawka - Train->mvControlled->ConverterSwitch( false ); - Train->mvControlled->CompressorSwitch( false ); - } - if( Train->fMainRelayTimer > Train->mvControlled->InitialCtrlDelay ) { - // wlaczanie WSa z opoznieniem - if( Train->mvControlled->MainSwitch( true ) ) { - // sound feedback, engine start for diesel vehicle - if( Train->mvControlled->EngineType == DieselEngine ) { - Train->play_sound( Train->dsbDieselIgnition ); - } - } - } - } - } - else { - // ...to open the circuit - if( true == Train->m_linebreakerclosed ) { - // safety check so we don't open the circuit right after closing - if( Train->mvControlled->MainSwitch( false ) ) { - - if( Train->ggMainOffButton.SubModel != nullptr ) { - // two separate switches to close and break the circuit +/* + // NOTE: we don't have switch type definition for the line breaker switch + // so for the time being we have hard coded "impulse" switches for all EMUs + // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz + if( Train->mvControlled->TrainType == dt_EZT ) { // audio feedback if( Command.action == GLFW_PRESS ) { Train->play_sound( Train->dsbSwitch ); } // visual feedback - Train->ggMainOffButton.UpdateValue( 1.0 ); + Train->ggMainButton.UpdateValue( 1.0 ); } - else if( Train->ggMainButton.SubModel != nullptr ) { - // single two-state switch -/* - // NOTE: we don't have switch type definition for the line breaker switch - // so for the time being we have hard coded "impulse" switches for all EMUs - // TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz - if( Train->mvControlled->TrainType == dt_EZT ) { - // audio feedback - if( Command.action == GLFW_PRESS ) { - Train->play_sound( Train->dsbSwitch ); - } - // visual feedback - Train->ggMainButton.UpdateValue( 1.0 ); - } - else + else */ - { - // audio feedback - if( Command.action == GLFW_PRESS ) { - Train->play_sound( Train->dsbSwitch ); - } - // visual feedback - Train->ggMainButton.UpdateValue( 0.0 ); + { + // audio feedback + if( Command.action == GLFW_PRESS ) { + Train->play_sound( Train->dsbSwitch ); } + // visual feedback + Train->ggMainButton.UpdateValue( 0.0 ); } } - // play sound immediately when the switch is hit, not after release - if( Train->fMainRelayTimer > 0.0f ) { - Train->play_sound( Train->dsbRelay ); - Train->fMainRelayTimer = 0.0f; - } + } + // play sound immediately when the switch is hit, not after release + if( Train->fMainRelayTimer > 0.0f ) { + Train->play_sound( Train->dsbRelay ); + Train->fMainRelayTimer = 0.0f; } } } else { // release... - if( false == Train->mvControlled->Mains ) { + if( Train->m_linebreakerstate <= 0 ) { // ...after opening circuit, or holding for too short time to close it // hunter-091012: przeniesione z mover.pas, zeby dzwiek sie nie zapetlal, if( Train->fMainRelayTimer > 0.0f ) { @@ -1656,13 +1657,19 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com // visual feedback Train->ggMainButton.UpdateValue( 0.0 ); } - Train->m_linebreakerclosed = false; + // finalize the state of the line breaker + Train->m_linebreakerstate = 0; } else { // ...after closing the circuit - // side-effects - Train->mvControlled->ConverterSwitch( Train->ggConverterButton.GetValue() > 0.5 ); - Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 ); + // we don't need to start the diesel twice, but the other types still need to be launched + if( Train->mvControlled->EngineType != DieselEngine ) { + if( Train->mvControlled->MainSwitch( true ) ) { + // side-effects + Train->mvControlled->ConverterSwitch( Train->ggConverterButton.GetValue() > 0.5 ); + Train->mvControlled->CompressorSwitch( Train->ggCompressorButton.GetValue() > 0.5 ); + } + } // audio feedback if( Train->ggMainOnButton.GetValue() > 0.5 ) { Train->play_sound( Train->dsbSwitch ); @@ -1685,7 +1692,8 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com Train->ggMainButton.UpdateValue( 0.0 ); } } - Train->m_linebreakerclosed = true; + // finalize the state of the line breaker + Train->m_linebreakerstate = 1; } } } @@ -1710,8 +1718,8 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma // NOTE: this is most likely setup wrong, but the whole thing is smoke and mirrors anyway if( ( Train->mvOccupied->ConvSwitchType != "impulse" ) || ( Train->mvControlled->Mains ) ) { - if( ( true == Train->m_linebreakerclosed ) // won't start if the line breaker button is still held - && ( true == Train->mvControlled->ConverterSwitch( true ) ) ) { + // won't start if the line breaker button is still held + if( true == Train->mvControlled->ConverterSwitch( true ) ) { // side effects // control the compressor, if it's paired with the converter if( Train->mvControlled->CompressorPower == 2 ) { @@ -1752,13 +1760,10 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma Train->mvControlled->ConvOvldFlag = false; } // if there's no (low voltage) power source left, drop pantographs -/* - // NOTE: on second thought, don't and let them drop when the pantograph tank pressure drops below threshold if( false == Train->mvControlled->Battery ) { Train->mvControlled->PantFront( false ); Train->mvControlled->PantRear( false ); } -*/ } } } @@ -1911,6 +1916,23 @@ void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &C } } +void TTrain::OnCommand_motordisconnect( TTrain *Train, command_data const &Command ) { + + if( ( Train->mvControlled->TrainType == dt_EZT ? + ( Train->mvControlled != Train->mvOccupied ) : + ( Train->mvOccupied->ActiveCab != 0 ) ) ) { + // tylko w maszynowym + return; + } + + if( Command.action == GLFW_PRESS ) { + if( true == Train->mvControlled->CutOffEngine() ) { + // sound feedback + Train->play_sound( Train->dsbSwitch ); + } + } +} + void TTrain::OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command ) { if( Command.action == GLFW_PRESS ) { @@ -3106,7 +3128,6 @@ void TTrain::OnKeyDown(int cKey) play_sound( dsbSwitch ); } } -#endif else if( cKey == Global::Keys[ k_FailedEngineCutOff ] ) { // McZapkie-060103: E - wylaczanie sekcji silnikow if (mvControlled->CutOffEngine()) @@ -3114,7 +3135,6 @@ void TTrain::OnKeyDown(int cKey) play_sound( dsbSwitch ); } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM else if( cKey == Global::Keys[ k_OpenLeft ] ) // NBMX 17-09-2003: otwieranie drzwi { if (mvOccupied->DoorOpenCtrl == 1) @@ -5014,6 +5034,10 @@ bool TTrain::Update( double const Deltatime ) auto lookup = m_commandhandlers.find( commanddata.command ); if( lookup != m_commandhandlers.end() ) { + // debug data + if( commanddata.action != GLFW_RELEASE ) { + WriteLog( mvOccupied->Name + " received command: [" + simulation::Commands_descriptions[ static_cast( commanddata.command ) ].name + "]" ); + } // pass the command to the assigned handler lookup->second( this, commanddata ); } @@ -5033,6 +5057,16 @@ bool TTrain::Update( double const Deltatime ) DWORD stat; double dt = Deltatime; // Timer::GetDeltaTime(); + + // catch cases where the power goes out, and the linebreaker state is left as closed + if( ( m_linebreakerstate == 1 ) + && ( false == mvControlled->Mains ) + && ( ggMainButton.GetValue() < 0.05 ) ) { + // crude way to catch cases where the main was knocked out and the user is trying to restart it + // because the state of the line breaker isn't changed to match, we need to do it here manually + m_linebreakerstate = 0; + } + /* // NOTE: disabled while switch state isn't preserved while moving between compartments // check whether we should raise the pantographs, based on volume in pantograph tank @@ -5907,7 +5941,7 @@ bool TTrain::Update( double const Deltatime ) if (mvControlled->Battery || mvControlled->ConverterFlag) { - btLampkaWylSzybki.Turn( mvControlled->Mains ); + btLampkaWylSzybki.Turn( ( m_linebreakerstate > 0 ? true : false ) ); // hunter-261211: jakis stary kod (i niezgodny z prawda), // zahaszowalem i poprawilem diff --git a/Train.h b/Train.h index 1bce34d6..786883c2 100644 --- a/Train.h +++ b/Train.h @@ -120,7 +120,7 @@ class TTrain static void OnCommand_secondcontrollerdecrease( TTrain *Train, command_data const &Command ); static void OnCommand_secondcontrollerdecreasefast( TTrain *Train, command_data const &Command ); static void OnCommand_notchingrelaytoggle( TTrain *Train, command_data const &Command ); - static void OnCommand_mucurrentindicatorsourcetoggle( TTrain *Train, command_data const &Command ); + static void OnCommand_mucurrentindicatorothersourceactivate( TTrain *Train, command_data const &Command ); static void OnCommand_independentbrakeincrease( TTrain *Train, command_data const &Command ); static void OnCommand_independentbrakeincreasefast( TTrain *Train, command_data const &Command ); static void OnCommand_independentbrakedecrease( TTrain *Train, command_data const &Command ); @@ -154,6 +154,7 @@ class TTrain static void OnCommand_converteroverloadrelayreset( TTrain *Train, command_data const &Command ); static void OnCommand_compressortoggle( TTrain *Train, command_data const &Command ); static void OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ); + static void OnCommand_motordisconnect( TTrain *Train, command_data const &Command ); static void OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command ); static void OnCommand_motoroverloadrelayreset( TTrain *Train, command_data const &Command ); static void OnCommand_heatingtoggle( TTrain *Train, command_data const &Command ); @@ -186,7 +187,7 @@ class TTrain TMoverParameters *mvSecond; // drugi człon (ET40, ET41, ET42, ukrotnienia) TMoverParameters *mvThird; // trzeci człon (SN61) // helper variable, to prevent immediate switch between closing and opening line breaker circuit - bool m_linebreakerclosed{ false }; + int m_linebreakerstate{ 0 }; // -1: freshly open, 0: open, 1: closed, 2: freshly closed (and yes this is awful way to go about it) static const commandhandler_map m_commandhandlers; public: // reszta może by?publiczna diff --git a/command.cpp b/command.cpp index 6d75124e..4ad7c4e0 100644 --- a/command.cpp +++ b/command.cpp @@ -27,7 +27,7 @@ commanddescription_sequence Commands_descriptions = { { "secondcontrollerincreasefast", command_target::vehicle }, { "secondcontrollerdecrease", command_target::vehicle }, { "secondcontrollerdecreasefast", command_target::vehicle }, - { "mucurrentindicatorsourcetoggle", command_target::vehicle }, + { "mucurrentindicatorothersourceactivate", command_target::vehicle }, { "independentbrakeincrease", command_target::vehicle }, { "independentbrakeincreasefast", command_target::vehicle }, { "independentbrakedecrease", command_target::vehicle }, @@ -58,7 +58,7 @@ commanddescription_sequence Commands_descriptions = { { "mubrakingindicatortoggle", command_target::vehicle }, { "alerteracknowledge", command_target::vehicle }, { "hornlowactivate", command_target::vehicle }, - { "hornhighctivate", command_target::vehicle }, + { "hornhighactivate", command_target::vehicle }, { "radiotoggle", command_target::vehicle }, /* const int k_FailedEngineCutOff = 35; @@ -111,6 +111,7 @@ const int k_ProgramHelp = 48; { "redmarkertogglerearright", 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 }, @@ -180,7 +181,7 @@ command_relay::post( user_command const Command, std::uint64_t const Param1, std Param2, Timer::GetDeltaTime() }, static_cast( command.target ) | Recipient ); - +/* #ifdef _DEBUG if( Action != GLFW_RELEASE ) { // key was pressed or is still held @@ -204,13 +205,12 @@ command_relay::post( user_command const Command, std::uint64_t const Param1, std } } } -/* else { // key was released (but we don't log this) - WriteLog( "Key released: " + m_command.name ); + WriteLog( "Key released: " + command.name ); } -*/ #endif +*/ } //--------------------------------------------------------------------------- diff --git a/command.h b/command.h index 2be03a0c..9ba1d725 100644 --- a/command.h +++ b/command.h @@ -22,7 +22,7 @@ enum class user_command { secondcontrollerincreasefast, secondcontrollerdecrease, secondcontrollerdecreasefast, - mucurrentindicatorsourcetoggle, + mucurrentindicatorothersourceactivate, independentbrakeincrease, independentbrakeincreasefast, independentbrakedecrease, @@ -106,6 +106,7 @@ const int k_ProgramHelp = 48; redmarkertogglerearright, headlightsdimtoggle, motorconnectorsopen, + motordisconnect, interiorlighttoggle, interiorlightdimtoggle, instrumentlighttoggle, diff --git a/keyboardinput.cpp b/keyboardinput.cpp index af3e3ef8..2c32b9e4 100644 --- a/keyboardinput.cpp +++ b/keyboardinput.cpp @@ -10,13 +10,93 @@ http://mozilla.org/MPL/2.0/. #include "stdafx.h" #include "keyboardinput.h" #include "logs.h" +#include "parser.h" -void +bool keyboard_input::recall_bindings() { - // TODO: implement + // build helper translation tables + std::unordered_map nametocommandmap; + std::size_t commandid = 0; + for( auto const &description : simulation::Commands_descriptions ) { + nametocommandmap.emplace( + description.name, + static_cast( commandid ) ); + ++commandid; + } + std::unordered_map nametokeymap = { + { "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 }, + { "p", GLFW_KEY_P }, { "q", GLFW_KEY_Q }, { "r", GLFW_KEY_R }, { "s", GLFW_KEY_S }, { "t", GLFW_KEY_T }, + { "u", GLFW_KEY_U }, { "v", GLFW_KEY_V }, { "w", GLFW_KEY_W }, { "x", GLFW_KEY_X }, { "y", GLFW_KEY_Y }, { "z", GLFW_KEY_Z }, + { "-", GLFW_KEY_MINUS }, { "=", GLFW_KEY_EQUAL }, { "backspace", GLFW_KEY_BACKSPACE }, + { "[", GLFW_KEY_LEFT_BRACKET }, { "]", GLFW_KEY_RIGHT_BRACKET }, { "\\", GLFW_KEY_BACKSLASH }, + { ";", GLFW_KEY_SEMICOLON }, { "'", GLFW_KEY_APOSTROPHE }, { "enter", GLFW_KEY_ENTER }, + { ",", GLFW_KEY_COMMA }, { ".", GLFW_KEY_PERIOD }, { "/", GLFW_KEY_SLASH }, + { "space", GLFW_KEY_SPACE }, + // 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 }, + { "num_4", GLFW_KEY_KP_4 }, { "num_5", GLFW_KEY_KP_5 }, { "num_6", GLFW_KEY_KP_6 }, + { "num_1", GLFW_KEY_KP_1 }, { "num_2", GLFW_KEY_KP_2 }, { "num_3", GLFW_KEY_KP_3 }, { "num_enter", GLFW_KEY_KP_ENTER }, + { "num_0", GLFW_KEY_KP_0 }, { "num_.", GLFW_KEY_KP_DECIMAL } + }; + + cParser bindingparser( "eu07_input-keyboard.ini", cParser::buffer_FILE ); + if( false == bindingparser.ok() ) { + return false; + } + + while( true == bindingparser.getTokens( 1, true, "\n" ) ) { + + std::string bindingentry; + bindingparser >> bindingentry; + cParser entryparser( bindingentry ); + if( true == entryparser.getTokens( 1, true, "\n\r\t " ) ) { + + std::string commandname; + entryparser >> commandname; + + auto const lookup = nametocommandmap.find( commandname ); + if( lookup == nametocommandmap.end() ) { + + WriteLog( "Keyboard binding defined for unknown command, \"" + commandname + "\"" ); + } + else { + int binding{ 0 }; + while( entryparser.getTokens( 1, true, "\n\r\t " ) ) { + + std::string bindingkeyname; + entryparser >> bindingkeyname; + + if( bindingkeyname == "shift" ) { binding |= keymodifier::shift; } + else if( bindingkeyname == "ctrl" ) { binding |= keymodifier::control; } + else { + // regular key, convert it to glfw key code + auto const keylookup = nametokeymap.find( bindingkeyname ); + if( keylookup == nametokeymap.end() ) { + + WriteLog( "Keyboard binding included unrecognized key, \"" + bindingkeyname + "\"" ); + } + else { + // replace any existing binding, preserve modifiers + // (protection from cases where there's more than one key listed in the entry) + binding = keylookup->second | ( binding & 0xffff0000 ); + } + } + + if( ( binding & 0xffff ) != 0 ) { + m_commands.at( static_cast( lookup->second ) ).binding = binding; + } + } + } + } + } bind(); + + return true; } bool @@ -108,7 +188,7 @@ keyboard_input::default_bindings() { { GLFW_KEY_KP_MULTIPLY }, // secondcontrollerdecreasefast { GLFW_KEY_KP_MULTIPLY | keymodifier::shift }, - // mucurrentindicatorsourcetoggle + // mucurrentindicatorothersourceactivate { GLFW_KEY_Z | keymodifier::shift }, // independentbrakeincrease { GLFW_KEY_KP_1 }, @@ -164,7 +244,7 @@ keyboard_input::default_bindings() { { GLFW_KEY_B | keymodifier::shift }, // brakeactingspeeddecrease { GLFW_KEY_B }, - // brakingindicatortoggle + // mubrakingindicatortoggle { GLFW_KEY_L | keymodifier::shift }, // alerteracknowledge { GLFW_KEY_SPACE }, @@ -174,9 +254,6 @@ keyboard_input::default_bindings() { { GLFW_KEY_A | keymodifier::shift }, // radiotoggle { GLFW_KEY_R | keymodifier::control }, -/* -const int k_FailedEngineCutOff = 35; -*/ // viewturn { -1 }, // movevector @@ -261,6 +338,8 @@ const int k_ProgramHelp = 48; { GLFW_KEY_L | keymodifier::control }, // motorconnectorsopen { GLFW_KEY_L }, + // motordisconnect + { GLFW_KEY_E | keymodifier::shift }, // interiorlighttoggle { GLFW_KEY_APOSTROPHE }, // interiorlightdimtoggle @@ -300,6 +379,7 @@ keyboard_input::bind() { } ++commandcode; } + // cache movement key bindings, so we can test them faster in the input loop m_bindingscache.forward = m_commands[ static_cast( user_command::moveforward ) ].binding; m_bindingscache.back = m_commands[ static_cast( user_command::moveback ) ].binding; diff --git a/keyboardinput.h b/keyboardinput.h index 12301797..e2d78708 100644 --- a/keyboardinput.h +++ b/keyboardinput.h @@ -20,7 +20,9 @@ public: keyboard_input() { default_bindings(); } // methods - void + bool + init() { return recall_bindings(); } + bool recall_bindings(); bool key( int const Key, int const Action ); From da65fb7fac40870f14e3adc8d9edbd67935aa14d Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Mon, 24 Apr 2017 14:37:19 +0200 Subject: [PATCH 11/12] leak rate as .fiz parameter, support for low and high horn buttons, brake .fiz parsing fix --- McZapkie/MOVER.h | 1 + McZapkie/Mover.cpp | 26 ++++++++++++++++++-------- Train.cpp | 30 +++++++++++++++++++++++++----- Train.h | 2 ++ 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 75db0f36..bc08b127 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -659,6 +659,7 @@ public: double CompressorSpeed = 0.0; /*cisnienie wlaczania, zalaczania sprezarki, wydajnosc sprezarki*/ TBrakeDelayTable BrakeDelay; /*opoznienie hamowania/odhamowania t/o*/ + double AirLeakRate{ 0.01 }; // base rate of air leak from brake system components ( 0.001 = 1 l/sec ) int BrakeCtrlPosNo = 0; /*ilosc pozycji hamulca*/ /*nastawniki:*/ int MainCtrlPosNo = 0; /*ilosc pozycji nastawnika*/ diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 98a48ea5..62678a41 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -2843,8 +2843,7 @@ void TMoverParameters::UpdateBrakePressure(double dt) // ************************************************************************************************* void TMoverParameters::CompressorCheck(double dt) { - // TODO: expose leak rate as a parameter to the .fiz file - CompressedVolume = std::max( 0.0, CompressedVolume - dt * 0.001 ); // nieszczelności: 0.001=1l/s + CompressedVolume = std::max( 0.0, CompressedVolume - dt * AirLeakRate * 0.1 ); // nieszczelności: 0.001=1l/s // if (CompressorSpeed>0.0) then //ten warunek został sprawdzony przy wywołaniu funkcji if (VeselVolume > 0) @@ -2968,8 +2967,10 @@ void TMoverParameters::CompressorCheck(double dt) // ************************************************************************************************* void TMoverParameters::UpdatePipePressure(double dt) { - // TODO: expose leak rate as a parameter to the .fiz file - PipePress = std::max( 0.0, PipePress - dt * 0.001 ); // nieszczelności: 0.001=1l/s + if( PipePress > 1.0 ) { + Pipe->Flow( -(PipePress)* AirLeakRate * dt ); + Pipe->Act(); + } const double LBDelay = 100; const double kL = 0.5; @@ -3187,8 +3188,10 @@ void TMoverParameters::UpdatePipePressure(double dt) // ************************************************************************************************* void TMoverParameters::UpdateScndPipePressure(double dt) { - // TODO: expose leak rate as a parameter to the .fiz file - ScndPipePress = std::max( 0.0, ScndPipePress - dt * 0.001 ); // nieszczelności: 0.001=0.1l/s + if( ScndPipePress > 1.0 ) { + Pipe2->Flow( -(ScndPipePress)* AirLeakRate * dt ); + Pipe2->Act(); + } const double Spz = 0.5067; TMoverParameters *c; @@ -6494,6 +6497,11 @@ void TMoverParameters::LoadFIZ_Brake( std::string const &line ) { lookup->second : 1; } + + if( true == extract_value( AirLeakRate, "AirLeakRate", line, "" ) ) { + // the parameter is provided in form of a multiplier, where 1.0 means the default rate of 0.001 + AirLeakRate *= 0.01; + } } void TMoverParameters::LoadFIZ_Doors( std::string const &line ) { @@ -6705,8 +6713,10 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) { } // mbpm - extract_value( MBPM, "MaxBPMass", line, "" ); -// MBPM *= 1000; + if( true == extract_value( MBPM, "MaxBPMass", line, "" ) ) { + // NOTE: only convert the value from tons to kilograms if the entry is present in the config file + MBPM *= 1000.0; + } // asbtype std::string asb; diff --git a/Train.cpp b/Train.cpp index 70fb0519..5a860870 100644 --- a/Train.cpp +++ b/Train.cpp @@ -2742,7 +2742,8 @@ void TTrain::OnCommand_departureannounce( TTrain *Train, command_data const &Com void TTrain::OnCommand_hornlowactivate( TTrain *Train, command_data const &Command ) { - if( Train->ggHornButton.SubModel == nullptr ) { + if( ( Train->ggHornButton.SubModel == nullptr ) + && ( Train->ggHornLowButton.SubModel == nullptr ) ) { if( Command.action == GLFW_PRESS ) { WriteLog( "Horn button is missing, or wasn't defined" ); } @@ -2759,11 +2760,13 @@ void TTrain::OnCommand_hornlowactivate( TTrain *Train, command_data const &Comma Train->mvControlled->WarningSignal &= ~2; } // audio feedback - if( Train->ggHornButton.GetValue() > -0.5 ) { + if( ( Train->ggHornButton.GetValue() > -0.5 ) + || ( Train->ggHornLowButton.GetValue() < 0.5 ) ) { Train->play_sound( Train->dsbSwitch ); } // visual feedback Train->ggHornButton.UpdateValue( -1.0 ); + Train->ggHornLowButton.UpdateValue( 1.0 ); } } else if( Command.action == GLFW_RELEASE ) { @@ -2771,17 +2774,20 @@ void TTrain::OnCommand_hornlowactivate( TTrain *Train, command_data const &Comma // NOTE: we turn off both low and high horn, due to unreliability of release event when shift key is involved Train->mvControlled->WarningSignal &= ~( 1 | 2 ); // audio feedback - if( Train->ggHornButton.GetValue() < -0.5 ) { + if( ( Train->ggHornButton.GetValue() < -0.5 ) + || ( Train->ggHornLowButton.GetValue() > 0.5 ) ) { Train->play_sound( Train->dsbSwitch ); } // visual feedback Train->ggHornButton.UpdateValue( 0.0 ); + Train->ggHornLowButton.UpdateValue( 0.0 ); } } void TTrain::OnCommand_hornhighactivate( TTrain *Train, command_data const &Command ) { - if( Train->ggHornButton.SubModel == nullptr ) { + if( ( Train->ggHornButton.SubModel == nullptr ) + && ( Train->ggHornHighButton.SubModel == nullptr ) ) { if( Command.action == GLFW_PRESS ) { WriteLog( "Horn button is missing, or wasn't defined" ); } @@ -2803,6 +2809,7 @@ void TTrain::OnCommand_hornhighactivate( TTrain *Train, command_data const &Comm } // visual feedback Train->ggHornButton.UpdateValue( 1.0 ); + Train->ggHornHighButton.UpdateValue( 1.0 ); } } else if( Command.action == GLFW_RELEASE ) { @@ -2815,6 +2822,7 @@ void TTrain::OnCommand_hornhighactivate( TTrain *Train, command_data const &Comm } // visual feedback Train->ggHornButton.UpdateValue( 0.0 ); + Train->ggHornButton.UpdateValue( 0.0 ); } } @@ -7399,6 +7407,8 @@ bool TTrain::Update( double const Deltatime ) ggSignallingButton.Update(); ggNextCurrentButton.Update(); ggHornButton.Update(); + ggHornLowButton.Update(); + ggHornHighButton.Update(); ggUniversal1Button.Update(); ggUniversal2Button.Update(); ggUniversal3Button.Update(); @@ -8169,6 +8179,8 @@ void TTrain::clear_cab_controls() ggSandButton.Clear(); ggAntiSlipButton.Clear(); ggHornButton.Clear(); + ggHornLowButton.Clear(); + ggHornHighButton.Clear(); ggNextCurrentButton.Clear(); ggUniversal1Button.Clear(); ggUniversal2Button.Clear(); @@ -8759,7 +8771,15 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con // dzwignia syreny ggHornButton.Load(Parser, DynamicObject->mdKabina); } - else if (Label == "fuse_bt:") + else if( Label == "hornlow_bt:" ) { + // dzwignia syreny + ggHornLowButton.Load( Parser, DynamicObject->mdKabina ); + } + else if( Label == "hornhigh_bt:" ) { + // dzwignia syreny + ggHornHighButton.Load( Parser, DynamicObject->mdKabina ); + } + else if( Label == "fuse_bt:" ) { // bezp. nadmiarowy ggFuseButton.Load(Parser, DynamicObject->mdKabina); diff --git a/Train.h b/Train.h index 786883c2..e2658c1b 100644 --- a/Train.h +++ b/Train.h @@ -261,6 +261,8 @@ public: // reszta może by?publiczna // ABu 090305 - syrena i prad nastepnego czlonu TGauge ggHornButton; + TGauge ggHornLowButton; + TGauge ggHornHighButton; TGauge ggNextCurrentButton; // ABu 090305 - uniwersalne przyciski TGauge ggUniversal1Button; From c4e280f1c0c5dd5de5de3a9d0f2ff1383775c0be Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Mon, 24 Apr 2017 14:58:32 +0200 Subject: [PATCH 12/12] maintenance: removed deprecated code from train control --- EU07.cpp | 4 - Train.cpp | 1599 +---------------------------------------------------- Train.h | 8 +- World.cpp | 9 - World.h | 1 - 5 files changed, 2 insertions(+), 1619 deletions(-) diff --git a/EU07.cpp b/EU07.cpp index 4fbfa0c9..57162e81 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -161,10 +161,6 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo default: { break; } } } - else if( action == GLFW_RELEASE ) - { - World.OnKeyUp( key ); - } } void focus_callback( GLFWwindow *window, int focus ) diff --git a/Train.cpp b/Train.cpp index 5a860870..81d72c95 100644 --- a/Train.cpp +++ b/Train.cpp @@ -2871,150 +2871,6 @@ void TTrain::OnKeyDown(int cKey) if (Global::shiftState) { // wciśnięty [Shift] -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - if (cKey == Global::Keys[k_IncMainCtrlFAST]) // McZapkie-200702: szybkie - // przelaczanie na poz. - // bezoporowa - { - if (mvControlled->IncMainCtrl(2)) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - } - if (cKey == Global::Keys[k_DirectionBackward]) - { - if (mvOccupied->Radio == false) - if (Global::ctrlState) - { - play_sound( dsbSwitch ); - mvOccupied->Radio = true; - } - } - else if (cKey == Global::Keys[k_DecMainCtrlFAST]) - if (mvControlled->DecMainCtrl(2)) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - else - ; - else if (cKey == Global::Keys[k_IncScndCtrlFAST]) - if (mvControlled->IncScndCtrl(2)) - { - if (dsbNastawnikBocz) // hunter-081211 - { - dsbNastawnikBocz->SetCurrentPosition(0); - dsbNastawnikBocz->Play(0, 0, 0); - } - else if (!dsbNastawnikBocz) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - } - else - ; - else if (cKey == Global::Keys[k_DecScndCtrlFAST]) - if (mvControlled->DecScndCtrl(2)) - { - if (dsbNastawnikBocz) // hunter-081211 - { - dsbNastawnikBocz->SetCurrentPosition(0); - dsbNastawnikBocz->Play(0, 0, 0); - } - else if (!dsbNastawnikBocz) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - } - else - ; - else if( cKey == Global::Keys[ k_IncLocalBrakeLevelFAST ] ) - if (mvOccupied->IncLocalBrakeLevel(2)) - ; - else - ; - else if (cKey == Global::Keys[k_DecLocalBrakeLevelFAST]) - if (mvOccupied->DecLocalBrakeLevel(2)) - ; - else - ; - if( cKey == Global::Keys[ k_Battery ] ) - { - // if - // (((mvControlled->TrainType==dt_EZT)||(mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->EngineType==DieselElectric))&&(!mvControlled->Battery)) - if (!mvControlled->Battery) - { // wyłącznik jest też w SN61, ewentualnie - // załączać prąd na stałe z poziomu FIZ - if (mvOccupied->BatterySwitch(true)) // bateria potrzebna np. do zapalenia świateł - { - dsbSwitch->Play(0, 0, 0); - if (ggBatteryButton.SubModel) - { - ggBatteryButton.PutValue(1); - } - if (mvOccupied->LightsPosNo > 0) - { - SetLights(); - } - if (TestFlag(mvOccupied->SecuritySystem.SystemType, - 2)) // Ra: znowu w kabinie jest coś, co być nie powinno! - { - SetFlag(mvOccupied->SecuritySystem.Status, s_active); - SetFlag(mvOccupied->SecuritySystem.Status, s_SHPalarm); - } - } - } - } - if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // shift&ctrl are used for light dimming - { - if (mvControlled->TrainType == dt_EZT) - { - if ((mvControlled->Signalling == false)) - { - play_sound( dsbSwitch ); - mvControlled->Signalling = true; - } - } - } - else - if( cKey == Global::Keys[ k_Sand ] ) - { - if( mvControlled->TrainType == dt_EZT ) - { - if (ggDoorSignallingButton.SubModel != NULL) - { - if (!mvControlled->DoorSignalling) - { - mvOccupied->DoorBlocked = true; - play_sound( dsbSwitch ); - mvControlled->DoorSignalling = true; - } - } - } - else if (mvControlled->TrainType != dt_EZT) - { - if (ggSandButton.SubModel != NULL) - { - ggSandButton.PutValue(1); - // dsbPneumaticRelay->SetVolume(-80); - // dsbPneumaticRelay->Play(0, 0, 0); - } - } - } - if( cKey == Global::Keys[ k_Main ] ) - { - if (fabs(ggMainOnButton.GetValue()) < 0.001) - if (dsbSwitch) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else -#endif if( cKey == Global::Keys[ k_BrakeProfile ] ) // McZapkie-240302-B: //----------- @@ -3063,46 +2919,6 @@ void TTrain::OnKeyDown(int cKey) } } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else if (cKey == Global::Keys[k_Converter]) - { - if (ggConverterButton.GetValue() == 0) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else if ((cKey == Global::Keys[k_Compressor]) && - (mvControlled->CompressorPower < 2)) // hunter-091012: tak jest poprawnie - // if - // ((cKey==Global::Keys[k_Compressor])&&((mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->TrainType==dt_EZT))) - // //hunter-110212: poprawka dla EZT - - { - if (ggCompressorButton.GetValue() == 0) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else if( cKey == Global::Keys[ k_SmallCompressor ] ) // Winger 160404: mala - // sprezarka wl - { // Ra: dźwięk, gdy razem z [Shift] - if ((mvControlled->TrainType & dt_EZT) ? mvControlled == mvOccupied : - !mvOccupied->ActiveCab) // tylko w maszynowym - if (Global::ctrlState) // z [Ctrl] - mvControlled->bPantKurek3 = true; // zbiornik pantografu połączony - // jest ze zbiornikiem głównym - // (pompowanie nie ma sensu) - else if (!mvControlled->PantCompFlag) // jeśli wyłączona - if (mvControlled->Battery) // jeszcze musi być załączona bateria - if (mvControlled->PantPress < 4.8) // piszą, że to tak nie działa - { - mvControlled->PantCompFlag = true; - play_sound( dsbSwitch ); // dźwięk tylko po naciśnięciu klawisza - } - } -#endif else if( cKey == GLFW_KEY_Q ) // ze Shiftem - włączenie AI { // McZapkie-240302 - wlaczanie automatycznego pilota (zadziala tylko w // trybie debugmode) @@ -3116,297 +2932,6 @@ void TTrain::OnKeyDown(int cKey) DynamicObject->Mechanik->TakeControl(true); } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else if (cKey == Global::Keys[k_MaxCurrent]) { - // McZapkie-160502: F - wysoki rozruch - if ((mvControlled->EngineType == DieselElectric) && (mvControlled->ShuntModeAllow) && - (mvControlled->MainCtrlPos == 0)) - { - mvControlled->ShuntMode = true; - } - if (mvControlled->CurrentSwitch(true)) - { - play_sound( dsbSwitch ); - } - } - else if (cKey == Global::Keys[k_CurrentAutoRelay]) { - // McZapkie-241002: G - wlaczanie PSR - if (mvControlled->AutoRelaySwitch(true)) - { - play_sound( dsbSwitch ); - } - } - else if( cKey == Global::Keys[ k_FailedEngineCutOff ] ) { - // McZapkie-060103: E - wylaczanie sekcji silnikow - if (mvControlled->CutOffEngine()) - { - play_sound( dsbSwitch ); - } - } - else if( cKey == Global::Keys[ k_OpenLeft ] ) // NBMX 17-09-2003: otwieranie drzwi - { - if (mvOccupied->DoorOpenCtrl == 1) - if (mvOccupied->CabNo < 0 ? mvOccupied->DoorRight(true) : mvOccupied->DoorLeft(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (dsbDoorOpen) - { - dsbDoorOpen->SetCurrentPosition(0); - dsbDoorOpen->Play(0, 0, 0); - } - } - } - else if (cKey == Global::Keys[k_OpenRight]) // NBMX 17-09-2003: otwieranie drzwi - { - if (mvOccupied->DoorOpenCtrl == 1) - if (mvOccupied->CabNo < 0 ? mvOccupied->DoorLeft(true) : mvOccupied->DoorRight(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (dsbDoorOpen) - { - dsbDoorOpen->SetCurrentPosition(0); - dsbDoorOpen->Play(0, 0, 0); - } - } - } - //----------- - // hunter-131211: dzwiek dla przelacznika universala podniesionego - // hunter-091012: ubajerowanie swiatla w kabinie (wyrzucenie - // przyciemnienia pod Univ4) - else if (cKey == Global::Keys[k_Univ3]) - { - if( Global::ctrlState ) - { - if (bCabLight == false) //(ggCabLightButton.GetValue()==0) - { - play_sound( dsbSwitch ); - } - } - else - { - if (ggUniversal3Button.GetValue() == 0) - { - play_sound( dsbSwitch ); - } - /* - if (Global::ctrlState) - {//z [Ctrl] zapalamy albo gasimy światełko w kabinie - if (iCabLightFlag<2) ++iCabLightFlag; //zapalenie - } - */ - } - } - - //----------- - // hunter-091012: dzwiek dla przyciemnienia swiatelka w kabinie - else if (cKey == Global::Keys[k_Univ4]) - { - if (Global::ctrlState) - { - if (bCabLightDim == false) //(ggCabLightDimButton.GetValue()==0) - { - play_sound( dsbSwitch ); - } - } - } - //----------- - else if (cKey == Global::Keys[k_PantFrontUp]) - { // Winger 160204: podn. - // przedn. pantografu - if (mvOccupied->ActiveCab == - 1) //||((mvOccupied->ActiveCab<1)&&((mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))==0))) - { // przedni gdy w kabinie 1 lub (z wyjątkiem ET40, ET41, ET42 i EZT) gdy - // w kabinie -1 - mvControlled->PantFrontSP = false; - if (mvControlled->PantFront(true)) - if (mvControlled->PantFrontStart != 1) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else - // if - // ((mvOccupied->ActiveCab<1)&&(mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))) - { // w kabinie -1 dla ET40, ET41, ET42 i EZT - mvControlled->PantRearSP = false; - if (mvControlled->PantRear(true)) - if (mvControlled->PantRearStart != 1) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - } - else if (cKey == Global::Keys[k_PantRearUp]) - { // Winger 160204: podn. - // tyln. pantografu - // względem kierunku jazdy - if (mvOccupied->ActiveCab == - 1) //||((mvOccupied->ActiveCab<1)&&((mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))==0))) - { // tylny gdy w kabinie 1 lub (z wyjątkiem ET40, ET41, ET42 i EZT) gdy w - // kabinie -1 - mvControlled->PantRearSP = false; - if (mvControlled->PantRear(true)) - if (mvControlled->PantRearStart != 1) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else - // if - // ((mvOccupied->ActiveCab<1)&&(mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))) - { // przedni w kabinie -1 dla ET40, ET41, ET42 i EZT - mvControlled->PantFrontSP = false; - if (mvControlled->PantFront(true)) - if (mvControlled->PantFrontStart != 1) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - } - else if( cKey == Global::Keys[ k_Active ] ) // yB 300407: przelacznik rozrzadu - { // Ra 2014-06: uruchomiłem to, aby aktywować czuwak w zajmowanym członie, - // a wyłączyć w innych - // Ra 2014-03: aktywacja czuwaka przepięta na ustawienie kierunku w - // mvOccupied - // if (mvControlled->Battery) //jeśli bateria jest już załączona - // mvOccupied->BatterySwitch(true); //to w ten oto durny sposób aktywuje - // się CA/SHP - // if (mvControlled->CabActivisation()) - // { - // dsbSwitch->SetVolume(DSBVOLUME_MAX); - // dsbSwitch->Play(0,0,0); - // } - } - else if( cKey == Global::Keys[ k_Heating ] ) // Winger 020304: ogrzewanie - // skladu - wlaczenie - { // Ra 2014-09: w trybie latania obsługa jest w World.cpp - if (!FreeFlyModeFlag) - { - if ((mvControlled->Heating == false) && - ((mvControlled->EngineType == ElectricSeriesMotor) && - (mvControlled->Mains == true) || - (mvControlled->ConverterFlag))) - { - mvControlled->Heating = true; - play_sound( dsbSwitch ); - } - } - } - else if( cKey == Global::Keys[ k_LeftSign ] ) // lewe swiatlo - włączenie - // ABu 060205: dzielo Wingera po malutkim liftingu: - { - if (false == (mvOccupied->LightsPosNo > 0)) - { - if ((Global::ctrlState) && - (ggRearRightLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu. - // 17.02.17 changed rear to opposite side, so the same key actually controls both lights on the left side, from the driver's point of view - // TODO: do it a more elegant way. preferably along with the rest of the controlling code - { - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[1]) & 48) == 0) - { - DynamicObject->iLights[1] |= 16; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearRightLightButton.PutValue(1); - } - if (((DynamicObject->iLights[1]) & 48) == 32) - { - DynamicObject->iLights[1] &= (255 - 32); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRearRightEndLightButton.SubModel) - { - ggRearRightEndLightButton.PutValue(0); - ggRearRightLightButton.PutValue(0); - } - else - ggRearRightLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[0]) & 48) == 0) - { - DynamicObject->iLights[0] |= 16; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearRightLightButton.PutValue(1); - } - if (((DynamicObject->iLights[0]) & 48) == 32) - { - DynamicObject->iLights[0] &= (255 - 32); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRearRightEndLightButton.SubModel) - { - ggRearRightEndLightButton.PutValue(0); - ggRearRightLightButton.PutValue(0); - } - else - ggRearRightLightButton.PutValue(0); - } - } - } - else - { - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[0]) & 3) == 0) - { - DynamicObject->iLights[0] |= 1; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggLeftLightButton.PutValue(1); - } - if (((DynamicObject->iLights[0]) & 3) == 2) - { - DynamicObject->iLights[0] &= (255 - 2); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggLeftEndLightButton.SubModel) - { - ggLeftEndLightButton.PutValue(0); - ggLeftLightButton.PutValue(0); - } - else - ggLeftLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[1]) & 3) == 0) - { - DynamicObject->iLights[1] |= 1; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggLeftLightButton.PutValue(1); - } - if (((DynamicObject->iLights[1]) & 3) == 2) - { - DynamicObject->iLights[1] &= (255 - 2); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggLeftEndLightButton.SubModel) - { - ggLeftEndLightButton.PutValue(0); - ggLeftLightButton.PutValue(0); - } - else - ggLeftLightButton.PutValue(0); - } - } - } //----------- - } - } -#endif else if (cKey == Global::Keys[k_UpperSign]) // ABu 060205: światło górne - // włączenie { @@ -3423,232 +2948,10 @@ void TTrain::OnKeyDown(int cKey) SetLights(); } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else if ((Global::ctrlState) && - (ggRearUpperLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu - { - //------------------------------ - if ((mvOccupied->ActiveCab) == 1) - { // kabina 1 - if (((DynamicObject->iLights[1]) & 12) == 0) - { - DynamicObject->iLights[1] |= 4; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearUpperLightButton.PutValue(1); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[0]) & 12) == 0) - { - DynamicObject->iLights[0] |= 4; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearUpperLightButton.PutValue(1); - } - } - } //------------------------------ - else - { - if ((mvOccupied->ActiveCab) == 1) - { // kabina 1 - if (((DynamicObject->iLights[0]) & 12) == 0) - { - DynamicObject->iLights[0] |= 4; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggUpperLightButton.PutValue(1); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[1]) & 12) == 0) - { - DynamicObject->iLights[1] |= 4; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggUpperLightButton.PutValue(1); - } - } - } -#endif } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else if( cKey == Global::Keys[ k_RightSign ] ) // Winger 070304: swiatla - // tylne (koncowki) - - // wlaczenie - { - if (false == (mvOccupied->LightsPosNo > 0)) - { - if ((Global::ctrlState) && - (ggRearLeftLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu - // 17.02.17 changed rear to opposite side, so the same key actually controls both lights on the left side, from the driver's point of view - // TODO: do it a more elegant way. preferably along with the rest of the controlling code - { - if( mvOccupied->ActiveCab == 1 ) { // kabina 1 - if( ( ( DynamicObject->iLights[ 1 ] ) & 3 ) == 0 ) { - DynamicObject->iLights[ 1 ] |= 1; - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - ggRearLeftLightButton.PutValue( 1 ); - } - if( ( ( DynamicObject->iLights[ 1 ] ) & 3 ) == 2 ) { - DynamicObject->iLights[ 1 ] &= ( 255 - 2 ); - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - if( ggRearLeftEndLightButton.SubModel ) { - ggRearLeftEndLightButton.PutValue( 0 ); - ggRearLeftLightButton.PutValue( 0 ); - } - else - ggRearLeftLightButton.PutValue( 0 ); - } - } - else { // kabina -1 - if( ( ( DynamicObject->iLights[ 0 ] ) & 3 ) == 0 ) { - DynamicObject->iLights[ 0 ] |= 1; - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - ggRearLeftLightButton.PutValue( 1 ); - } - if( ( ( DynamicObject->iLights[ 0 ] ) & 3 ) == 2 ) { - DynamicObject->iLights[ 0 ] &= ( 255 - 2 ); - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - if( ggRearLeftEndLightButton.SubModel ) { - ggRearLeftEndLightButton.PutValue( 0 ); - ggRearLeftLightButton.PutValue( 0 ); - } - else - ggRearLeftLightButton.PutValue( 0 ); - } - } - } //------------------------------ - else - { - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[0]) & 48) == 0) - { - DynamicObject->iLights[0] |= 16; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRightLightButton.PutValue(1); - } - if (((DynamicObject->iLights[0]) & 48) == 32) - { - DynamicObject->iLights[0] &= (255 - 32); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRightEndLightButton.SubModel) - { - ggRightEndLightButton.PutValue(0); - ggRightLightButton.PutValue(0); - } - else - ggRightLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[1]) & 48) == 0) - { - DynamicObject->iLights[1] |= 16; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRightLightButton.PutValue(1); - } - if (((DynamicObject->iLights[1]) & 48) == 32) - { - DynamicObject->iLights[1] &= (255 - 32); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRightEndLightButton.SubModel) - { - ggRightEndLightButton.PutValue(0); - ggRightLightButton.PutValue(0); - } - else - ggRightLightButton.PutValue(0); - } - } - } - } - } -#endif } else // McZapkie-240302 - klawisze bez shifta { -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - if( cKey == Global::Keys[ k_IncMainCtrl ] ) - { - if (mvControlled->IncMainCtrl(1)) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - } - else if (cKey == Global::Keys[k_DecMainCtrl]) - if (mvControlled->DecMainCtrl(1)) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - else - ; - if (cKey == Global::Keys[k_IncScndCtrl]) - // if (MoverParameters->ScndCtrlPosScndCtrlPosNo) - // if - // (mvControlled->EnginePowerSource.SourceType==CurrentCollector) - if (mvControlled->ShuntMode) - { - mvControlled->AnPos += (Timer::GetDeltaTime() / 0.85f); - if (mvControlled->AnPos > 1) - mvControlled->AnPos = 1; - } - else if (mvControlled->IncScndCtrl(1)) - { - if (dsbNastawnikBocz) // hunter-081211 - { - dsbNastawnikBocz->SetCurrentPosition(0); - dsbNastawnikBocz->Play(0, 0, 0); - } - else if (!dsbNastawnikBocz) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - } - else - ; - else if( cKey == Global::Keys[ k_DecScndCtrl ] ) - // if (mvControlled->EnginePowerSource.SourceType==CurrentCollector) - if (mvControlled->ShuntMode) - { - mvControlled->AnPos -= (Timer::GetDeltaTime() / 0.55f); - if (mvControlled->AnPos < 0) - mvControlled->AnPos = 0; - } - else - - if (mvControlled->DecScndCtrl(1)) - // if (MoverParameters->ScndCtrlPos>0) - { - if (dsbNastawnikBocz) // hunter-081211 - { - dsbNastawnikBocz->SetCurrentPosition(0); - dsbNastawnikBocz->Play(0, 0, 0); - } - else if (!dsbNastawnikBocz) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - } - else - ; -#endif if( cKey == Global::Keys[ k_IncLocalBrakeLevel ] ) { // Ra 2014-09: w // trybie latania @@ -3661,8 +2964,6 @@ void TTrain::OnKeyDown(int cKey) { mvOccupied->IncManualBrakeLevel(1); } - else - ; #ifdef EU07_USE_OLD_COMMAND_SYSTEM else if (mvOccupied->LocalBrake != ManualBrake) mvOccupied->IncLocalBrakeLevel(1); @@ -3679,8 +2980,6 @@ void TTrain::OnKeyDown(int cKey) if (Global::ctrlState) if ((mvOccupied->LocalBrake == ManualBrake) || (mvOccupied->MBrake == true)) mvOccupied->DecManualBrakeLevel(1); - else - ; #ifdef EU07_USE_OLD_COMMAND_SYSTEM else // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku - // odhamować jakoś trzeba @@ -3689,293 +2988,19 @@ void TTrain::OnKeyDown(int cKey) #endif } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else if ((cKey == Global::Keys[k_IncBrakeLevel]) && (mvOccupied->BrakeHandle != FV4a)) - // if (mvOccupied->IncBrakeLevel()) - if (mvOccupied->BrakeLevelAdd(Global::fBrakeStep)) // nieodpowiedni - // warunek; true, jeśli - // można dalej kręcić - { - keybrakecount = 0; - if ((isEztOer) && (mvOccupied->BrakeCtrlPos < 3)) - { // Ra: uzależnić dźwięk od zmiany stanu EP, nie od klawisza - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); - } - } - else - ; - else if ((cKey == Global::Keys[k_DecBrakeLevel]) && (mvOccupied->BrakeHandle != FV4a)) - { - // nową wersję dostarczył ZiomalCl ("fixed looped sound in ezt when using - // NUM_9 key") - if ((mvOccupied->BrakeCtrlPos > -1) || (keybrakecount > 1)) - { - - if ((isEztOer) && (mvControlled->Mains) && (mvOccupied->BrakeCtrlPos != -1)) - { // Ra: uzależnić dźwięk od zmiany stanu EP, nie od klawisza - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); - } - // mvOccupied->DecBrakeLevel(); - mvOccupied->BrakeLevelAdd(-Global::fBrakeStep); - } - else - keybrakecount += 1; - // koniec wersji dostarczonej przez ZiomalCl - /* wersja poprzednia - ten pierwszy if ze średnikiem nie działał jak - warunek - if ((mvOccupied->BrakeCtrlPos>-1)|| (keybrakecount>1)) - { - if (mvOccupied->DecBrakeLevel()); - { - if ((isEztOer) && - (mvOccupied->BrakeCtrlPos<2)&&(keybrakecount<=1)) - { - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0,0,0); - } - } - } - else keybrakecount+=1; - */ - } - else if( cKey == Global::Keys[ k_EmergencyBrake ] ) - { - // while (mvOccupied->IncBrakeLevel()); - mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EB)); - if (mvOccupied->BrakeCtrlPosNo <= 0.1) // hamulec bezpieczeństwa dla wagonów - mvOccupied->EmergencyBrakeFlag = true; - } - else if( cKey == Global::Keys[ k_Brake3 ] ) - { - if ((isEztOer) && ((mvOccupied->BrakeCtrlPos == 1) || (mvOccupied->BrakeCtrlPos == -1))) - { - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); - } - // while (mvOccupied->BrakeCtrlPos>mvOccupied->BrakeCtrlPosNo-1 && - // mvOccupied->DecBrakeLevel()); - // while (mvOccupied->BrakeCtrlPosBrakeCtrlPosNo-1 && - // mvOccupied->IncBrakeLevel()); - mvOccupied->BrakeLevelSet(mvOccupied->BrakeCtrlPosNo - 1); - } -#endif else if (cKey == Global::Keys[k_Brake2]) { -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - if( ( isEztOer ) && ( ( mvOccupied->BrakeCtrlPos == 1 ) || ( mvOccupied->BrakeCtrlPos == -1 ) ) ) - { - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); - } - // while (mvOccupied->BrakeCtrlPos>mvOccupied->BrakeCtrlPosNo/2 && - // mvOccupied->DecBrakeLevel()); - // while (mvOccupied->BrakeCtrlPosBrakeCtrlPosNo/2 && - // mvOccupied->IncBrakeLevel()); - mvOccupied->BrakeLevelSet(mvOccupied->BrakeCtrlPosNo / 2 + - (mvOccupied->BrakeHandle == FV4a ? 1 : 0)); -#endif if (Global::ctrlState) mvOccupied->BrakeLevelSet( - mvOccupied->Handle->GetPos(bh_NP)); // yB: czy ten stos funkcji nie - // powinien być jako oddzielna - // funkcja movera? + mvOccupied->Handle->GetPos(bh_NP)); // yB: czy ten stos funkcji nie powinien być jako oddzielna funkcja movera? } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else if( cKey == Global::Keys[ k_Brake1 ] ) - { - if ((isEztOer) && (mvOccupied->BrakeCtrlPos != 1)) - { - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); - } - // while (mvOccupied->BrakeCtrlPos>1 && mvOccupied->DecBrakeLevel()); - // while (mvOccupied->BrakeCtrlPos<1 && mvOccupied->IncBrakeLevel()); - mvOccupied->BrakeLevelSet(1); - } -#endif else if (cKey == Global::Keys[k_Brake0]) { if (Global::ctrlState) { mvOccupied->BrakeCtrlPos2 = 0; // wyrownaj kapturek } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else - { - if ((isEztOer) && - ((mvOccupied->BrakeCtrlPos == 1) || (mvOccupied->BrakeCtrlPos == -1))) - { - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); - } - // while (mvOccupied->BrakeCtrlPos>0 && mvOccupied->DecBrakeLevel()); - // while (mvOccupied->BrakeCtrlPos<0 && mvOccupied->IncBrakeLevel()); - mvOccupied->BrakeLevelSet(0); - } -#endif } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else if (cKey == Global::Keys[k_WaveBrake]) //[Num.] - { - if ((isEztOer) && (mvControlled->Mains) && (mvOccupied->BrakeCtrlPos != -1)) - { - dsbPneumaticSwitch->SetVolume(-10); - dsbPneumaticSwitch->Play(0, 0, 0); - } - // while (mvOccupied->BrakeCtrlPos>-1 && mvOccupied->DecBrakeLevel()); - // while (mvOccupied->BrakeCtrlPos<-1 && mvOccupied->IncBrakeLevel()); - mvOccupied->BrakeLevelSet(-1); - } - else if (cKey == Global::Keys[k_Czuwak]) - //--------------- - // hunter-131211: zbicie czuwaka przeniesione do TTrain::Update() - { // Ra: tu został tylko dźwięk - // dsbBuzzer->Stop(); - // if (mvOccupied->SecuritySystemReset()) - if (fabs(ggSecurityResetButton.GetValue()) < 0.001) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - // ggSecurityResetButton.PutValue(1); - } - else if( cKey == Global::Keys[ k_AntiSlipping ] ) - //--------------- - // hunter-221211: hamulec przeciwposlizgowy przeniesiony do - // TTrain::Update() - { - if (mvOccupied->BrakeSystem != ElectroPneumatic) - { - // if (mvControlled->AntiSlippingButton()) - if (fabs(ggAntiSlipButton.GetValue()) < 0.001) - { - // Dlaczego bylo '-50'??? - // dsbSwitch->SetVolume(-50); - play_sound( dsbSwitch ); - } - // ggAntiSlipButton.PutValue(1); - } - } - else if( cKey == Global::Keys[ k_Fuse ] ) - //--------------- - { - if (Global::ctrlState) // z controlem - { - ggConverterFuseButton.PutValue(1); // hunter-261211 - if ((mvControlled->Mains == false) && (ggConverterButton.GetValue() < 0.01) && - (mvControlled->TrainType != dt_EZT)) - mvControlled->ConvOvldFlag = false; - } - else - { - ggFuseButton.PutValue(1); - mvControlled->FuseOn(); - } - } - else if (cKey == Global::Keys[k_DirectionForward]) - // McZapkie-240302 - zmiana kierunku: 'd' do przodu, 'r' do tylu - { - if (mvOccupied->DirectionForward()) - { - //------------ - // hunter-121211: dzwiek kierunkowego - if (dsbReverserKey) - { - dsbReverserKey->SetCurrentPosition(0); - dsbReverserKey->SetVolume(DSBVOLUME_MAX); - dsbReverserKey->Play(0, 0, 0); - } - else if (!dsbReverserKey) - if (dsbSwitch) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - //------------ - if (mvOccupied->ActiveDir) // jeśli kierunek niezerowy - if (DynamicObject->Mechanik) // na wszelki wypadek - DynamicObject->Mechanik->CheckVehicles( - Change_direction); // aktualizacja skrajnych pojazdów w składzie - } - } - else if (cKey == Global::Keys[k_DirectionBackward]) // r - { - if (Global::ctrlState) - { // wciśnięty [Ctrl] - if (mvOccupied->Radio == true) - { - play_sound( dsbSwitch ); - mvOccupied->Radio = false; - } - } - else if (mvOccupied->DirectionBackward()) - { - //------------ - // hunter-121211: dzwiek kierunkowego - if (dsbReverserKey) - { - dsbReverserKey->SetCurrentPosition(0); - dsbReverserKey->SetVolume(DSBVOLUME_MAX); - dsbReverserKey->Play(0, 0, 0); - } - else if (!dsbReverserKey) - if (dsbSwitch) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - //------------ - if (mvOccupied->ActiveDir) // jeśli kierunek niezerowy - if (DynamicObject->Mechanik) // na wszelki wypadek - DynamicObject->Mechanik->CheckVehicles( - Change_direction); // aktualizacja skrajnych pojazdów w składzie - } - } - else if( cKey == Global::Keys[ k_Main ] ) - // McZapkie-240302 - wylaczanie glownego obwodu - //----------- - // hunter-141211: wyl. szybki wylaczony przeniesiony do TTrain::Update() - { - if (fabs(ggMainOffButton.GetValue()) < 0.001) - if (dsbSwitch) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else if( cKey == Global::Keys[ k_Battery ] ) - { - // if ((mvControlled->TrainType==dt_EZT) || - // (mvControlled->EngineType==ElectricSeriesMotor)|| - // (mvControlled->EngineType==DieselElectric)) - if (mvOccupied->BatterySwitch(false)) - { // ewentualnie zablokować z FIZ, - // np. w samochodach się nie - // odłącza akumulatora - if (ggBatteryButton.SubModel) - { - ggBatteryButton.PutValue(0); - } - dsbSwitch->Play(0, 0, 0); - // mvOccupied->SecuritySystem.Status=0; - mvControlled->PantFront(false); - mvControlled->PantRear(false); - } - } -#endif - //----------- - // if (cKey==Global::Keys[k_Active]) //yB 300407: przelacznik - // rozrzadu - // { - // if (mvControlled->CabDeactivisation()) - // { - // dsbSwitch->SetVolume(DSBVOLUME_MAX); - // dsbSwitch->Play(0,0,0); - // } - // } - // else if (cKey == Global::Keys[k_BrakeProfile]) { // yB://ABu: male poprawki, zeby // bylo mozna ustawic dowolny @@ -4022,68 +3047,6 @@ void TTrain::OnKeyDown(int cKey) } } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else if (cKey == Global::Keys[k_Converter]) - //----------- - // hunter-261211: przetwornica i sprzezarka przeniesione do - // TTrain::Update() - { - if (ggConverterButton.GetValue() != 0) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - // if - // ((cKey==Global::Keys[k_Compressor])&&((mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->TrainType==dt_EZT))) - // //hunter-110212: poprawka dla EZT - else if ((cKey == Global::Keys[k_Compressor]) && - (mvControlled->CompressorPower < 2)) // hunter-091012: tak jest poprawnie - { - if (ggCompressorButton.GetValue() != 0) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - //----------- - else if( cKey == Global::Keys[ k_Releaser ] ) // odluzniacz - { - if (!FreeFlyModeFlag) - { - if ((mvControlled->EngineType == ElectricSeriesMotor) || - (mvControlled->EngineType == DieselElectric) || - (mvControlled->EngineType == ElectricInductionMotor)) - if (mvControlled->TrainType != dt_EZT) - if (mvOccupied->BrakeCtrlPosNo > 0) - { - ggReleaserButton.PutValue(1); - mvOccupied->BrakeReleaser(1); - // if (mvOccupied->BrakeReleaser(1)) - // { - // dsbPneumaticRelay->SetVolume(-80); - // dsbPneumaticRelay->Play(0, 0, 0); - // } - } - } - } - else if (cKey == Global::Keys[k_SmallCompressor]) // Winger 160404: mala sprezarka wl - { // Ra: bez [Shift] też dać dźwięk - if ((mvControlled->TrainType & dt_EZT) ? mvControlled == mvOccupied : - !mvOccupied->ActiveCab) // tylko w maszynowym - if (Global::ctrlState) // z [Ctrl] - mvControlled->bPantKurek3 = - false; // zbiornik pantografu połączony jest z małą sprężarką - // (pompowanie ma sens, ale potem trzeba przełączyć) - else if( !mvControlled->PantCompFlag ) // jeśli wyłączona - if (mvControlled->Battery) // jeszcze musi być załączona bateria - if (mvControlled->PantPress < 4.8) // piszą, że to tak nie działa - { - mvControlled->PantCompFlag = true; - play_sound( dsbSwitch ); // dźwięk tylko po naciśnięciu klawisza - } - } -#endif // McZapkie-240302 - wylaczanie automatycznego pilota (w trybie ~debugmode // mozna tylko raz) else if (cKey == GLFW_KEY_Q) // bez Shift @@ -4091,56 +3054,6 @@ void TTrain::OnKeyDown(int cKey) if (DynamicObject->Mechanik) DynamicObject->Mechanik->TakeControl(false); } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else if( cKey == Global::Keys[ k_MaxCurrent ] ) // McZapkie-160502: f - niski rozruch - { - if ((mvControlled->EngineType == DieselElectric) && (mvControlled->ShuntModeAllow) && - (mvControlled->MainCtrlPos == 0)) - { - mvControlled->ShuntMode = false; - } - if (mvControlled->CurrentSwitch(false)) - { - play_sound( dsbSwitch ); - } - } - else if (cKey == Global::Keys[k_CurrentAutoRelay]) // McZapkie-241002: g - - // wylaczanie PSR - { - if (mvControlled->AutoRelaySwitch(false)) - { - play_sound( dsbSwitch ); - } - } - // hunter-201211: piasecznica poprawiona oraz przeniesiona do - // TTrain::Update() - else if( cKey == Global::Keys[ k_Sand ] ) - { - /* - if (mvControlled->TrainType!=dt_EZT) - { - if (mvControlled->SandDoseOn()) - if (mvControlled->SandDose) - { - dsbPneumaticRelay->SetVolume(-30); - dsbPneumaticRelay->Play(0,0,0); - } - } - */ - if (mvControlled->TrainType == dt_EZT) - { - if (ggDoorSignallingButton.SubModel != NULL) - { - if (mvControlled->DoorSignalling) - { - mvOccupied->DoorBlocked = false; - play_sound( dsbSwitch ); - mvControlled->DoorSignalling = false; - } - } - } - } -#endif else if (cKey == Global::Keys[k_CabForward]) { if (!CabChange(1)) @@ -4337,239 +3250,6 @@ if } } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else if (cKey == Global::Keys[k_CloseLeft]) // NBMX 17-09-2003: zamykanie drzwi - { - if( mvOccupied->DoorCloseCtrl == 1 ) { - if( mvOccupied->CabNo < 0 ? mvOccupied->DoorRight( false ) : mvOccupied->DoorLeft( false ) ) { - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - if( dsbDoorClose ) { - dsbDoorClose->SetCurrentPosition( 0 ); - dsbDoorClose->Play( 0, 0, 0 ); - } - } - } - } - else if (cKey == Global::Keys[k_CloseRight]) // NBMX 17-09-2003: zamykanie drzwi - { - if( mvOccupied->DoorCloseCtrl == 1 ) { - if( mvOccupied->CabNo < 0 ? mvOccupied->DoorLeft( false ) : mvOccupied->DoorRight( false ) ) { - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - if( dsbDoorClose ) { - dsbDoorClose->SetCurrentPosition( 0 ); - dsbDoorClose->Play( 0, 0, 0 ); - } - } - } - } - //----------- - // hunter-131211: dzwiek dla przelacznika universala - // hunter-091012: ubajerowanie swiatla w kabinie (wyrzucenie - // przyciemnienia pod Univ4) - else if (cKey == Global::Keys[k_Univ3]) - { - if (Global::ctrlState) - { - if (bCabLight == true) //(ggCabLightButton.GetValue()!=0) - { - play_sound( dsbSwitch ); - } - } - else - { - if (ggUniversal3Button.GetValue() != 0) - { - play_sound( dsbSwitch ); - } - /* - if (Global::ctrlState) - {//z [Ctrl] zapalamy albo gasimy światełko w kabinie - if (iCabLightFlag) --iCabLightFlag; //gaszenie - } */ - } - } - //----------- - // hunter-091012: dzwiek dla przyciemnienia swiatelka w kabinie - else if (cKey == Global::Keys[k_Univ4]) - { - if (Global::ctrlState) - { - if (bCabLightDim == true) //(ggCabLightDimButton.GetValue()!=0) - { - play_sound( dsbSwitch ); - } - } - } - //----------- - else if (cKey == Global::Keys[k_PantFrontDown]) // Winger 160204: - // opuszczanie prz. patyka - { - if (mvOccupied->ActiveCab == - 1) //||((mvOccupied->ActiveCab<1)&&(mvControlled->TrainType!=dt_ET40)&&(mvControlled->TrainType!=dt_ET41)&&(mvControlled->TrainType!=dt_ET42)&&(mvControlled->TrainType!=dt_EZT))) - { - // if (!mvControlled->PantFrontUp) //jeśli był opuszczony - // if () //jeśli połamany - // //to powtórzone opuszczanie naprawia - if (mvControlled->PantFront(false)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else - // if - // ((mvOccupied->ActiveCab<1)&&((mvControlled->TrainType==dt_ET40)||(mvControlled->TrainType==dt_ET41)||(mvControlled->TrainType==dt_ET42)||(mvControlled->TrainType==dt_EZT))) - { - if (mvControlled->PantRear(false)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - } - else if (cKey == Global::Keys[k_PantRearDown]) // Winger 160204: - // opuszczanie tyl. patyka - { - if (mvOccupied->ActiveCab == - 1) //||((mvOccupied->ActiveCab<1)&&(mvControlled->TrainType!=dt_ET40)&&(mvControlled->TrainType!=dt_ET41)&&(mvControlled->TrainType!=dt_ET42)&&(mvControlled->TrainType!=dt_EZT))) - { - if (mvControlled->PantSwitchType == "impulse") - ggPantFrontButtonOff.PutValue(1); - if (mvControlled->PantRear(false)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else - // if - // ((mvOccupied->ActiveCab<1)&&((mvControlled->TrainType==dt_ET40)||(mvControlled->TrainType==dt_ET41)||(mvControlled->TrainType==dt_ET42)||(mvControlled->TrainType==dt_EZT))) - { - /* if (mvControlled->PantSwitchType=="impulse") - ggPantRearButtonOff.PutValue(1); */ - if (mvControlled->PantFront(false)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - } - else if( cKey == Global::Keys[ k_Heating ] ) // Winger 020304: ogrzewanie - - // wylaczenie - { // Ra 2014-09: w trybie latania obsługa jest w World.cpp - if (!FreeFlyModeFlag) - { - if (mvControlled->Heating == true) - { - play_sound( dsbSwitch ); - mvControlled->Heating = false; - } - } - } - else if (cKey == Global::Keys[k_LeftSign]) // ABu 060205: lewe swiatlo - - // wylaczenie - { - if (false == (mvOccupied->LightsPosNo > 0)) - { - if ((Global::ctrlState) && - (ggRearLeftLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu - // 17.02.17 changed rear to opposite side, so the same key actually controls both lights on the left side, from the driver's point of view - // TODO: do it a more elegant way. preferably along with the rest of the controlling code - { - //------------------------------ - if( mvOccupied->ActiveCab == 1 ) { // kabina 1 (od strony 0) - if( ( ( DynamicObject->iLights[ 1 ] ) & 48 ) == 0 ) { - DynamicObject->iLights[ 1 ] |= 32; - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - if( ggRearRightEndLightButton.SubModel ) { - ggRearRightEndLightButton.PutValue( 1 ); - ggRearRightLightButton.PutValue( 0 ); - } - else - ggRearRightLightButton.PutValue( -1 ); - } - if( ( ( DynamicObject->iLights[ 1 ] ) & 48 ) == 16 ) { - DynamicObject->iLights[ 1 ] &= ( 255 - 16 ); - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - ggRearRightLightButton.PutValue( 0 ); - } - } - else { // kabina -1 - if( ( ( DynamicObject->iLights[ 0 ] ) & 48 ) == 0 ) { - DynamicObject->iLights[ 0 ] |= 32; - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - if( ggRearRightEndLightButton.SubModel ) { - ggRearRightEndLightButton.PutValue( 1 ); - ggRearRightLightButton.PutValue( 0 ); - } - else - ggRearRightLightButton.PutValue( -1 ); - } - if( ( ( DynamicObject->iLights[ 0 ] ) & 48 ) == 16 ) { - DynamicObject->iLights[ 0 ] &= ( 255 - 16 ); - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - ggRearRightLightButton.PutValue( 0 ); - } - } - } //------------------------------ - else - { - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[0]) & 3) == 0) - { - DynamicObject->iLights[0] |= 2; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggLeftEndLightButton.SubModel) - { - ggLeftEndLightButton.PutValue(1); - ggLeftLightButton.PutValue(0); - } - else - ggLeftLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[0]) & 3) == 1) - { - DynamicObject->iLights[0] &= (255 - 1); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggLeftLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[1]) & 3) == 0) - { - DynamicObject->iLights[1] |= 2; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggLeftEndLightButton.SubModel) - { - ggLeftEndLightButton.PutValue(1); - ggLeftLightButton.PutValue(0); - } - else - ggLeftLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[1]) & 3) == 1) - { - DynamicObject->iLights[1] &= (255 - 1); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggLeftLightButton.PutValue(0); - } - } - } - } - } -#endif else if (cKey == Global::Keys[k_UpperSign]) // ABu 060205: światło górne - // wyłączenie { @@ -4586,244 +3266,7 @@ if SetLights(); } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - else if ((Global::ctrlState) && - (ggRearUpperLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu - { - //------------------------------ - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[1]) & 12) == 4) - { - DynamicObject->iLights[1] &= (255 - 4); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearUpperLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[0]) & 12) == 4) - { - DynamicObject->iLights[0] &= (255 - 4); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearUpperLightButton.PutValue(0); - } - } - } //------------------------------ - else - { - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[0]) & 12) == 4) - { - DynamicObject->iLights[0] &= (255 - 4); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggUpperLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[1]) & 12) == 4) - { - DynamicObject->iLights[1] &= (255 - 4); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggUpperLightButton.PutValue(0); - } - } - } -#endif } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - if (cKey == Global::Keys[k_RightSign]) // Winger 070304: swiatla tylne - // (koncowki) - wlaczenie - { - if (false == (mvOccupied->LightsPosNo > 0)) - { - if ((Global::ctrlState) && - (ggRearRightLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu - // 17.02.17 changed rear to opposite side, so the same key actually controls both lights on the left side, from the driver's point of view - // TODO: do it a more elegant way. preferably along with the rest of the controlling code - { - //------------------------------ - if( mvOccupied->ActiveCab == 1 ) { // kabina 1 - if( ( ( DynamicObject->iLights[ 1 ] ) & 3 ) == 0 ) { - DynamicObject->iLights[ 1 ] |= 2; - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - if( ggRearLeftEndLightButton.SubModel ) { - ggRearLeftEndLightButton.PutValue( 1 ); - ggRearLeftLightButton.PutValue( 0 ); - } - else - ggRearLeftLightButton.PutValue( -1 ); - } - if( ( ( DynamicObject->iLights[ 1 ] ) & 3 ) == 1 ) { - DynamicObject->iLights[ 1 ] &= ( 255 - 1 ); - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - ggRearLeftLightButton.PutValue( 0 ); - } - } - else { // kabina -1 - if( ( ( DynamicObject->iLights[ 0 ] ) & 3 ) == 0 ) { - DynamicObject->iLights[ 0 ] |= 2; - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - if( ggRearLeftEndLightButton.SubModel ) { - ggRearLeftEndLightButton.PutValue( 1 ); - ggRearLeftLightButton.PutValue( 0 ); - } - else - ggRearLeftLightButton.PutValue( -1 ); - } - if( ( ( DynamicObject->iLights[ 1 ] ) & 3 ) == 1 ) { - DynamicObject->iLights[ 1 ] &= ( 255 - 1 ); - dsbSwitch->SetVolume( DSBVOLUME_MAX ); - dsbSwitch->Play( 0, 0, 0 ); - ggLeftLightButton.PutValue( 0 ); - } - } - } //------------------------------ - else - { - if (mvOccupied->ActiveCab == 1) - { // kabina 0 - if (((DynamicObject->iLights[0]) & 48) == 0) - { - DynamicObject->iLights[0] |= 32; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRightEndLightButton.SubModel) - { - ggRightEndLightButton.PutValue(1); - ggRightLightButton.PutValue(0); - } - else - ggRightLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[0]) & 48) == 16) - { - DynamicObject->iLights[0] &= (255 - 16); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRightLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[1]) & 48) == 0) - { - DynamicObject->iLights[1] |= 32; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRightEndLightButton.SubModel) - { - ggRightEndLightButton.PutValue(1); - ggRightLightButton.PutValue(0); - } - else - ggRightLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[1]) & 48) == 16) - { - DynamicObject->iLights[1] &= (255 - 16); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRightLightButton.PutValue(0); - } - } - } - } - } - else if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // Winger 110904: wylacznik st. - // liniowych - { - if( ( mvControlled->TrainType != dt_EZT ) && ( mvControlled->TrainType != dt_EP05 ) && - (mvControlled->TrainType != dt_ET40)) - { - ggStLinOffButton.PutValue(1); // Ra: było Fuse... - play_sound( dsbSwitch ); - if (mvControlled->MainCtrlPosNo > 0) - { - mvControlled->StLinFlag = - false; // yBARC - zmienione na przeciwne, bo true to zalaczone - play_sound( dsbRelay ); - } - } - if (mvControlled->TrainType == dt_EZT) - { - if (mvControlled->Signalling == true) - { - play_sound( dsbSwitch ); - mvControlled->Signalling = false; - } - } - } -#endif - else - { - // McZapkie: poruszanie sie po kabinie, w updatemechpos zawarte sa wiezy -/* - auto step = 1.0f; - auto const camerayaw = Global::pCamera->Yaw; - Math3D::vector3 direction( 0.0f, 0.0f, step ); - direction.RotateY( camerayaw ); - Math3D::vector3 right( -step, 0.0f, 0.0f ); - right.RotateY( camerayaw ); - // auto right = Math3D::CrossProduct( direction, Math3D::vector3( 0.0f, 1.0f, 0.0f ) ); - - if( mvOccupied->ActiveCab < 0 ) { - - direction *= -1.0f; - right *= -1.0f; - } - // if (!GetAsyncKeyState(VK_SHIFT)<0) // bez shifta - if (!Global::ctrlState) // gdy [Ctrl] zwolniony (dodatkowe widoki) - { - if (cKey == Global::Keys[k_MechLeft]) - { - vMechMovement -= right; - if (DynamicObject->Mechanik) - if (!FreeFlyModeFlag) //żeby nie mieszać obserwując z zewnątrz - DynamicObject->Mechanik->RouteSwitch( - 1); // na skrzyżowaniu skręci w lewo - } - else if (cKey == Global::Keys[k_MechRight]) - { - vMechMovement += right; - if (DynamicObject->Mechanik) - if (!FreeFlyModeFlag) //żeby nie mieszać obserwując z zewnątrz - DynamicObject->Mechanik->RouteSwitch( - 2); // na skrzyżowaniu skręci w prawo - } - else if (cKey == Global::Keys[k_MechBackward]) - { - vMechMovement -= direction; - // if (DynamicObject->Mechanik) - // if (!FreeFlyModeFlag) //żeby nie mieszać obserwując z zewnątrz - // DynamicObject->Mechanik->RouteSwitch(0); //na skrzyżowaniu stanie - // i poczeka - } - else if (cKey == Global::Keys[k_MechForward]) - { - vMechMovement += direction; - if (DynamicObject->Mechanik) - if (!FreeFlyModeFlag) //żeby nie mieszać obserwując z zewnątrz - DynamicObject->Mechanik->RouteSwitch( - 3); // na skrzyżowaniu pojedzie prosto - } - else if (cKey == Global::Keys[k_MechUp]) - pMechOffset.y += 0.25; // McZapkie-120302 - wstawanie - else if (cKey == Global::Keys[k_MechDown]) - pMechOffset.y -= 0.25; // McZapkie-120302 - siadanie - } -*/ - } - // else if (DebugModeFlag) { // przesuwanie składu o 100m @@ -4868,48 +3311,8 @@ if ++iRadioChannel; // 0=wyłączony } } -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - // TODO: break the mess above into individual command-based routines. - // TODO: test for modifiers inside the routines, instead of grouping by the modifier - // TODO: do away with the modifier tests, each command should be separate and issued by input processor(s) up the chain - if( cKey == Global::Keys[ k_DimHeadlights ] ) { - // headlight strength toggle - if( !Global::ctrlState ) { - // switch uses either ctrl, or ctrl+shift, so we can bail early here - return; - } - if( DynamicObject->DimHeadlights && (!Global::shiftState)) { - DynamicObject->DimHeadlights = false; - // switch sound - play_sound( dsbSwitch ); - } - else if( (!DynamicObject->DimHeadlights) && (Global::shiftState)) { - DynamicObject->DimHeadlights = true; - // switch sound - play_sound( dsbSwitch ); - } - } -#endif } -void TTrain::OnKeyUp(int cKey) -{ // zwolnienie klawisza -#ifdef EU07_USE_OLD_COMMAND_SYSTEM - if( Global::shiftState ) - { // wciśnięty [Shift] - } - else - { - if ((cKey == Global::Keys[k_StLinOff]) && (!Global::shiftState) && (!Global::ctrlState)) // Winger 110904: wylacznik st. liniowych - { // zwolnienie klawisza daje powrót przycisku do zwykłego stanu - if ((mvControlled->TrainType != dt_EZT) && (mvControlled->TrainType != dt_EP05) && - (mvControlled->TrainType != dt_ET40)) - ggStLinOffButton.PutValue(0); - } - } -#endif -}; - // cab movement update, fixed step part void TTrain::UpdateMechPosition(double dt) { // Ra: mechanik powinien być diff --git a/Train.h b/Train.h index e2658c1b..60e212fb 100644 --- a/Train.h +++ b/Train.h @@ -23,16 +23,12 @@ http://mozilla.org/MPL/2.0/. const int maxcab = 2; -// const double fCzuwakTime= 90.0f; const double fCzuwakBlink = 0.15; const float fConverterPrzekaznik = 1.5f; // hunter-261211: do przekaznika nadmiarowego przetwornicy // 0.33f // const double fBuzzerTime= 5.0f; const float fHaslerTime = 1.2f; -// const double fStycznTime= 0.5f; -// const double fDblClickTime= 0.2f; - class TCab { public: @@ -73,7 +69,6 @@ class TTrain // McZapkie-010302 bool Init(TDynamicObject *NewDynamicObject, bool e3d = false); void OnKeyDown(int cKey); - void OnKeyUp(int cKey); inline vector3 GetDirection() { return DynamicObject->VectorFront(); }; inline vector3 GetUp() { return DynamicObject->VectorUp(); }; @@ -423,8 +418,7 @@ public: // reszta może by?publiczna // TFadeSound sConverter; //przetwornica // TFadeSound sSmallCompressor; //przetwornica - int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: - // przyciemnione, 2: pelne) + int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne) bool bCabLight; // hunter-091012: czy swiatlo jest zapalone? bool bCabLightDim; // hunter-091012: czy przyciemnienie kabiny jest zapalone? diff --git a/World.cpp b/World.cpp index da1c2575..aaf67aa7 100644 --- a/World.cpp +++ b/World.cpp @@ -824,15 +824,6 @@ void TWorld::OnKeyDown(int cKey) //} } -void TWorld::OnKeyUp(int cKey) -{ // zwolnienie klawisza; (cKey) to kod klawisza, cyfrowe i literowe się zgadzają - if (!Global::iPause) // podczas pauzy sterownaie nie działa - if (Train) - if (Controlled) - if ((Controlled->Controller == Humandriver) ? true : DebugModeFlag || (cKey == 'Q')) - Train->OnKeyUp(cKey); // przekazanie zwolnienia klawisza do kabiny -}; - void TWorld::OnMouseMove(double x, double y) { // McZapkie:060503-definicja obracania myszy Camera.OnCursorMove(x * Global::fMouseXScale / Global::ZoomFactor, -y * Global::fMouseYScale / Global::ZoomFactor); diff --git a/World.h b/World.h index 312bd3cf..36ae1b76 100644 --- a/World.h +++ b/World.h @@ -101,7 +101,6 @@ TWorld(); bool InitPerformed() { return m_init; } GLFWwindow *window; void OnKeyDown(int cKey); - void OnKeyUp(int cKey); // void UpdateWindow(); void OnMouseMove(double x, double y); void OnCommandGet(DaneRozkaz *pRozkaz);