16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 22:09:19 +02:00

serial port input device configuration, additional control commands and minor control logic tweaks

This commit is contained in:
tmj-fstate
2018-02-10 19:53:21 +01:00
parent e9c4714780
commit 0c880f3d4e
16 changed files with 1437 additions and 897 deletions

View File

@@ -3590,7 +3590,7 @@ void TDynamicObject::RenderSounds() {
0.0, 1.0 );
rsBrake
.pitch( rsBrake.m_frequencyoffset + MoverParameters->Vel * rsBrake.m_frequencyfactor )
.gain( rsBrake.m_amplitudeoffset + std::sqrt( brakeforceratio * interpolate( 0.4, 1.0, ( MoverParameters->Vel / ( 1 + MoverParameters->Vmax ) ) ) ) )
.gain( rsBrake.m_amplitudeoffset + std::sqrt( brakeforceratio * interpolate( 0.4, 1.0, ( MoverParameters->Vel / ( 1 + MoverParameters->Vmax ) ) ) ) * rsBrake.m_amplitudefactor )
.play( sound_flags::exclusive | sound_flags::looping );
}
else {

View File

@@ -416,6 +416,7 @@ int main(int argc, char *argv[])
input::Gamepad.init();
if( true == Global.uart_conf.enable ) {
input::uart = std::make_unique<uart_input>();
input::uart->init();
}
Global.pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów

View File

@@ -235,6 +235,11 @@ double TGauge::GetValue() const {
return ( fValue - fOffset ) / fScale;
}
double TGauge::GetDesiredValue() const {
// we feed value in range 0-1 so we should be getting it reported in the same range
return ( fDesiredValue - fOffset ) / fScale;
}
void TGauge::Update() {
if( fValue != fDesiredValue ) {

View File

@@ -38,6 +38,7 @@ public:
void UpdateValue( double fNewDesired, sound_source &Fallbacksound );
void PutValue(double fNewDesired);
double GetValue() const;
double GetDesiredValue() const;
void Update();
void AssignFloat(float *fValue);
void AssignDouble(double *dValue);

View File

@@ -1669,9 +1669,8 @@ bool TMoverParameters::IncMainCtrl(int CtrlSpeed)
// all work is done in the loop header
;
}
// OK:=true ; {takie chamskie, potem poprawie} <-Ra: kto mia³ to
// poprawiæ i po co?
if( ActiveDir == -1 ) {
// OK:=true ; {takie chamskie, potem poprawie} <-Ra: kto mia³ to poprawiæ i po co?
if( ActiveDir < 0 ) {
while( ( RList[ MainCtrlPos ].Bn > 1 )
&& IncMainCtrl( 1 ) ) {
--MainCtrlPos;
@@ -1702,7 +1701,7 @@ bool TMoverParameters::IncMainCtrl(int CtrlSpeed)
}
}
}
if( ActiveDir == -1 ) {
if( ActiveDir < 0 ) {
if( ( TrainType != dt_PseudoDiesel )
&& ( RList[ MainCtrlPos ].Bn > 1 ) ) {
// blokada wejścia na równoległą podczas jazdy do tyłu
@@ -5206,9 +5205,12 @@ bool TMoverParameters::AutoRelayCheck(void)
// Ra 2014-06: dla SN61 nie działa prawidłowo
// rozlaczanie stycznikow liniowych
if ((!Mains) || (FuseFlag) || (MainCtrlPos == 0) ||
((BrakePress > 2.1) && (TrainType != dt_EZT)) ||
(ActiveDir == 0)) // hunter-111211: wylacznik cisnieniowy
if( ( false == Mains )
|| ( true == FuseFlag )
|| ( true == StLinSwitchOff )
|| ( MainCtrlPos == 0 )
|| ( ( TrainType != dt_EZT ) && ( BrakePress > 2.1 ) )
|| ( ActiveDir == 0 ) ) // hunter-111211: wylacznik cisnieniowy
{
StLinFlag = false; // yBARC - rozlaczenie stycznikow liniowych
OK = false;

1869
Train.cpp

File diff suppressed because it is too large Load Diff

38
Train.h
View File

@@ -133,6 +133,10 @@ class TTrain
TDynamicObject *find_nearest_consist_vehicle() const;
// moves train brake lever to specified position, potentially emits switch sound if conditions are met
void set_train_brake( double const Position );
// sets specified brake acting speed for specified vehicle, potentially updating state of cab controls to match
void set_train_brake_speed( TDynamicObject *Vehicle, int const Speed );
// sets the motor connector button in paired unit to specified state
void set_paired_open_motor_connectors_button( bool const State );
// update function subroutines
void update_sounds( double const Deltatime );
@@ -181,6 +185,9 @@ class TTrain
static void OnCommand_epbrakecontroltoggle( TTrain *Train, command_data const &Command );
static void OnCommand_brakeactingspeedincrease( TTrain *Train, command_data const &Command );
static void OnCommand_brakeactingspeeddecrease( TTrain *Train, command_data const &Command );
static void OnCommand_brakeactingspeedsetcargo( TTrain *Train, command_data const &Command );
static void OnCommand_brakeactingspeedsetpassenger( TTrain *Train, command_data const &Command );
static void OnCommand_brakeactingspeedsetrapid( TTrain *Train, command_data const &Command );
static void OnCommand_brakeloadcompensationincrease( TTrain *Train, command_data const &Command );
static void OnCommand_brakeloadcompensationdecrease( TTrain *Train, command_data const &Command );
static void OnCommand_mubrakingindicatortoggle( TTrain *Train, command_data const &Command );
@@ -188,27 +195,50 @@ class TTrain
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_batteryenable( TTrain *Train, command_data const &Command );
static void OnCommand_batterydisable( 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_pantographraisefront( TTrain *Train, command_data const &Command );
static void OnCommand_pantographraiserear( TTrain *Train, command_data const &Command );
static void OnCommand_pantographlowerfront( TTrain *Train, command_data const &Command );
static void OnCommand_pantographlowerrear( 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_linebreakeropen( TTrain *Train, command_data const &Command );
static void OnCommand_linebreakerclose( TTrain *Train, command_data const &Command );
static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command );
static void OnCommand_converterenable( TTrain *Train, command_data const &Command );
static void OnCommand_converterdisable( TTrain *Train, command_data const &Command );
static void OnCommand_convertertogglelocal( 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_compressorenable( TTrain *Train, command_data const &Command );
static void OnCommand_compressordisable( TTrain *Train, command_data const &Command );
static void OnCommand_compressortogglelocal( TTrain *Train, command_data const &Command );
static void OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command );
static void OnCommand_motorconnectorsclose( 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_motoroverloadrelaythresholdsetlow( TTrain *Train, command_data const &Command );
static void OnCommand_motoroverloadrelaythresholdsethigh( 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_heatingenable( TTrain *Train, command_data const &Command );
static void OnCommand_heatingdisable( TTrain *Train, command_data const &Command );
static void OnCommand_lightspresetactivatenext( TTrain *Train, command_data const &Command );
static void OnCommand_lightspresetactivateprevious( TTrain *Train, command_data const &Command );
static void OnCommand_headlighttoggleleft( TTrain *Train, command_data const &Command );
static void OnCommand_headlightenableleft( TTrain *Train, command_data const &Command );
static void OnCommand_headlightdisableleft( TTrain *Train, command_data const &Command );
static void OnCommand_headlighttoggleright( TTrain *Train, command_data const &Command );
static void OnCommand_headlightenableright( TTrain *Train, command_data const &Command );
static void OnCommand_headlightdisableright( TTrain *Train, command_data const &Command );
static void OnCommand_headlighttoggleupper( TTrain *Train, command_data const &Command );
static void OnCommand_headlightenableupper( TTrain *Train, command_data const &Command );
static void OnCommand_headlightdisableupper( 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 );
@@ -219,9 +249,17 @@ class TTrain
static void OnCommand_redmarkerstoggle( TTrain *Train, command_data const &Command );
static void OnCommand_endsignalstoggle( TTrain *Train, command_data const &Command );
static void OnCommand_headlightsdimtoggle( TTrain *Train, command_data const &Command );
static void OnCommand_headlightsdimenable( TTrain *Train, command_data const &Command );
static void OnCommand_headlightsdimdisable( TTrain *Train, command_data const &Command );
static void OnCommand_interiorlighttoggle( TTrain *Train, command_data const &Command );
static void OnCommand_interiorlightenable( TTrain *Train, command_data const &Command );
static void OnCommand_interiorlightdisable( TTrain *Train, command_data const &Command );
static void OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const &Command );
static void OnCommand_interiorlightdimenable( TTrain *Train, command_data const &Command );
static void OnCommand_interiorlightdimdisable( TTrain *Train, command_data const &Command );
static void OnCommand_instrumentlighttoggle( TTrain *Train, command_data const &Command );
static void OnCommand_instrumentlightenable( TTrain *Train, command_data const &Command );
static void OnCommand_instrumentlightdisable( 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 );

View File

@@ -2163,7 +2163,7 @@ world_environment::update() {
else {
// regular situation with sun as the key light
Global.SunAngle = m_sun.getAngle();
Global.DayLight.position = m_sun.getPosition();
Global.DayLight.position = m_sun.getDirection();
Global.DayLight.direction = -1.0f * m_sun.getDirection();
keylightintensity = sunlightlevel;
// include 'golden hour' effect in twilight lighting

View File

@@ -61,17 +61,28 @@ commanddescription_sequence Commands_descriptions = {
{ "reverserincrease", command_target::vehicle },
{ "reverserdecrease", command_target::vehicle },
{ "linebreakertoggle", command_target::vehicle },
{ "linebreakeropen", command_target::vehicle },
{ "linebreakerclose", command_target::vehicle },
{ "convertertoggle", command_target::vehicle },
{ "converterenable", command_target::vehicle },
{ "converterdisable", command_target::vehicle },
{ "convertertogglelocal", command_target::vehicle },
{ "converteroverloadrelayreset", command_target::vehicle },
{ "compressortoggle", command_target::vehicle },
{ "compressorenable", command_target::vehicle },
{ "compressordisable", command_target::vehicle },
{ "compressortogglelocal", command_target::vehicle },
{ "motoroverloadrelaythresholdtoggle", command_target::vehicle },
{ "motoroverloadrelaythresholdsetlow", command_target::vehicle },
{ "motoroverloadrelaythresholdsethigh", command_target::vehicle },
{ "motoroverloadrelayreset", command_target::vehicle },
{ "notchingrelaytoggle", command_target::vehicle },
{ "epbrakecontroltoggle", command_target::vehicle },
{ "brakeactingspeedincrease", command_target::vehicle },
{ "brakeactingspeeddecrease", command_target::vehicle },
{ "brakeactingspeedsetcargo", command_target::vehicle },
{ "brakeactingspeedsetpassenger", command_target::vehicle },
{ "brakeactingspeedsetrapid", command_target::vehicle },
{ "brakeloadcompensationincrease", command_target::vehicle },
{ "brakeloadcompensationdecrease", command_target::vehicle },
{ "mubrakingindicatortoggle", command_target::vehicle },
@@ -109,13 +120,25 @@ commanddescription_sequence Commands_descriptions = {
{ "pantographcompressoractivate", command_target::vehicle },
{ "pantographtogglefront", command_target::vehicle },
{ "pantographtogglerear", command_target::vehicle },
{ "pantographraisefront", command_target::vehicle },
{ "pantographraiserear", command_target::vehicle },
{ "pantographlowerfront", command_target::vehicle },
{ "pantographlowerrear", command_target::vehicle },
{ "pantographlowerall", command_target::vehicle },
{ "heatingtoggle", command_target::vehicle },
{ "heatingenable", command_target::vehicle },
{ "heatingdisable", command_target::vehicle },
{ "lightspresetactivatenext", command_target::vehicle },
{ "lightspresetactivateprevious", command_target::vehicle },
{ "headlighttoggleleft", command_target::vehicle },
{ "headlightenableleft", command_target::vehicle },
{ "headlightdisableleft", command_target::vehicle },
{ "headlighttoggleright", command_target::vehicle },
{ "headlightenableright", command_target::vehicle },
{ "headlightdisableright", command_target::vehicle },
{ "headlighttoggleupper", command_target::vehicle },
{ "headlightenableupper", command_target::vehicle },
{ "headlightdisableupper", command_target::vehicle },
{ "redmarkertoggleleft", command_target::vehicle },
{ "redmarkertoggleright", command_target::vehicle },
{ "headlighttogglerearleft", command_target::vehicle },
@@ -126,11 +149,20 @@ commanddescription_sequence Commands_descriptions = {
{ "redmarkerstoggle", command_target::vehicle },
{ "endsignalstoggle", command_target::vehicle },
{ "headlightsdimtoggle", command_target::vehicle },
{ "headlightsdimenable", command_target::vehicle },
{ "headlightsdimdisable", command_target::vehicle },
{ "motorconnectorsopen", command_target::vehicle },
{ "motorconnectorsclose", command_target::vehicle },
{ "motordisconnect", command_target::vehicle },
{ "interiorlighttoggle", command_target::vehicle },
{ "interiorlightenable", command_target::vehicle },
{ "interiorlightdisable", command_target::vehicle },
{ "interiorlightdimtoggle", command_target::vehicle },
{ "interiorlightdimenable", command_target::vehicle },
{ "interiorlightdimdisable", command_target::vehicle },
{ "instrumentlighttoggle", command_target::vehicle },
{ "instrumentlightenable", command_target::vehicle },
{ "instrumentlightdisable", command_target::vehicle },
{ "generictoggle0", command_target::vehicle },
{ "generictoggle1", command_target::vehicle },
{ "generictoggle2", command_target::vehicle },
@@ -141,7 +173,9 @@ commanddescription_sequence Commands_descriptions = {
{ "generictoggle7", command_target::vehicle },
{ "generictoggle8", command_target::vehicle },
{ "generictoggle9", command_target::vehicle },
{ "batterytoggle", command_target::vehicle }
{ "batterytoggle", command_target::vehicle },
{ "batteryenable", command_target::vehicle },
{ "batterydisable", command_target::vehicle }
};
}
@@ -177,7 +211,7 @@ command_queue::pop( command_data &Command, std::size_t const Recipient ) {
}
void
command_relay::post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2, int const Action, command_hint const Hint, std::uint16_t const Recipient ) const {
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 &command = simulation::Commands_descriptions[ static_cast<std::size_t>( Command ) ];
if( ( command.target == command_target::vehicle )
@@ -194,7 +228,6 @@ command_relay::post( user_command const Command, std::uint64_t const Param1, std
Action,
Param1,
Param2,
Hint,
Timer::GetDeltaTime() },
static_cast<std::size_t>( command.target ) | Recipient );
/*

View File

@@ -55,17 +55,28 @@ enum class user_command {
reverserincrease,
reverserdecrease,
linebreakertoggle,
linebreakeropen,
linebreakerclose,
convertertoggle,
converterenable,
converterdisable,
convertertogglelocal,
converteroverloadrelayreset,
compressortoggle,
compressorenable,
compressordisable,
compressortogglelocal,
motoroverloadrelaythresholdtoggle,
motoroverloadrelaythresholdsetlow,
motoroverloadrelaythresholdsethigh,
motoroverloadrelayreset,
notchingrelaytoggle,
epbrakecontroltoggle,
brakeactingspeedincrease,
brakeactingspeeddecrease,
brakeactingspeedsetcargo,
brakeactingspeedsetpassenger,
brakeactingspeedsetrapid,
brakeloadcompensationincrease,
brakeloadcompensationdecrease,
mubrakingindicatortoggle,
@@ -102,13 +113,25 @@ enum class user_command {
pantographcompressoractivate,
pantographtogglefront,
pantographtogglerear,
pantographraisefront,
pantographraiserear,
pantographlowerfront,
pantographlowerrear,
pantographlowerall,
heatingtoggle,
heatingenable,
heatingdisable,
lightspresetactivatenext,
lightspresetactivateprevious,
headlighttoggleleft,
headlightenableleft,
headlightdisableleft,
headlighttoggleright,
headlightenableright,
headlightdisableright,
headlighttoggleupper,
headlightenableupper,
headlightdisableupper,
redmarkertoggleleft,
redmarkertoggleright,
headlighttogglerearleft,
@@ -119,11 +142,20 @@ enum class user_command {
redmarkerstoggle,
endsignalstoggle,
headlightsdimtoggle,
headlightsdimenable,
headlightsdimdisable,
motorconnectorsopen,
motorconnectorsclose,
motordisconnect,
interiorlighttoggle,
interiorlightenable,
interiorlightdisable,
interiorlightdimtoggle,
interiorlightdimenable,
interiorlightdimdisable,
instrumentlighttoggle,
instrumentlightenable,
instrumentlightdisable,
generictoggle0,
generictoggle1,
generictoggle2,
@@ -135,16 +167,12 @@ enum class user_command {
generictoggle8,
generictoggle9,
batterytoggle,
batteryenable,
batterydisable,
none = -1
};
enum class command_hint {
off,
on,
none = -1
};
enum class command_target {
userinterface,
@@ -173,7 +201,6 @@ struct command_data {
int action; // press, repeat or release
std::uint64_t param1;
std::uint64_t param2;
command_hint hint;
double time_delta;
};
@@ -224,7 +251,7 @@ public:
// 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, command_hint const Hint, std::uint16_t const Recipient ) const;
int const Action, std::uint16_t const Recipient ) const;
private:
// types
// members

View File

@@ -201,7 +201,6 @@ gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, g
reinterpret_cast<std::uint64_t const &>( turnx ),
reinterpret_cast<std::uint64_t const &>( turny ),
GLFW_PRESS,
command_hint::none,
// 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 );
@@ -219,7 +218,6 @@ gamepad_input::process_axes( glm::vec2 Leftstick, glm::vec2 const &Rightstick, g
reinterpret_cast<std::uint64_t const &>( movex ),
reinterpret_cast<std::uint64_t const &>( movez ),
GLFW_PRESS,
command_hint::none,
0 );
}
}
@@ -249,7 +247,6 @@ gamepad_input::process_mode( float const Value, std::uint16_t const Recipient )
lookup.second,
0, 0,
GLFW_RELEASE,
command_hint::none,
Recipient );
m_modeaccumulator = 0.0f;
}
@@ -263,7 +260,6 @@ gamepad_input::process_mode( float const Value, std::uint16_t const Recipient )
lookup.first,
0, 0,
GLFW_PRESS,
command_hint::none,
Recipient );
m_modeaccumulator -= 1.0f;
}
@@ -275,7 +271,6 @@ gamepad_input::process_mode( float const Value, std::uint16_t const Recipient )
lookup.first,
0, 0,
GLFW_RELEASE,
command_hint::none,
Recipient );
m_modeaccumulator = 0.0f;
}
@@ -289,7 +284,6 @@ gamepad_input::process_mode( float const Value, std::uint16_t const Recipient )
lookup.first,
0, 0,
GLFW_RELEASE,
command_hint::none,
Recipient );
m_modeaccumulator = 0.0f;
}
@@ -303,7 +297,6 @@ gamepad_input::process_mode( float const Value, std::uint16_t const Recipient )
lookup.second,
0, 0,
GLFW_PRESS,
command_hint::none,
Recipient );
m_modeaccumulator += 1.0f;
}
@@ -315,7 +308,6 @@ gamepad_input::process_mode( float const Value, std::uint16_t const Recipient )
lookup.second,
0, 0,
GLFW_RELEASE,
command_hint::none,
Recipient );
m_modeaccumulator = 0.0f;
}

View File

@@ -19,6 +19,11 @@ extern TWorld World;
bool
keyboard_input::recall_bindings() {
cParser bindingparser( "eu07_input-keyboard.ini", cParser::buffer_FILE );
if( false == bindingparser.ok() ) {
return false;
}
// build helper translation tables
std::unordered_map<std::string, user_command> nametocommandmap;
std::size_t commandid = 0;
@@ -51,11 +56,7 @@ keyboard_input::recall_bindings() {
{ "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;
}
// NOTE: to simplify things we expect one entry per line, and whole entry in one line
while( true == bindingparser.getTokens( 1, true, "\n" ) ) {
std::string bindingentry;
@@ -80,6 +81,7 @@ keyboard_input::recall_bindings() {
if( bindingkeyname == "shift" ) { binding |= keymodifier::shift; }
else if( bindingkeyname == "ctrl" ) { binding |= keymodifier::control; }
else if( bindingkeyname == "none" ) { binding = -1; }
else {
// regular key, convert it to glfw key code
auto const keylookup = nametokeymap.find( bindingkeyname );
@@ -158,7 +160,7 @@ keyboard_input::key( int const Key, int const Action ) {
// 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, command_hint::none, 0 );
m_relay.post( lookup->second, 0, 0, Action, 0 );
return true;
}
@@ -249,18 +251,34 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_R },
// linebreakertoggle
{ GLFW_KEY_M },
// linebreakeropen
{ -1 },
// linebreakerclose
{ -1 },
// convertertoggle
{ GLFW_KEY_X },
// converterenable,
{ -1 },
// converterdisable,
{ -1 },
// convertertogglelocal
{ GLFW_KEY_X | keymodifier::shift },
// converteroverloadrelayreset
{ GLFW_KEY_N | keymodifier::control },
// compressortoggle
{ GLFW_KEY_C },
// compressorenable
{ -1 },
// compressordisable
{ -1 },
// compressortoggleloal
{ GLFW_KEY_C | keymodifier::shift },
// motoroverloadrelaythresholdtoggle
{ GLFW_KEY_F },
// motoroverloadrelaythresholdsetlow
{ -1 },
// motoroverloadrelaythresholdsethigh
{ -1 },
// motoroverloadrelayreset
{ GLFW_KEY_N },
// notchingrelaytoggle
@@ -271,6 +289,12 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_B | keymodifier::shift },
// brakeactingspeeddecrease
{ GLFW_KEY_B },
// brakeactingspeedsetcargo
{ -1 },
// brakeactingspeedsetpassenger
{ -1 },
// brakeactingspeedsetrapid
{ -1 },
// brakeloadcompensationincrease
{ GLFW_KEY_H | keymodifier::shift | keymodifier::control },
// brakeloadcompensationdecrease
@@ -323,11 +347,6 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_INSERT },
// carcouplingdisconnect
{ GLFW_KEY_DELETE },
/*
const int k_ProgramQuit = 46;
// const int k_ProgramPause= 47;
const int k_ProgramHelp = 48;
*/
// doortoggleleft
{ GLFW_KEY_COMMA },
// doortoggleright
@@ -344,23 +363,44 @@ const int k_ProgramHelp = 48;
{ GLFW_KEY_P },
// pantographtogglerear
{ GLFW_KEY_O },
// pantographraisefront
{ -1 },
// pantographraiserear
{ -1 },
// pantographlowerfront
{ -1 },
// pantographlowerrear
{ -1 },
// pantographlowerall
{ GLFW_KEY_P | keymodifier::control },
// heatingtoggle
{ GLFW_KEY_H },
/*
// const int k_FreeFlyMode= 59;
*/
// heatingenable
{ -1 },
// heatingdisable
{ -1 },
// lightspresetactivatenext
{ GLFW_KEY_T | keymodifier::shift },
// lightspresetactivateprevious
{ GLFW_KEY_T },
// headlighttoggleleft
{ GLFW_KEY_Y },
// headlightenableleft
{ -1 },
// headlightdisableleft
{ -1 },
// headlighttoggleright
{ GLFW_KEY_I },
// headlightenableright
{ -1 },
// headlightdisableright
{ -1 },
// headlighttoggleupper
{ GLFW_KEY_U },
// headlightenableupper
{ -1 },
// headlightdisableupper
{ -1 },
// redmarkertoggleleft
{ GLFW_KEY_Y | keymodifier::shift },
// redmarkertoggleright
@@ -381,19 +421,34 @@ const int k_ProgramHelp = 48;
{ GLFW_KEY_E },
// headlightsdimtoggle
{ GLFW_KEY_L | keymodifier::control },
// headlightsdimenable
{ -1 },
// headlightsdimdisable
{ -1 },
// motorconnectorsopen
{ GLFW_KEY_L },
// motorconnectorsclose
{ -1 },
// motordisconnect
{ GLFW_KEY_E | keymodifier::control },
// interiorlighttoggle
{ GLFW_KEY_APOSTROPHE },
// interiorlightenable
{ -1 },
// interiorlightdisable
{ -1 },
// interiorlightdimtoggle
{ GLFW_KEY_APOSTROPHE | keymodifier::control },
// interiorlightdimenable
{ -1 },
// interiorlightdimdisable
{ -1 },
// instrumentlighttoggle
{ GLFW_KEY_SEMICOLON },
/*
const int k_Active = 71;
*/
// instrumentlightenable
{ -1 },
// instrumentlightdisable,
{ -1 },
// "generictoggle0"
{ GLFW_KEY_0 },
// "generictoggle1"
@@ -415,10 +470,11 @@ const int k_Active = 71;
// "generictoggle9"
{ GLFW_KEY_9 },
// "batterytoggle"
{ GLFW_KEY_J }
/*
const int k_WalkMode = 73;
*/
{ GLFW_KEY_J },
// batteryenable
{ -1 },
// batterydisable
{ -1 },
};
bind();
@@ -489,7 +545,6 @@ keyboard_input::poll() {
reinterpret_cast<std::uint64_t const &>( movexparam ),
reinterpret_cast<std::uint64_t const &>( movezparam ),
GLFW_PRESS,
command_hint::none,
0 );
}
@@ -512,7 +567,6 @@ keyboard_input::poll() {
reinterpret_cast<std::uint64_t const &>( moveyparam ),
0,
GLFW_PRESS,
command_hint::none,
0 );
}

View File

@@ -42,12 +42,12 @@ mouse_input::move( double Mousex, double Mousey ) {
reinterpret_cast<std::uint64_t const &>( Mousex ),
reinterpret_cast<std::uint64_t const &>( Mousey ),
GLFW_PRESS,
command_hint::none,
// 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 );
}
else {
// control picking mode
if( false == m_pickmodepanning ) {
// even if the view panning isn't active we capture the cursor position in case it does get activated
m_cursorposition.x = Mousex;
@@ -61,7 +61,6 @@ mouse_input::move( double Mousex, double Mousey ) {
reinterpret_cast<std::uint64_t const &>( viewoffset.x ),
reinterpret_cast<std::uint64_t const &>( viewoffset.y ),
GLFW_PRESS,
command_hint::none,
// 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 );
@@ -104,7 +103,7 @@ mouse_input::button( int const Button, int const Action ) {
// 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( mousecommand, 0, 0, Action, command_hint::none, 0 );
m_relay.post( mousecommand, 0, 0, Action, 0 );
mousecommand = user_command::none;
}
else {
@@ -143,7 +142,7 @@ mouse_input::button( int const Button, int const Action ) {
// 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( mousecommand, 0, 0, Action, command_hint::none, 0 );
m_relay.post( mousecommand, 0, 0, Action, 0 );
m_updateaccumulator = -0.25; // prevent potential command repeat right after issuing one
switch( mousecommand ) {
@@ -194,13 +193,13 @@ mouse_input::poll() {
// 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( m_mousecommandleft, 0, 0, GLFW_REPEAT, command_hint::none, 0 );
m_relay.post( m_mousecommandleft, 0, 0, GLFW_REPEAT, 0 );
}
if( m_mousecommandright != user_command::none ) {
// 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( m_mousecommandright, 0, 0, GLFW_REPEAT, command_hint::none, 0 );
m_relay.post( m_mousecommandright, 0, 0, GLFW_REPEAT, 0 );
}
m_updateaccumulator -= updaterate;
}
@@ -244,11 +243,11 @@ mouse_input::default_bindings() {
user_command::motoroverloadrelaythresholdtoggle,
user_command::none } },
{ "main_off_bt:", {
user_command::linebreakertoggle,
user_command::linebreakeropen,
user_command::none } },
{ "main_on_bt:",{
user_command::linebreakertoggle,
user_command::none } }, // TODO: dedicated on and off line breaker commands
user_command::linebreakerclose,
user_command::none } },
{ "security_reset_bt:", {
user_command::alerteracknowledge,
user_command::none } },

View File

@@ -434,6 +434,9 @@ opengl_renderer::Render() {
+ " exponent: " + to_string( lightexponent, 2 )
+ " constant attn: " + to_string( lightconstant, 2 )
+ " linear attn: " + to_string( lightlinear, 3 );
*/
/*
m_debugstatstext = "sun hour angle: " + to_string( -World.Environment.m_sun.getHourAngle(), 6 );
*/
++m_framestamp;

141
uart.cpp
View File

@@ -4,6 +4,7 @@
#include "Globals.h"
#include "World.h"
#include "Train.h"
#include "parser.h"
#include "Logs.h"
uart_input::uart_input()
@@ -38,7 +39,7 @@ uart_input::uart_input()
uart_input::~uart_input()
{
std::array<uint8_t, 31> buffer = { 0 };
std::array<std::uint8_t, 31> buffer = { 0 };
sp_blocking_write(port, (void*)buffer.data(), buffer.size(), 0);
sp_drain(port);
@@ -46,6 +47,80 @@ uart_input::~uart_input()
sp_free_port(port);
}
bool
uart_input::recall_bindings() {
m_inputbindings.clear();
cParser bindingparser( "eu07_input-uart.ini", cParser::buffer_FILE );
if( false == bindingparser.ok() ) {
return false;
}
// build helper translation tables
std::unordered_map<std::string, user_command> nametocommandmap;
std::size_t commandid = 0;
for( auto const &description : simulation::Commands_descriptions ) {
nametocommandmap.emplace(
description.name,
static_cast<user_command>( commandid ) );
++commandid;
}
std::unordered_map<std::string, input_type_t> nametotypemap {
{ "impulse", input_type_t::impulse },
{ "toggle", input_type_t::toggle },
{ "value", input_type_t::value } };
// NOTE: to simplify things we expect one entry per line, and whole entry in one line
while( true == bindingparser.getTokens( 1, true, "\n" ) ) {
std::string bindingentry;
bindingparser >> bindingentry;
cParser entryparser( bindingentry );
if( true == entryparser.getTokens( 2, true, "\n\r\t " ) ) {
std::size_t bindingpin {};
std::string bindingtypename {};
entryparser
>> bindingpin
>> bindingtypename;
auto const typelookup = nametotypemap.find( bindingtypename );
if( typelookup == nametotypemap.end() ) {
WriteLog( "Uart binding for input pin " + std::to_string( bindingpin ) + " specified unknown control type, \"" + bindingtypename + "\"" );
}
else {
auto const bindingtype { typelookup->second };
std::array<user_command, 2> bindingcommands { user_command::none, user_command::none };
auto const commandcount { ( bindingtype == toggle ? 2 : 1 ) };
for( int commandidx = 0; commandidx < commandcount; ++commandidx ) {
// grab command(s) associated with the input pin
auto const bindingcommandname { entryparser.getToken<std::string>() };
if( true == bindingcommandname.empty() ) {
// no tokens left, may as well complain then call it a day
WriteLog( "Uart binding for input pin " + std::to_string( bindingpin ) + " didn't specify associated command(s)" );
break;
}
auto const commandlookup = nametocommandmap.find( bindingcommandname );
if( commandlookup == nametocommandmap.end() ) {
WriteLog( "Uart binding for input pin " + std::to_string( bindingpin ) + " specified unknown command, \"" + bindingcommandname + "\"" );
}
else {
bindingcommands[ commandidx ] = commandlookup->second;
}
}
// push the binding on the list
m_inputbindings.emplace_back( bindingpin, bindingtype, bindingcommands[ 0 ], bindingcommands[ 1 ] );
}
}
}
return true;
}
#define SPLIT_INT16(x) (uint8_t)x, (uint8_t)(x >> 8)
void uart_input::poll()
@@ -63,7 +138,7 @@ void uart_input::poll()
if ((ret = sp_input_waiting(port)) >= 16)
{
std::array<uint8_t, 16> buffer;
std::array<uint8_t, 16> 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");
@@ -79,49 +154,33 @@ void uart_input::poll()
data_pending = false;
for (auto entry : input_bits)
{
input_type_t type = std::get<2>(entry);
for (auto const &entry : m_inputbindings) {
size_t byte = std::get<0>(entry) / 8;
size_t bit = std::get<0>(entry) % 8;
auto const byte { std::get<std::size_t>( entry ) / 8 };
auto const bit { std::get<std::size_t>( entry ) % 8 };
bool state = ( (buffer[byte] & (1 << bit)) != 0 );
bool const state { ( ( buffer[ byte ] & ( 1 << bit ) ) != 0 ) };
bool const changed { ( ( old_packet[ byte ] & ( 1 << bit ) ) != state ) };
bool repeat = (type == impulse_r ||
type == impulse_r_off ||
type == impulse_r_on);
if( false == changed ) { continue; }
bool changed = ( (buffer[ byte ] & (1 << bit)) != (old_packet[ byte ] & (1 << bit)) );
auto const type { std::get<input_type_t>( entry ) };
auto const action { (
type != impulse ?
GLFW_PRESS :
( true == state ?
GLFW_PRESS :
GLFW_RELEASE ) ) };
if (!changed && !(repeat && state))
continue;
auto const command { (
type != toggle ?
std::get<2>( entry ) :
( action == GLFW_PRESS ?
std::get<2>( entry ) :
std::get<3>( entry ) ) ) };
int action;
command_hint desired_state;
if (type == toggle)
{
action = GLFW_PRESS;
desired_state = ( state ? command_hint::on : command_hint::off );
}
else if (type == impulse_r_on)
{
action = ( state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE );
desired_state = command_hint::on;
}
else if (type == impulse_r_off)
{
action = ( state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE );
desired_state = command_hint::off;
}
else if (type == impulse || type == impulse_r)
{
action = ( state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE );
desired_state = command_hint::none;
}
relay.post( std::get<1>(entry), 0, 0, action, desired_state, 0 );
// TODO: pass correct entity id once the missing systems are in place
relay.post( command, 0, 0, action, 0 );
}
if( true == conf.mainenable ) {
@@ -131,7 +190,6 @@ void uart_input::poll()
buffer[ 6 ],
0,
GLFW_PRESS,
command_hint::none,
// TODO: pass correct entity id once the missing systems are in place
0 );
}
@@ -142,7 +200,6 @@ void uart_input::poll()
buffer[ 7 ],
0,
GLFW_PRESS,
command_hint::none,
// TODO: pass correct entity id once the missing systems are in place
0 );
}
@@ -154,7 +211,6 @@ void uart_input::poll()
reinterpret_cast<std::uint64_t const &>( position ),
0,
GLFW_PRESS,
command_hint::none,
// TODO: pass correct entity id once the missing systems are in place
0 );
}
@@ -166,7 +222,6 @@ void uart_input::poll()
reinterpret_cast<std::uint64_t const &>( position ),
0,
GLFW_PRESS,
command_hint::none,
// TODO: pass correct entity id once the missing systems are in place
0 );
}

49
uart.h
View File

@@ -39,53 +39,30 @@ public:
// methods
uart_input();
~uart_input();
void poll();
bool
init() { return recall_bindings(); }
bool
recall_bindings();
void
poll();
private:
// types
enum input_type_t
{
toggle,
impulse,
impulse_r,
impulse_r_on,
impulse_r_off
toggle, // two commands, each mapped to one state; press event on state change
impulse, // one command; press event when set, release when cleared
value // one command; press event, value of specified byte passed as param1
};
std::array<std::tuple<size_t, user_command, input_type_t>, 23> input_bits =
{
std::make_tuple(1, user_command::linebreakertoggle, impulse_r_off),
std::make_tuple(2, user_command::linebreakertoggle, impulse_r_on),
std::make_tuple(3, user_command::motoroverloadrelayreset, impulse),
std::make_tuple(5, user_command::converteroverloadrelayreset, impulse),
std::make_tuple(6, user_command::motorconnectorsopen, toggle),
std::make_tuple(7, user_command::alerteracknowledge, impulse_r),
std::make_tuple(9, user_command::convertertoggle, toggle),
std::make_tuple(10, user_command::compressortoggle, toggle),
std::make_tuple(11, user_command::sandboxactivate, impulse),
std::make_tuple(12, user_command::heatingtoggle, toggle),
std::make_tuple(15, user_command::motoroverloadrelaythresholdtoggle, toggle),
std::make_tuple(16, user_command::pantographtogglefront, toggle),
std::make_tuple(17, user_command::pantographtogglerear, toggle),
std::make_tuple(18, user_command::wheelspinbrakeactivate, impulse),
std::make_tuple(19, user_command::headlightsdimtoggle, toggle),
std::make_tuple(20, user_command::interiorlightdimtoggle, toggle),
std::make_tuple(21, user_command::independentbrakebailoff, impulse),
std::make_tuple(22, user_command::hornhighactivate, impulse),
std::make_tuple(23, user_command::hornlowactivate, impulse),
std::make_tuple(24, user_command::batterytoggle, toggle),
std::make_tuple(25, user_command::headlighttoggleleft, toggle),
std::make_tuple(26, user_command::headlighttoggleupper, toggle),
std::make_tuple(27, user_command::headlighttoggleright, toggle)
};
using input_pin_t = std::tuple<std::size_t, input_type_t, user_command, user_command>;
using inputpin_sequence = std::vector<input_pin_t>;
// members
sp_port *port = nullptr;
inputpin_sequence m_inputbindings;
command_relay relay;
std::array<uint8_t, 16> old_packet;
std::array<std::uint8_t, 16> old_packet; // TBD, TODO: replace with vector of configurable size?
std::chrono::time_point<std::chrono::high_resolution_clock> last_update;
conf_t conf;
bool data_pending = false;