mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
424 lines
17 KiB
C++
424 lines
17 KiB
C++
/*
|
|
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 "mouseinput.h"
|
|
#include "usefull.h"
|
|
#include "Globals.h"
|
|
#include "Timer.h"
|
|
#include "World.h"
|
|
#include "Train.h"
|
|
#include "renderer.h"
|
|
|
|
extern TWorld World;
|
|
|
|
bool
|
|
mouse_input::init() {
|
|
|
|
#ifdef _WINDOWS
|
|
DWORD systemkeyboardspeed;
|
|
::SystemParametersInfo( SPI_GETKEYBOARDSPEED, 0, &systemkeyboardspeed, 0 );
|
|
m_updaterate = interpolate( 0.5, 0.04, systemkeyboardspeed / 31.0 );
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
void
|
|
mouse_input::move( double Mousex, double Mousey ) {
|
|
|
|
if( false == Global::ControlPicking ) {
|
|
// default control mode
|
|
m_relay.post(
|
|
user_command::viewturn,
|
|
reinterpret_cast<std::uint64_t const &>( Mousex ),
|
|
reinterpret_cast<std::uint64_t const &>( 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 );
|
|
}
|
|
else {
|
|
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;
|
|
m_cursorposition.y = Mousey;
|
|
return;
|
|
}
|
|
glm::dvec2 cursorposition { Mousex, Mousey };
|
|
auto const viewoffset = cursorposition - m_cursorposition;
|
|
m_relay.post(
|
|
user_command::viewturn,
|
|
reinterpret_cast<std::uint64_t const &>( viewoffset.x ),
|
|
reinterpret_cast<std::uint64_t const &>( viewoffset.y ),
|
|
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 );
|
|
m_cursorposition = cursorposition;
|
|
}
|
|
}
|
|
|
|
void
|
|
mouse_input::button( int const Button, int const Action ) {
|
|
|
|
if( false == Global::ControlPicking ) { return; }
|
|
|
|
if( true == FreeFlyModeFlag ) {
|
|
// world editor controls
|
|
// currently we only handle view panning in this mode
|
|
if( Action == GLFW_RELEASE ) {
|
|
// if it's the right mouse button that got released we were potentially in view panning mode; stop it
|
|
if( Button == GLFW_MOUSE_BUTTON_RIGHT ) {
|
|
m_pickmodepanning = false;
|
|
}
|
|
}
|
|
else {
|
|
// button press
|
|
if( Button == GLFW_MOUSE_BUTTON_RIGHT ) {
|
|
// the right button activates mouse panning mode
|
|
m_pickmodepanning = true;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// cab controls mode
|
|
user_command &mousecommand = (
|
|
Button == GLFW_MOUSE_BUTTON_LEFT ?
|
|
m_mousecommandleft :
|
|
m_mousecommandright
|
|
);
|
|
|
|
if( Action == GLFW_RELEASE ) {
|
|
if( mousecommand != 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( mousecommand, 0, 0, Action, 0 );
|
|
mousecommand = user_command::none;
|
|
}
|
|
else {
|
|
// if it's the right mouse button that got released and we had no command active, we were potentially in view panning mode; stop it
|
|
if( Button == GLFW_MOUSE_BUTTON_RIGHT ) {
|
|
m_pickmodepanning = false;
|
|
}
|
|
}
|
|
// if we were in varying command repeat rate, we can stop that now. done without any conditions, to catch some unforeseen edge cases
|
|
m_varyingpollrate = false;
|
|
}
|
|
else {
|
|
// if not release then it's press
|
|
auto train = World.train();
|
|
if( train != nullptr ) {
|
|
auto lookup = m_mousecommands.find( train->GetLabel( GfxRenderer.Update_Pick_Control() ) );
|
|
if( lookup != m_mousecommands.end() ) {
|
|
mousecommand = (
|
|
Button == GLFW_MOUSE_BUTTON_LEFT ?
|
|
lookup->second.left :
|
|
lookup->second.right
|
|
);
|
|
if( mousecommand != user_command::none ) {
|
|
// check manually for commands which have 'fast' variants launched with shift modifier
|
|
if( Global::shiftState ) {
|
|
switch( mousecommand ) {
|
|
case user_command::mastercontrollerincrease: { mousecommand = user_command::mastercontrollerincreasefast; break; }
|
|
case user_command::mastercontrollerdecrease: { mousecommand = user_command::mastercontrollerdecreasefast; break; }
|
|
case user_command::secondcontrollerincrease: { mousecommand = user_command::secondcontrollerincreasefast; break; }
|
|
case user_command::secondcontrollerdecrease: { mousecommand = user_command::secondcontrollerdecreasefast; break; }
|
|
case user_command::independentbrakeincrease: { mousecommand = user_command::independentbrakeincreasefast; break; }
|
|
case user_command::independentbrakedecrease: { mousecommand = user_command::independentbrakedecreasefast; break; }
|
|
default: { break; }
|
|
}
|
|
}
|
|
// 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, 0 );
|
|
m_updateaccumulator = 0.0; // prevent potential command repeat right after issuing one
|
|
|
|
switch( mousecommand ) {
|
|
case user_command::mastercontrollerincrease:
|
|
case user_command::mastercontrollerdecrease:
|
|
case user_command::secondcontrollerincrease:
|
|
case user_command::secondcontrollerdecrease:
|
|
case user_command::trainbrakeincrease:
|
|
case user_command::trainbrakedecrease:
|
|
case user_command::independentbrakeincrease:
|
|
case user_command::independentbrakedecrease: {
|
|
// these commands trigger varying repeat rate mode,
|
|
// which scales the rate based on the distance of the cursor from its point when the command was first issued
|
|
m_commandstartcursor = m_cursorposition;
|
|
m_varyingpollrate = true;
|
|
break;
|
|
}
|
|
default: {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
// if we don't have any recognized element under the cursor and the right button was pressed, enter view panning mode
|
|
if( Button == GLFW_MOUSE_BUTTON_RIGHT ) {
|
|
m_pickmodepanning = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
mouse_input::poll() {
|
|
|
|
m_updateaccumulator += Timer::GetDeltaRenderTime();
|
|
|
|
auto updaterate { m_updaterate };
|
|
if( m_varyingpollrate ) {
|
|
updaterate /= std::max( 0.15, 2.0 * glm::length( m_cursorposition - m_commandstartcursor ) / std::max( 1, Global::iWindowHeight ) );
|
|
}
|
|
|
|
if( m_updateaccumulator < updaterate ) {
|
|
// too early for any work
|
|
return;
|
|
}
|
|
m_updateaccumulator -= updaterate;
|
|
|
|
if( m_mousecommandleft != 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_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, 0 );
|
|
}
|
|
}
|
|
|
|
void
|
|
mouse_input::default_bindings() {
|
|
|
|
m_mousecommands = {
|
|
{ "mainctrl:", {
|
|
user_command::mastercontrollerincrease,
|
|
user_command::mastercontrollerdecrease } },
|
|
{ "scndctrl:", {
|
|
user_command::secondcontrollerincrease,
|
|
user_command::secondcontrollerdecrease } },
|
|
{ "dirkey:", {
|
|
user_command::reverserincrease,
|
|
user_command::reverserdecrease } },
|
|
{ "brakectrl:", {
|
|
user_command::trainbrakeincrease,
|
|
user_command::trainbrakedecrease } },
|
|
{ "localbrake:", {
|
|
user_command::independentbrakeincrease,
|
|
user_command::independentbrakedecrease } },
|
|
{ "manualbrake:", {
|
|
user_command::manualbrakeincrease,
|
|
user_command::manualbrakedecrease } },
|
|
{ "alarmchain:", {
|
|
user_command::alarmchaintoggle,
|
|
user_command::none } },
|
|
{ "brakeprofile_sw:", {
|
|
user_command::brakeactingspeedincrease,
|
|
user_command::brakeactingspeeddecrease } },
|
|
{ "brakeprofileg_sw:", {
|
|
user_command::brakeactingspeeddecrease,
|
|
user_command::none } },
|
|
{ "brakeprofiler_sw:", {
|
|
user_command::brakeactingspeedincrease,
|
|
user_command::none } },
|
|
{ "maxcurrent_sw:", {
|
|
user_command::motoroverloadrelaythresholdtoggle,
|
|
user_command::none } },
|
|
{ "main_off_bt:", {
|
|
user_command::linebreakertoggle,
|
|
user_command::none } },
|
|
{ "main_on_bt:",{
|
|
user_command::linebreakertoggle,
|
|
user_command::none } }, // TODO: dedicated on and off line breaker commands
|
|
{ "security_reset_bt:", {
|
|
user_command::alerteracknowledge,
|
|
user_command::none } },
|
|
{ "releaser_bt:", {
|
|
user_command::independentbrakebailoff,
|
|
user_command::none } },
|
|
{ "sand_bt:", {
|
|
user_command::sandboxactivate,
|
|
user_command::none } },
|
|
{ "antislip_bt:", {
|
|
user_command::wheelspinbrakeactivate,
|
|
user_command::none } },
|
|
{ "horn_bt:", {
|
|
user_command::hornhighactivate,
|
|
user_command::hornlowactivate } },
|
|
{ "hornlow_bt:", {
|
|
user_command::hornlowactivate,
|
|
user_command::none } },
|
|
{ "hornhigh_bt:", {
|
|
user_command::hornhighactivate,
|
|
user_command::none } },
|
|
{ "fuse_bt:", {
|
|
user_command::motoroverloadrelayreset,
|
|
user_command::none } },
|
|
{ "converterfuse_bt:", {
|
|
user_command::converteroverloadrelayreset,
|
|
user_command::none } },
|
|
{ "stlinoff_bt:", {
|
|
user_command::motorconnectorsopen,
|
|
user_command::none } },
|
|
{ "door_left_sw:", {
|
|
user_command::doortoggleleft,
|
|
user_command::none } },
|
|
{ "door_right_sw:", {
|
|
user_command::doortoggleright,
|
|
user_command::none } },
|
|
{ "departure_signal_bt:", {
|
|
user_command::departureannounce,
|
|
user_command::none } },
|
|
{ "upperlight_sw:", {
|
|
user_command::headlighttoggleupper,
|
|
user_command::none } },
|
|
{ "leftlight_sw:", {
|
|
user_command::headlighttoggleleft,
|
|
user_command::none } },
|
|
{ "rightlight_sw:", {
|
|
user_command::headlighttoggleright,
|
|
user_command::none } },
|
|
{ "dimheadlights_sw:", {
|
|
user_command::headlightsdimtoggle,
|
|
user_command::none } },
|
|
{ "leftend_sw:", {
|
|
user_command::redmarkertoggleleft,
|
|
user_command::none } },
|
|
{ "rightend_sw:", {
|
|
user_command::redmarkertoggleright,
|
|
user_command::none } },
|
|
{ "lights_sw:", {
|
|
user_command::none,
|
|
user_command::none } }, // TODO: implement commands for lights controller
|
|
{ "rearupperlight_sw:", {
|
|
user_command::headlighttogglerearupper,
|
|
user_command::none } },
|
|
{ "rearleftlight_sw:", {
|
|
user_command::headlighttogglerearleft,
|
|
user_command::none } },
|
|
{ "rearrightlight_sw:", {
|
|
user_command::headlighttogglerearright,
|
|
user_command::none } },
|
|
{ "rearleftend_sw:", {
|
|
user_command::redmarkertogglerearleft,
|
|
user_command::none } },
|
|
{ "rearrightend_sw:", {
|
|
user_command::redmarkertogglerearright,
|
|
user_command::none } },
|
|
{ "compressor_sw:", {
|
|
user_command::compressortoggle,
|
|
user_command::none } },
|
|
{ "compressorlocal_sw:", {
|
|
user_command::compressortogglelocal,
|
|
user_command::none } },
|
|
{ "converter_sw:", {
|
|
user_command::convertertoggle,
|
|
user_command::none } },
|
|
{ "converterlocal_sw:", {
|
|
user_command::convertertogglelocal,
|
|
user_command::none } },
|
|
{ "converteroff_sw:", {
|
|
user_command::convertertoggle,
|
|
user_command::none } }, // TODO: dedicated converter shutdown command
|
|
{ "main_sw:", {
|
|
user_command::linebreakertoggle,
|
|
user_command::none } },
|
|
{ "radio_sw:", {
|
|
user_command::radiotoggle,
|
|
user_command::none } },
|
|
{ "pantfront_sw:", {
|
|
user_command::pantographtogglefront,
|
|
user_command::none } },
|
|
{ "pantrear_sw:", {
|
|
user_command::pantographtogglerear,
|
|
user_command::none } },
|
|
{ "pantfrontoff_sw:", {
|
|
user_command::pantographtogglefront,
|
|
user_command::none } }, // TODO: dedicated lower pantograph commands
|
|
{ "pantrearoff_sw:", {
|
|
user_command::pantographtogglerear,
|
|
user_command::none } }, // TODO: dedicated lower pantograph commands
|
|
{ "pantalloff_sw:", {
|
|
user_command::pantographlowerall,
|
|
user_command::none } },
|
|
{ "pantselected_sw:", {
|
|
user_command::none,
|
|
user_command::none } }, // TODO: selected pantograph(s) operation command
|
|
{ "pantselectedoff_sw:", {
|
|
user_command::none,
|
|
user_command::none } }, // TODO: lower selected pantograp(s) command
|
|
{ "trainheating_sw:", {
|
|
user_command::heatingtoggle,
|
|
user_command::none } },
|
|
{ "signalling_sw:", {
|
|
user_command::mubrakingindicatortoggle,
|
|
user_command::none } },
|
|
{ "door_signalling_sw:", {
|
|
user_command::doorlocktoggle,
|
|
user_command::none } },
|
|
{ "nextcurrent_sw:", {
|
|
user_command::mucurrentindicatorothersourceactivate,
|
|
user_command::none } },
|
|
{ "instrumentlight_sw:", {
|
|
user_command::instrumentlighttoggle,
|
|
user_command::none } },
|
|
{ "cablight_sw:", {
|
|
user_command::interiorlighttoggle,
|
|
user_command::none } },
|
|
{ "cablightdim_sw:", {
|
|
user_command::interiorlightdimtoggle,
|
|
user_command::none } },
|
|
{ "battery_sw:", {
|
|
user_command::batterytoggle,
|
|
user_command::none } },
|
|
{ "universal0:", {
|
|
user_command::generictoggle0,
|
|
user_command::none } },
|
|
{ "universal1:", {
|
|
user_command::generictoggle1,
|
|
user_command::none } },
|
|
{ "universal2:", {
|
|
user_command::generictoggle2,
|
|
user_command::none } },
|
|
{ "universal3:", {
|
|
user_command::generictoggle3,
|
|
user_command::none } },
|
|
{ "universal4:", {
|
|
user_command::generictoggle4,
|
|
user_command::none } },
|
|
{ "universal5:", {
|
|
user_command::generictoggle5,
|
|
user_command::none } },
|
|
{ "universal6:", {
|
|
user_command::generictoggle6,
|
|
user_command::none } },
|
|
{ "universal7:", {
|
|
user_command::generictoggle7,
|
|
user_command::none } },
|
|
{ "universal8:", {
|
|
user_command::generictoggle8,
|
|
user_command::none } },
|
|
{ "universal9:", {
|
|
user_command::generictoggle9,
|
|
user_command::none } }
|
|
};
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|