diff --git a/Globals.cpp b/Globals.cpp index 156af648..82e85400 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -392,6 +392,10 @@ global_settings::ConfigParse(cParser &Parser) { Parser.getTokens(); Parser >> render_cab; } + else if (token == "skipmainrender") { + Parser.getTokens(); + Parser >> skip_main_render; + } else if( token == "createswitchtrackbeds" ) { // podwójna jasność ambient Parser.getTokens(); @@ -742,6 +746,14 @@ global_settings::ConfigParse(cParser &Parser) { Parser.getTokens(1); Parser >> gui_defaultwindows; } + else if (token == "gui.showtranscripts") { + Parser.getTokens(1); + Parser >> gui_showtranscripts; + } + else if (token == "gui.trainingdefault") { + Parser.getTokens(1); + Parser >> gui_trainingdefault; + } else if (token == "gfx.framebuffer.width") { Parser.getTokens(1, false); diff --git a/Globals.h b/Globals.h index 600e5aec..a2212820 100644 --- a/Globals.h +++ b/Globals.h @@ -188,8 +188,11 @@ struct global_settings { bool dds_upper_origin = false; bool captureonstart = true; bool render_cab = true; + bool skip_main_render = false; bool crash_damage = true; bool gui_defaultwindows = true; + bool gui_showtranscripts = true; + bool gui_trainingdefault = false; #ifdef USE_EXTCAM_CAMERA std::string extcam_cmd; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 4490a2f9..6fc9d16e 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -171,8 +171,7 @@ bool TSecuritySystem::is_cabsignal_beeping() const { } bool TSecuritySystem::is_braking() const { - return alert_timer > SoundSignalDelay + EmergencyBrakeDelay - && (velocity > AwareMinSpeed || pressed); + return alert_timer > SoundSignalDelay + EmergencyBrakeDelay; } bool TSecuritySystem::radiostop_available() const { @@ -3970,6 +3969,10 @@ void TMoverParameters::UpdatePipePressure(double dt) || ( true == AlarmChainFlag ) || SecuritySystem.is_braking() ) { dpMainValve = dpMainValve + PF( 0, PipePress, 0.15 ) * dt; + + if (EIMCtrlType > 0) { + eimic = 0; + } } // 0.2*Spg diff --git a/Segment.cpp b/Segment.cpp index 197ae304..5db4fd16 100644 --- a/Segment.cpp +++ b/Segment.cpp @@ -552,10 +552,20 @@ glm::vec3 TSegment::get_nearest_point(const glm::dvec3 &point, float quality) co float min = std::numeric_limits::max(); for (x = step; x <= 1.0f; x += step) { - glm::vec3 p = FastGetPoint(x); - float dist2 = glm::distance2(p, (glm::vec3)point); + glm::vec3 p1 = FastGetPoint(x); + glm::vec3 p2 = FastGetPoint(glm::min(1.0f, x + step)); + + if (p1 != p2) { + float l2 = glm::distance2(p1, p2); + float t = glm::max(0.0f, glm::min(1.0f, glm::dot((glm::vec3)point - p1, p2 - p1) / l2)); + glm::vec3 proj = p1 + t * (p2 - p1); + p1 = proj; + } + + float dist2 = glm::distance2(p1, (glm::vec3)point); + if (dist2 < min) { - nearest = p; + nearest = p1; min = dist2; } } diff --git a/driveruilayer.cpp b/driveruilayer.cpp index 306956cb..5cce786e 100644 --- a/driveruilayer.cpp +++ b/driveruilayer.cpp @@ -26,7 +26,8 @@ driver_ui::driver_ui() { add_external_panel( &m_scenariopanel ); add_external_panel( &m_timetablepanel ); add_external_panel( &m_debugpanel ); - add_external_panel( &m_transcriptspanel ); + if (Global.gui_showtranscripts) + add_external_panel( &m_transcriptspanel ); add_external_panel( &m_trainingcardpanel ); add_external_panel( &m_vehiclelist ); @@ -55,6 +56,12 @@ driver_ui::driver_ui() { m_aidpanel.is_open = true; m_scenariopanel.is_open = true; } + + if (Global.gui_trainingdefault) { + m_mappanel.is_open = true; + m_trainingcardpanel.is_open = true; + m_vehiclelist.is_open = true; + } } void driver_ui::render_menu_contents() { @@ -235,6 +242,7 @@ driver_ui::render_() { const std::string *rec_name = m_trainingcardpanel.is_recording(); if (rec_name && m_cameraviewpanel.set_state(true)) { m_cameraviewpanel.rec_name = *rec_name; + m_cameraviewpanel.is_open = true; } else if (!rec_name) m_cameraviewpanel.set_state(false); diff --git a/driveruipanels.cpp b/driveruipanels.cpp index 77fecaf8..7f229646 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -27,6 +27,7 @@ http://mozilla.org/MPL/2.0/. #include "renderer.h" #include "utilities.h" #include "Logs.h" +#include "widgets/vehicleparams.h" void drivingaid_panel::update() { diff --git a/renderer.cpp b/renderer.cpp index f15cee6a..eba262b5 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -665,10 +665,10 @@ void opengl_renderer::Render_pass(viewport_config &vp, rendermode const Mode) gl::buffer::unbind(); m_current_viewport = &vp; - if (!simulation::is_ready) + if (!simulation::is_ready || Global.skip_main_render) { gl::framebuffer::unbind(); - glClearColor(0.0f, 0.5f, 0.0f, 1.0f); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (vp.main) Application.render_ui(); @@ -3733,6 +3733,10 @@ void opengl_renderer::Update_Pick_Node() void opengl_renderer::pick_control(std::function callback) { + if (!Global.render_cab) { + callback(nullptr, glm::vec2()); + return; + } m_control_pick_requests.push_back(callback); } @@ -3975,7 +3979,7 @@ void opengl_renderer::Update_Lights(light_array &Lights) l->linear = headlight_config.falloff_linear / 10.0f; l->quadratic = headlight_config.falloff_quadratic / 100.0f; l->ambient = headlight_config.ambient; - l->intensity = headlight_config.intensity; + l->intensity = headlight_config.intensity * scenelight.intensity; light_i++; ++renderlight; diff --git a/uart.cpp b/uart.cpp index 1b18df0b..3f3c88d2 100644 --- a/uart.cpp +++ b/uart.cpp @@ -12,11 +12,31 @@ uart_input::uart_input() { conf = Global.uart_conf; - if (sp_get_port_by_name(conf.port.c_str(), &port) != SP_OK) - throw std::runtime_error("uart: cannot find specified port"); + if (!setup_port()) + throw std::runtime_error("uart: cannot open port"); - if (sp_open(port, (sp_mode)(SP_MODE_READ | SP_MODE_WRITE)) != SP_OK) - throw std::runtime_error("uart: cannot open port"); + old_packet.fill(0); + last_update = std::chrono::high_resolution_clock::now(); +} + +bool uart_input::setup_port() +{ + if (port) { + sp_close(port); + sp_free_port(port); + port = nullptr; + } + + if (sp_get_port_by_name(conf.port.c_str(), &port) != SP_OK) { + ErrorLog("uart: cannot find specified port"); + return false; + } + + if (sp_open(port, (sp_mode)(SP_MODE_READ | SP_MODE_WRITE)) != SP_OK) { + ErrorLog("uart: cannot open port"); + port = nullptr; + return false; + } sp_port_config *config; @@ -26,21 +46,33 @@ uart_input::uart_input() sp_set_config_bits(config, 8) != SP_OK || sp_set_config_stopbits(config, 1) != SP_OK || sp_set_config_parity(config, SP_PARITY_NONE) != SP_OK || - sp_set_config(port, config) != SP_OK) - throw std::runtime_error("uart: cannot set config"); + sp_set_config(port, config) != SP_OK) { + ErrorLog("uart: cannot set config"); + port = nullptr; + return false; + } sp_free_config(config); - if (sp_flush(port, SP_BUF_BOTH) != SP_OK) - throw std::runtime_error("uart: cannot flush"); - - old_packet.fill(0); - last_update = std::chrono::high_resolution_clock::now(); + if (sp_flush(port, SP_BUF_BOTH) != SP_OK) { + ErrorLog("uart: cannot flush"); + port = nullptr; + return false; + } + + return true; } uart_input::~uart_input() { - std::array buffer = { 0 }; + if (!port) + return; + + std::array buffer = { 0 }; + buffer[0] = 0xEF; + buffer[1] = 0xEF; + buffer[2] = 0xEF; + buffer[3] = 0xEF; sp_blocking_write(port, (void*)buffer.data(), buffer.size(), 0); sp_drain(port); @@ -131,18 +163,77 @@ void uart_input::poll() return; last_update = now; + if (!port) { + setup_port(); + return; + } + auto const *t =simulation::Train; if (!t) return; sp_return ret; - - if ((ret = sp_input_waiting(port)) >= 16) + + if ((ret = sp_input_waiting(port)) >= 20) { - std::array buffer; // TBD, TODO: replace with vector of configurable size? - ret = sp_blocking_read(port, (void*)buffer.data(), buffer.size(), 0); - if (ret < 0) - throw std::runtime_error("uart: failed to read from port"); + std::array tmp_buffer; // TBD, TODO: replace with vector of configurable size? + ret = sp_blocking_read(port, (void*)tmp_buffer.data(), tmp_buffer.size(), 0); + + if (ret < 0) { + setup_port(); + return; + } + + bool sync; + if (tmp_buffer[0] != 0xEF || tmp_buffer[1] != 0xEF || tmp_buffer[2] != 0xEF || tmp_buffer[3] != 0xEF) { + if (conf.debug) + WriteLog("uart: bad sync"); + sync = false; + } + else { + if (conf.debug) + WriteLog("uart: sync ok"); + sync = true; + } + + if (!sync) { + int sync_cnt = 0; + int sync_fail = 0; + char sc = 0; + while ((ret = sp_blocking_read(port, &sc, 1, 10)) >= 0) { + if (conf.debug) + WriteLog("uart: read byte: " + std::to_string((int)sc)); + if (sc == 0xEF) + sync_cnt++; + else { + sync_cnt = 0; + sync_fail++; + } + if (sync_cnt == 4) { + if (conf.debug) + WriteLog("uart: synced, skipping one packet.."); + ret = sp_blocking_read(port, (void*)tmp_buffer.data(), 16, 500); + if (ret < 0) { + setup_port(); + return; + } + data_pending = false; + break; + } + if (sync_fail >= 60) { + if (conf.debug) + WriteLog("uart: tired of trying"); + break; + } + } + if (ret < 0) { + setup_port(); + } + return; + } + + std::array buffer; + memmove(&buffer[0], &tmp_buffer[4], 16); if (conf.debug) { @@ -230,6 +321,11 @@ void uart_input::poll() old_packet = buffer; } + if (ret < 0) { + setup_port(); + return; + } + if (!data_pending && sp_output_waiting(port) == 0) { // TODO: ugly! move it into structure like input_bits @@ -251,8 +347,10 @@ void uart_input::poll() m_trainstatecab = trainstate.cab - 1; } - std::array buffer { - //byte 0-1 + std::array buffer { + //preamble + 0xEF, 0xEF, 0xEF, 0xEF, + //byte 0-1 (counting without preamble) SPLIT_INT16(tacho), //byte 2 (uint8_t)( @@ -323,8 +421,10 @@ void uart_input::poll() } ret = sp_blocking_write(port, (void*)buffer.data(), buffer.size(), 0); - if (ret != buffer.size()) - throw std::runtime_error("uart: failed to write to port"); + if (ret < 0) { + setup_port(); + return; + } data_pending = true; } diff --git a/uart.h b/uart.h index 73a65300..3d864740 100644 --- a/uart.h +++ b/uart.h @@ -60,6 +60,8 @@ private: using input_pin_t = std::tuple; using inputpin_sequence = std::vector; + + bool setup_port(); // members sp_port *port = nullptr; diff --git a/widgets/vehiclelist.cpp b/widgets/vehiclelist.cpp index 163b8171..d38ae2f5 100644 --- a/widgets/vehiclelist.cpp +++ b/widgets/vehiclelist.cpp @@ -7,11 +7,25 @@ ui::vehiclelist_panel::vehiclelist_panel(ui_layer &parent) : ui_panel(STR_C("Vehicle list"), false), m_parent(parent) { - } void ui::vehiclelist_panel::render_contents() { + if (m_first_show && Global.gui_trainingdefault) { + for (TDynamicObject *vehicle : simulation::Vehicles.sequence()) + { + if (!vehicle->Mechanik || vehicle->name() != ToLower(Global.local_start_vehicle)) + continue; + + ui_panel *panel = new vehicleparams_panel(vehicle->name()); + m_parent.add_owned_panel(panel); + } + + m_first_show = false; + is_open = false; + return; + } + for (TDynamicObject *vehicle : simulation::Vehicles.sequence()) { if (!vehicle->Mechanik) diff --git a/widgets/vehiclelist.h b/widgets/vehiclelist.h index 0e77c963..fe42a207 100644 --- a/widgets/vehiclelist.h +++ b/widgets/vehiclelist.h @@ -5,6 +5,7 @@ namespace ui class vehiclelist_panel : public ui_panel { ui_layer &m_parent; + bool m_first_show = true; public: vehiclelist_panel(ui_layer &parent); diff --git a/widgets/vehicleparams.h b/widgets/vehicleparams.h index 467fe29e..732ebe32 100644 --- a/widgets/vehicleparams.h +++ b/widgets/vehicleparams.h @@ -1,3 +1,5 @@ +#pragma once + #include "uilayer.h" #include "translation.h" #include "command.h"