diff --git a/Globals.cpp b/Globals.cpp index a766bd8c..2c4d8ab8 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -127,7 +127,7 @@ global_settings::ConfigParse(cParser &Parser) { // selected device for audio renderer Parser.getTokens(); Parser >> AudioVolume; - AudioVolume = clamp( AudioVolume, 1.f, 4.f ); + AudioVolume = clamp( AudioVolume, 0.0f, 2.f ); } // else if (str==AnsiString("renderalpha")) //McZapkie-1312302 - dwuprzebiegowe renderowanie // bRenderAlpha=(GetNextSymbol().LowerCase()==AnsiString("yes")); diff --git a/Globals.h b/Globals.h index 963249b4..b5b842fa 100644 --- a/Globals.h +++ b/Globals.h @@ -40,7 +40,7 @@ struct global_settings { std::string LastGLError; float ZoomFactor{ 1.f }; // determines current camera zoom level. TODO: move it to the renderer bool CabWindowOpen{ false }; // controls sound attenuation between cab and outside - bool ControlPicking{ false }; // indicates controls pick mode is active + bool ControlPicking{ true }; // indicates controls pick mode is active bool DLFont{ false }; // switch indicating presence of basic font bool bActive{ true }; // czy jest aktywnym oknem int iPause{ 0 }; // globalna pauza ruchu: b0=start,b1=klawisz,b2=tło,b3=lagi,b4=wczytywanie diff --git a/audiorenderer.cpp b/audiorenderer.cpp index a9b66e47..c02379fb 100644 --- a/audiorenderer.cpp +++ b/audiorenderer.cpp @@ -154,7 +154,7 @@ openal_source::sync_with( sound_properties const &State ) { properties.soundproofing = State.soundproofing; properties.soundproofing_stamp = State.soundproofing_stamp; - ::alSourcef( id, AL_GAIN, properties.gain * properties.soundproofing * Global.AudioVolume ); + ::alSourcef( id, AL_GAIN, properties.gain * properties.soundproofing ); } if( sound_range > 0 ) { auto const rangesquared { sound_range * sound_range }; @@ -170,7 +170,7 @@ openal_source::sync_with( sound_properties const &State ) { clamp( ( distancesquared - rangesquared ) / ( fadedistance * fadedistance ), 0.f, 1.f ) ) }; - ::alSourcef( id, AL_GAIN, properties.gain * properties.soundproofing * rangefactor * Global.AudioVolume ); + ::alSourcef( id, AL_GAIN, properties.gain * properties.soundproofing * rangefactor ); } is_in_range = ( distancesquared <= rangesquared ); } @@ -283,10 +283,7 @@ openal_renderer::init() { // basic initialization failed return false; } - // -// ::alDistanceModel( AL_LINEAR_DISTANCE ); ::alDistanceModel( AL_INVERSE_DISTANCE_CLAMPED ); - ::alListenerf( AL_GAIN, clamp( Global.AudioVolume, 1.f, 4.f ) ); // all done m_ready = true; return true; @@ -319,6 +316,8 @@ void openal_renderer::update( double const Deltatime ) { // update listener + // gain + ::alListenerf( AL_GAIN, clamp( Global.AudioVolume, 0.f, 2.f ) * ( Global.iPause == 0 ? 1.f : 0.15f ) ); // orientation glm::dmat4 cameramatrix; Global.pCamera.SetMatrix( cameramatrix ); diff --git a/drivermode.cpp b/drivermode.cpp index e952a0ae..05488a7f 100644 --- a/drivermode.cpp +++ b/drivermode.cpp @@ -299,9 +299,7 @@ driver_mode::enter() { Timer::ResetTimers(); - Application.set_cursor( GLFW_CURSOR_DISABLED ); - Application.set_cursor_pos( 0, 0 ); - Global.ControlPicking = false; + set_picking( Global.ControlPicking ); } // maintenance method, called when the mode is deactivated @@ -351,6 +349,9 @@ driver_mode::on_key( int const Key, int const Scancode, int const Action, int co void driver_mode::on_cursor_pos( double const Horizontal, double const Vertical ) { + // give the ui first shot at the input processing... + if( true == m_userinterface->on_cursor_pos( Horizontal, Vertical ) ) { return; } + if( false == Global.ControlPicking ) { // in regular view mode keep cursor on screen Application.set_cursor_pos( 0, 0 ); @@ -362,6 +363,9 @@ driver_mode::on_cursor_pos( double const Horizontal, double const Vertical ) { void driver_mode::on_mouse_button( int const Button, int const Action, int const Mods ) { + // give the ui first shot at the input processing... + if( true == m_userinterface->on_mouse_button( Button, Action ) ) { return; } + // give the potential event recipient a shot at it, in the virtual z order m_input.mouse.button( Button, Action ); } @@ -561,8 +565,8 @@ driver_mode::OnKeyDown(int cKey) { // actual key processing // TODO: redo the input system - if( ( cKey >= GLFW_KEY_0 ) && ( cKey <= GLFW_KEY_9 ) ) // klawisze cyfrowe - { + if( ( cKey >= GLFW_KEY_0 ) && ( cKey <= GLFW_KEY_9 ) ) { + // klawisze cyfrowe int i = cKey - GLFW_KEY_0; // numer klawisza if (Global.shiftState) { // z [Shift] uruchomienie eventu @@ -600,217 +604,183 @@ driver_mode::OnKeyDown(int cKey) { } } } + return; } - else if( ( cKey >= GLFW_KEY_F1 ) && ( cKey <= GLFW_KEY_F12 ) ) - { - switch (cKey) { - case GLFW_KEY_F1: { + switch (cKey) { - if( DebugModeFlag ) { - // additional simulation clock jump keys in debug mode - if( Global.ctrlState ) { - // ctrl-f1 - simulation::Time.update( 20.0 * 60.0 ); - } - else if( Global.shiftState ) { - // shift-f1 - simulation::Time.update( 5.0 * 60.0 ); - } - } - break; - } - - case GLFW_KEY_F4: { - - InOutKey( !Global.shiftState ); // distant view with Shift, short distance step out otherwise - break; - } - case GLFW_KEY_F5: { - // przesiadka do innego pojazdu - if( false == FreeFlyModeFlag ) { - // only available in free fly mode - break; - } - - TDynamicObject *tmp = std::get( simulation::Region->find_vehicle( Global.pCamera.Pos, 50, true, false ) ); - - if( tmp != nullptr ) { - - if( simulation::Train ) {// jeśli mielismy pojazd - if( simulation::Train->Dynamic()->Mechanik ) { // na skutek jakiegoś błędu może czasem zniknąć - simulation::Train->Dynamic()->Mechanik->TakeControl( true ); // oddajemy dotychczasowy AI - } - } - - if( ( true == DebugModeFlag ) - || ( tmp->MoverParameters->Vel <= 5.0 ) ) { - // works always in debug mode, or for stopped/slow moving vehicles otherwise - if( simulation::Train == nullptr ) { - simulation::Train = new TTrain(); // jeśli niczym jeszcze nie jeździlismy - } - if( simulation::Train->Init( tmp ) ) { // przejmujemy sterowanie - simulation::Train->Dynamic()->Mechanik->TakeControl( false ); - } - else { - SafeDelete( simulation::Train ); // i nie ma czym sterować - } - if( simulation::Train ) { - InOutKey(); // do kabiny - } - } - } - break; - } - case GLFW_KEY_F6: { - // przyspieszenie symulacji do testowania scenerii... uwaga na FPS! - if( DebugModeFlag ) { - - if( Global.ctrlState ) { Global.fTimeSpeed = ( Global.shiftState ? 60.0 : 20.0 ); } - else { Global.fTimeSpeed = ( Global.shiftState ? 5.0 : 1.0 ); } - } - break; - } - case GLFW_KEY_F7: { - // debug mode functions - if( DebugModeFlag ) { - - if( Global.ctrlState - && Global.shiftState ) { - // shift + ctrl + f7 toggles between debug and regular camera - DebugCameraFlag = !DebugCameraFlag; - } - else if( Global.ctrlState ) { - // ctrl + f7 toggles static daylight - simulation::Environment.toggle_daylight(); - break; - } - else if( Global.shiftState ) { - // shift + f7 is currently unused - } - else { - // f7: wireframe toggle - // TODO: pass this to renderer instead of making direct calls - Global.bWireFrame = !Global.bWireFrame; - if( true == Global.bWireFrame ) { - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - } - else { - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - } - } - } - break; - } - case GLFW_KEY_F11: { - // editor mode - if( ( false == Global.ctrlState ) - && ( false == Global.shiftState ) ) { - Application.push_mode( eu07_application::mode::editor ); - } - break; - } - case GLFW_KEY_F12: { - // quick debug mode toggle - if( Global.ctrlState - && Global.shiftState ) { - DebugModeFlag = !DebugModeFlag; - } - break; - } - - default: { - break; - } - } - // if (cKey!=VK_F4) - return; // nie są przekazywane do pojazdu wcale - } -/* - if ((Global.iTextMode == GLFW_KEY_F12) ? (cKey >= '0') && (cKey <= '9') : false) - { // tryb konfiguracji debugmode (przestawianie kamery już wyłączone - if (!Global.shiftState) // bez [Shift] - { - if (cKey == GLFW_KEY_1) - Global.iWriteLogEnabled ^= 1; // włącz/wyłącz logowanie do pliku - else if (cKey == GLFW_KEY_2) - { // włącz/wyłącz okno konsoli - Global.iWriteLogEnabled ^= 2; - if ((Global.iWriteLogEnabled & 2) == 0) // nie było okienka - { // otwarcie okna - AllocConsole(); // jeśli konsola już jest, to zwróci błąd; uwalniać nie ma po - // co, bo się odłączy - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN); - } - } - // 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 - // odpauzowanie, gdy po wczytaniu miało nie startować - Global.iPause &= ~1; - } - else if( ( Global.iMultiplayer & 2 ) == 0 ) { - // w multiplayerze pauza nie ma sensu - Global.iPause ^= 2; // zmiana stanu zapauzowania - if( ( Global.iPause & 2 ) - && ( false == Global.ControlPicking ) ) { - set_picking( true ); - } - } - } - else { - - if( ( true == DebugModeFlag ) - && ( false == Global.shiftState ) - && ( true == Global.ctrlState ) - && ( simulation::Train != nullptr ) - && ( simulation::Train->Dynamic()->Controller == Humandriver ) ) { + case GLFW_KEY_F1: { if( DebugModeFlag ) { - // przesuwanie składu o 100m - auto *vehicle { simulation::Train->Dynamic() }; - TDynamicObject *d = vehicle; - if( cKey == GLFW_KEY_LEFT_BRACKET ) { - while( d ) { - d->Move( 100.0 * d->DirectionGet() ); - d = d->Next(); // pozostałe też - } - d = vehicle->Prev(); - while( d ) { - d->Move( 100.0 * d->DirectionGet() ); - d = d->Prev(); // w drugą stronę też + // additional simulation clock jump keys in debug mode + if( Global.ctrlState ) { + // ctrl-f1 + simulation::Time.update( 20.0 * 60.0 ); + } + else if( Global.shiftState ) { + // shift-f1 + simulation::Time.update( 5.0 * 60.0 ); + } + } + break; + } + + case GLFW_KEY_F4: { + + InOutKey( !Global.shiftState ); // distant view with Shift, short distance step out otherwise + break; + } + case GLFW_KEY_F5: { + // przesiadka do innego pojazdu + if( false == FreeFlyModeFlag ) { + // only available in free fly mode + break; + } + + TDynamicObject *tmp = std::get( simulation::Region->find_vehicle( Global.pCamera.Pos, 50, true, false ) ); + + if( tmp != nullptr ) { + + if( simulation::Train ) {// jeśli mielismy pojazd + if( simulation::Train->Dynamic()->Mechanik ) { // na skutek jakiegoś błędu może czasem zniknąć + simulation::Train->Dynamic()->Mechanik->TakeControl( true ); // oddajemy dotychczasowy AI } } - else if( cKey == GLFW_KEY_RIGHT_BRACKET ) { - while( d ) { - d->Move( -100.0 * d->DirectionGet() ); - d = d->Next(); // pozostałe też + + if( ( true == DebugModeFlag ) + || ( tmp->MoverParameters->Vel <= 5.0 ) ) { + // works always in debug mode, or for stopped/slow moving vehicles otherwise + if( simulation::Train == nullptr ) { + simulation::Train = new TTrain(); // jeśli niczym jeszcze nie jeździlismy } - d = vehicle->Prev(); - while( d ) { - d->Move( -100.0 * d->DirectionGet() ); - d = d->Prev(); // w drugą stronę też + if( simulation::Train->Init( tmp ) ) { // przejmujemy sterowanie + simulation::Train->Dynamic()->Mechanik->TakeControl( false ); } - } - else if( cKey == GLFW_KEY_TAB ) { - while( d ) { - d->MoverParameters->V += d->DirectionGet()*2.78; - d = d->Next(); // pozostałe też + else { + SafeDelete( simulation::Train ); // i nie ma czym sterować } - d = vehicle->Prev(); - while( d ) { - d->MoverParameters->V += d->DirectionGet()*2.78; - d = d->Prev(); // w drugą stronę też + if( simulation::Train ) { + InOutKey(); // do kabiny } } } + break; + } + case GLFW_KEY_F6: { + // przyspieszenie symulacji do testowania scenerii... uwaga na FPS! + if( DebugModeFlag ) { + + if( Global.ctrlState ) { Global.fTimeSpeed = ( Global.shiftState ? 60.0 : 20.0 ); } + else { Global.fTimeSpeed = ( Global.shiftState ? 5.0 : 1.0 ); } + } + break; + } + case GLFW_KEY_F7: { + // debug mode functions + if( DebugModeFlag ) { + + if( Global.ctrlState + && Global.shiftState ) { + // shift + ctrl + f7 toggles between debug and regular camera + DebugCameraFlag = !DebugCameraFlag; + } + else if( Global.ctrlState ) { + // ctrl + f7 toggles static daylight + simulation::Environment.toggle_daylight(); + break; + } + else if( Global.shiftState ) { + // shift + f7 is currently unused + } + else { + // f7: wireframe toggle + // TODO: pass this to renderer instead of making direct calls + Global.bWireFrame = !Global.bWireFrame; + if( true == Global.bWireFrame ) { + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + } + else { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + } + } + break; + } + case GLFW_KEY_F11: { + // editor mode + if( ( false == Global.ctrlState ) + && ( false == Global.shiftState ) ) { + Application.push_mode( eu07_application::mode::editor ); + } + break; + } + case GLFW_KEY_F12: { + // quick debug mode toggle + if( Global.ctrlState + && Global.shiftState ) { + DebugModeFlag = !DebugModeFlag; + } + break; + } + + case GLFW_KEY_LEFT_BRACKET: + case GLFW_KEY_RIGHT_BRACKET: + case GLFW_KEY_TAB: { + // consist movement in debug mode + if( ( true == DebugModeFlag ) + && ( false == Global.shiftState ) + && ( true == Global.ctrlState ) + && ( simulation::Train != nullptr ) + && ( simulation::Train->Dynamic()->Controller == Humandriver ) ) { + + if( DebugModeFlag ) { + // przesuwanie składu o 100m + auto *vehicle { simulation::Train->Dynamic() }; + TDynamicObject *d = vehicle; + if( cKey == GLFW_KEY_LEFT_BRACKET ) { + while( d ) { + d->Move( 100.0 * d->DirectionGet() ); + d = d->Next(); // pozostałe też + } + d = vehicle->Prev(); + while( d ) { + d->Move( 100.0 * d->DirectionGet() ); + d = d->Prev(); // w drugą stronę też + } + } + else if( cKey == GLFW_KEY_RIGHT_BRACKET ) { + while( d ) { + d->Move( -100.0 * d->DirectionGet() ); + d = d->Next(); // pozostałe też + } + d = vehicle->Prev(); + while( d ) { + d->Move( -100.0 * d->DirectionGet() ); + d = d->Prev(); // w drugą stronę też + } + } + else if( cKey == GLFW_KEY_TAB ) { + while( d ) { + d->MoverParameters->V += d->DirectionGet()*2.78; + d = d->Next(); // pozostałe też + } + d = vehicle->Prev(); + while( d ) { + d->MoverParameters->V += d->DirectionGet()*2.78; + d = d->Prev(); // w drugą stronę też + } + } + } + } + break; + } + + default: { + break; } } + + return; // nie są przekazywane do pojazdu wcale } // places camera outside the controlled vehicle, or nearest if nothing is under control diff --git a/driveruilayer.cpp b/driveruilayer.cpp index a346adef..6fd4be74 100644 --- a/driveruilayer.cpp +++ b/driveruilayer.cpp @@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/. #include "driveruilayer.h" #include "globals.h" +#include "application.h" #include "translation.h" #include "simulation.h" #include "train.h" @@ -42,7 +43,26 @@ bool driver_ui::on_key( int const Key, int const Action ) { // TODO: pass the input first through an active ui element if there's any // if the ui element shows no interest or we don't have one, try to interpret the input yourself: - // shared conditions + + if( Key == GLFW_KEY_ESCAPE ) { + // toggle pause + if( Action != GLFW_PRESS ) { return true; } // recognized, but ignored + + if( Global.iPause & 1 ) { + // jeśli pauza startowa + // odpauzowanie, gdy po wczytaniu miało nie startować + Global.iPause ^= 1; + } + else if( ( Global.iMultiplayer & 2 ) == 0 ) { + // w multiplayerze pauza nie ma sensu + Global.iPause ^= 2; // zmiana stanu zapauzowania + } + return true; + } + + // if the pause is on ignore block other input + if( m_paused ) { return true; } + switch( Key ) { case GLFW_KEY_F1: @@ -108,10 +128,32 @@ driver_ui::on_key( int const Key, int const Action ) { return false; } +// potentially processes provided mouse movement. returns: true if the input was processed, false otherwise +bool +driver_ui::on_cursor_pos( double const Horizontal, double const Vertical ) { + // intercept mouse movement when the pause window is on + return m_paused; +} + +// potentially processes provided mouse button. returns: true if the input was processed, false otherwise +bool +driver_ui::on_mouse_button( int const Button, int const Action ) { + // intercept mouse movement when the pause window is on + return m_paused; +} + // updates state of UI elements void driver_ui::update() { + auto const pausemask { 1 | 2 }; + auto ispaused { ( Global.iPause & pausemask ) != 0 }; + if( ( ispaused != m_paused ) + && ( false == Global.ControlPicking ) ) { + set_cursor( ispaused ); + } + m_paused = ispaused; + set_tooltip( "" ); auto const *train { simulation::Train }; @@ -138,12 +180,24 @@ driver_ui::update() { ui_layer::update(); } +void +driver_ui::set_cursor( bool const Visible ) { + + if( Visible ) { + Application.set_cursor( GLFW_CURSOR_NORMAL ); + Application.set_cursor_pos( Global.iWindowWidth / 2, Global.iWindowHeight / 2 ); + } + else { + Application.set_cursor( GLFW_CURSOR_DISABLED ); + Application.set_cursor_pos( 0, 0 ); + } +} + // render() subclass details void driver_ui::render_() { - auto const pausemask { 1 | 2 }; - if( ( Global.iPause & pausemask ) != 0 ) { + if( m_paused ) { // pause/quit modal auto const popupheader { locale::strings[ locale::string::driver_pause_header ].c_str() }; ImGui::OpenPopup( popupheader ); @@ -151,6 +205,7 @@ driver_ui::render_() { auto const popupwidth{ locale::strings[ locale::string::driver_pause_header ].size() * 7 }; if( ImGui::Button( locale::strings[ locale::string::driver_pause_resume ].c_str(), ImVec2( popupwidth, 0 ) ) ) { ImGui::CloseCurrentPopup(); + auto const pausemask { 1 | 2 }; Global.iPause &= ~pausemask; } if( ImGui::Button( locale::strings[ locale::string::driver_pause_quit ].c_str(), ImVec2( popupwidth, 0 ) ) ) { diff --git a/driveruilayer.h b/driveruilayer.h index 3ef0c638..28a6d94b 100644 --- a/driveruilayer.h +++ b/driveruilayer.h @@ -21,12 +21,21 @@ public: // potentially processes provided input key. returns: true if the input was processed, false otherwise bool on_key( int const Key, int const Action ) override; + // potentially processes provided mouse movement. returns: true if the input was processed, false otherwise + bool + on_cursor_pos( double const Horizontal, double const Vertical ) override; + // potentially processes provided mouse button. returns: true if the input was processed, false otherwise + bool + on_mouse_button( int const Button, int const Action ) override; // updates state of UI elements void update() override; private: // methods + // sets visibility of the cursor + void + set_cursor( bool const Visible ); // render() subclass details void render_() override; @@ -35,5 +44,6 @@ private: timetable_panel m_timetablepanel { "Timetable", false }; debug_panel m_debugpanel { "Debug Data", false }; transcripts_panel m_transcriptspanel { "Transcripts", true }; // voice transcripts + bool m_paused { false }; }; diff --git a/uilayer.cpp b/uilayer.cpp index f4e32e98..b373afdb 100644 --- a/uilayer.cpp +++ b/uilayer.cpp @@ -129,6 +129,18 @@ ui_layer::on_key( int const Key, int const Action ) { return false; } +bool +ui_layer::on_cursor_pos( double const Horizontal, double const Vertical ) { + + return false; +} + +bool +ui_layer::on_mouse_button( int const Button, int const Action ) { + + return false; +} + void ui_layer::update() { diff --git a/uilayer.h b/uilayer.h index d22461b8..4bed2010 100644 --- a/uilayer.h +++ b/uilayer.h @@ -69,6 +69,14 @@ public: virtual bool on_key( int const Key, int const Action ); + // potentially processes provided mouse movement. returns: true if the input was processed, false otherwise + virtual + bool + on_cursor_pos( double const Horizontal, double const Vertical ); + // potentially processes provided mouse button. returns: true if the input was processed, false otherwise + virtual + bool + on_mouse_button( int const Button, int const Action ); // updates state of UI elements virtual void