refactored mouse input processor, tweaks to mouse input support, fix for diesel engine compressor, added progress bar label

This commit is contained in:
tmj-fstate
2017-07-10 19:36:23 +02:00
parent 9a008ecff5
commit 16718d53bb
15 changed files with 520 additions and 343 deletions

View File

@@ -23,6 +23,7 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
#include "Globals.h"
#include "Logs.h"
#include "keyboardinput.h"
#include "mouseinput.h"
#include "gamepadinput.h"
#include "Console.h"
#include "PyInt.h"
@@ -65,6 +66,7 @@ TWorld World;
namespace input {
keyboard_input Keyboard;
mouse_input Mouse;
gamepad_input Gamepad;
glm::dvec2 mouse_pos; // stores last mouse position in control picking mode
@@ -123,11 +125,12 @@ void window_resize_callback(GLFWwindow *window, int w, int h)
void cursor_pos_callback(GLFWwindow *window, double x, double y)
{
input::Mouse.move( x, y );
if( true == Global::ControlPicking ) {
glfwSetCursorPos( window, x, y );
}
else {
input::Keyboard.mouse( x, y );
glfwSetCursorPos( window, 0, 0 );
}
}
@@ -137,7 +140,7 @@ void mouse_button_callback( GLFWwindow* window, int button, int action, int mods
if( ( button == GLFW_MOUSE_BUTTON_LEFT )
|| ( button == GLFW_MOUSE_BUTTON_RIGHT ) ) {
// we don't care about other mouse buttons at the moment
input::Keyboard.mouse( button, action );
input::Mouse.button( button, action );
}
}
@@ -148,8 +151,9 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo
Global::shiftState = ( mods & GLFW_MOD_SHIFT ) ? true : false;
Global::ctrlState = ( mods & GLFW_MOD_CONTROL ) ? true : false;
if( ( key == GLFW_KEY_LEFT_ALT )
|| ( key == GLFW_KEY_RIGHT_ALT ) ) {
if( ( true == Global::InputMouse )
&& ( ( key == GLFW_KEY_LEFT_ALT )
|| ( key == GLFW_KEY_RIGHT_ALT ) ) ) {
// if the alt key was pressed toggle control picking mode and set matching cursor behaviour
if( action == GLFW_RELEASE ) {
@@ -413,6 +417,7 @@ int main(int argc, char *argv[])
return -1;
}
input::Keyboard.init();
input::Mouse.init();
input::Gamepad.init();
Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów
@@ -452,9 +457,8 @@ int main(int argc, char *argv[])
&& ( true == GfxRenderer.Render() ) ) {
glfwPollEvents();
input::Keyboard.poll();
if( true == Global::InputGamepad ) {
input::Gamepad.poll();
}
if( true == Global::InputMouse ) { input::Mouse.poll(); }
if( true == Global::InputGamepad ) { input::Gamepad.poll(); }
}
}
catch( std::bad_alloc const &Error ) {

View File

@@ -152,17 +152,19 @@ double TGauge::GetValue() const {
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;
}
else {
fValue = fDesiredValue;
}
if( std::abs( fDesiredValue - fValue ) <= 0.001 ) {
// close enough, we can stop updating the model
fValue = fDesiredValue; // set it exactly as requested just in case it matters
if( fValue != fDesiredValue ) {
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( std::abs( fDesiredValue - fValue ) <= 0.0001 ) {
// close enough, we can stop updating the model
fValue = fDesiredValue; // set it exactly as requested just in case it matters
}
}
else {
fValue = fDesiredValue;
}
}
if( SubModel )
{ // warunek na wszelki wypadek, gdyby się submodel nie podłączył

View File

@@ -48,6 +48,7 @@ bool Global::ctrlState;
int Global::iCameraLast = -1;
std::string Global::asVersion = "couldn't retrieve version string";
bool Global::ControlPicking = false; // indicates controls pick mode is enabled
bool Global::InputMouse = true; // whether control pick mode can be activated
int Global::iTextMode = 0; // tryb pracy wyświetlacza tekstowego
int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // numer ekranu wyświetlacza tekstowego
double Global::fSunDeclination = 0.0; // deklinacja Słońca
@@ -371,6 +372,11 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens(2, false);
Parser >> Global::fMouseXScale >> Global::fMouseYScale;
}
else if( token == "mousecontrol" ) {
// whether control pick mode can be activated
Parser.getTokens();
Parser >> Global::InputMouse;
}
else if (token == "enabletraction")
{
// Winger 040204 - 'zywe' patyki dostosowujace sie do trakcji; Ra 2014-03: teraz łamanie

View File

@@ -256,7 +256,8 @@ class Global
static int iCameraLast;
static std::string asVersion; // z opisem
static GLint iMaxTextureSize; // maksymalny rozmiar tekstury
static bool ControlPicking; // indicates controls pick mode is enabled
static bool ControlPicking; // indicates controls pick mode is active
static bool InputMouse; // whether control pick mode can be activated
static int iTextMode; // tryb pracy wyświetlacza tekstowego
static int iScreenMode[12]; // numer ekranu wyświetlacza tekstowego
static bool bDoubleAmbient; // podwójna jasność ambient

View File

@@ -1544,7 +1544,7 @@ double TMoverParameters::ShowEngineRotation(int VehN)
switch (VehN)
{ // numer obrotomierza
case 1:
return fabs(enrot);
return std::abs(enrot);
case 2:
for (b = 0; b <= 1; ++b)
if (TestFlag(Couplers[b].CouplingFlag, ctrain_controll))
@@ -3045,6 +3045,11 @@ void TMoverParameters::CompressorCheck(double dt)
}
else
{
if( ( EngineType == DieselEngine )
&& ( CompressorPower == 0 ) ) {
// experimental: make sure compressor coupled with diesel engine is always ready for work
CompressorAllow = true;
}
if (CompressorFlag) // jeśli sprężarka załączona
{ // sprawdzić możliwe warunki wyłączenia sprężarki
if (CompressorPower == 5) // jeśli zasilanie z sąsiedniego członu
@@ -3172,29 +3177,38 @@ void TMoverParameters::CompressorCheck(double dt)
}
}
if (CompressorFlag)
if ((EngineType == DieselElectric) && (CompressorPower > 0))
CompressedVolume += dt * CompressorSpeed * (2.0 * MaxCompressor - Compressor) /
MaxCompressor *
(DElist[MainCtrlPos].RPM / DElist[MainCtrlPosNo].RPM);
else
{
if( CompressorFlag ) {
if( ( EngineType == DieselElectric ) && ( CompressorPower > 0 ) ) {
CompressedVolume +=
dt * CompressorSpeed * (2.0 * MaxCompressor - Compressor) / MaxCompressor;
if ((CompressorPower == 5) && (Couplers[1].Connected != NULL))
Couplers[1].Connected->TotalCurrent +=
0.0015 * Couplers[1].Connected->Voltage; // tymczasowo tylko obciążenie
// sprężarki, tak z 5A na
// sprężarkę
else if ((CompressorPower == 4) && (Couplers[0].Connected != NULL))
Couplers[0].Connected->TotalCurrent +=
0.0015 * Couplers[0].Connected->Voltage; // tymczasowo tylko obciążenie
// sprężarki, tak z 5A na
// sprężarkę
dt * CompressorSpeed
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
* ( DElist[ MainCtrlPos ].RPM / DElist[ MainCtrlPosNo ].RPM );
}
else if( ( EngineType == DieselEngine ) && ( CompressorPower == 0 ) ) {
// experimental: compressor coupled with diesel engine, output scaled by current engine rotational speed
CompressedVolume +=
dt * CompressorSpeed
* ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor
* ( std::abs( enrot ) / nmax );
}
else {
CompressedVolume +=
dt * CompressorSpeed * ( 2.0 * MaxCompressor - Compressor ) / MaxCompressor;
if( ( CompressorPower == 5 ) && ( Couplers[ 1 ].Connected != NULL ) )
Couplers[ 1 ].Connected->TotalCurrent +=
0.0015 * Couplers[ 1 ].Connected->Voltage; // tymczasowo tylko obciążenie
// sprężarki, tak z 5A na
// sprężarkę
else if( ( CompressorPower == 4 ) && ( Couplers[ 0 ].Connected != NULL ) )
Couplers[ 0 ].Connected->TotalCurrent +=
0.0015 * Couplers[ 0 ].Connected->Voltage; // tymczasowo tylko obciążenie
// sprężarki, tak z 5A na
// sprężarkę
else
TotalCurrent += 0.0015 *
Voltage; // tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę
Voltage; // tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę
}
}
}
}
}
@@ -7236,9 +7250,10 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
extract_value( dizel_nmin, "nmin", Input, "" );
dizel_nmin /= 60.0;
extract_value( dizel_nmax, "nmax", Input, "" );
dizel_nmax /= 60.0;
nmax = dizel_nmax; // not sure if this is needed, but just in case
// TODO: unify naming scheme and sort out which diesel engine params are used where and how
extract_value( nmax, "nmax", Input, "" );
nmax /= 60.0;
// nmax = dizel_nmax; // not sure if this is needed, but just in case
extract_value( dizel_nmax_cutoff, "nmax_cutoff", Input, "0.0" );
dizel_nmax_cutoff /= 60.0;
extract_value( dizel_AIM, "AIM", Input, "1.0" );

View File

@@ -301,34 +301,38 @@ bool TWorld::Init( GLFWwindow *Window ) {
"ShaXbee, Oli_EU, youBy, KURS90, Ra, hunter, szociu, Stele, Q, firleju and others\n" );
UILayer.set_background( "logo" );
/*
std::shared_ptr<ui_panel> initpanel = std::make_shared<ui_panel>(85, 600);
*/
TSoundsManager::Init( glfwGetWin32Window( window ) );
WriteLog("Sound Init OK");
TModelsManager::Init();
WriteLog("Models init OK");
/*
initpanel->text_lines.emplace_back( "Loading scenery / Wczytywanie scenerii:", float4( 0.0f, 0.0f, 0.0f, 1.0f ) );
initpanel->text_lines.emplace_back( Global::SceneryFile.substr(0, 40), float4( 0.0f, 0.0f, 0.0f, 1.0f ) );
UILayer.push_back( initpanel );
*/
glfwSetWindowTitle( window, ( Global::AppName + " (" + Global::SceneryFile + ")" ).c_str() ); // nazwa scenerii
UILayer.set_progress(0.01);
UILayer.set_progress( "Loading scenery / Wczytywanie scenerii" );
GfxRenderer.Render();
WriteLog( "Ground init" );
Ground.Init(Global::SceneryFile);
WriteLog( "Ground init OK" );
glfwSetWindowTitle( window, ( Global::AppName + " (" + Global::SceneryFile + ")" ).c_str() ); // nazwa scenerii
if( true == Ground.Init( Global::SceneryFile ) ) {
WriteLog( "Ground init OK" );
}
simulation::Time.init();
Environment.init();
Camera.Init(Global::FreeCameraInit[0], Global::FreeCameraInitAngle[0]);
/*
initpanel->text_lines.clear();
initpanel->text_lines.emplace_back( "Preparing train / Przygotowanie kabiny:", float4( 0.0f, 0.0f, 0.0f, 1.0f ) );
*/
UILayer.set_progress( "Preparing train / Przygotowanie kabiny" );
GfxRenderer.Render();
WriteLog( "Player train init: " + Global::asHumanCtrlVehicle );
@@ -396,6 +400,7 @@ bool TWorld::Init( GLFWwindow *Window ) {
Train->Dynamic()->Mechanik->TakeControl(true);
*/
UILayer.set_progress();
UILayer.set_progress( "" );
UILayer.set_background( "" );
UILayer.clear_texts();

View File

@@ -11,11 +11,7 @@ http://mozilla.org/MPL/2.0/.
#include "keyboardinput.h"
#include "logs.h"
#include "parser.h"
#include "globals.h"
#include "timer.h"
//#include "world.h"
#include "train.h"
#include "renderer.h"
#include "world.h"
extern TWorld World;
@@ -162,91 +158,6 @@ keyboard_input::key( int const Key, int const Action ) {
return true;
}
void
keyboard_input::mouse( double Mousex, double Mousey ) {
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 );
}
void
keyboard_input::mouse( int const Button, int const Action ) {
if( false == Global::ControlPicking ) { return; }
if( true == FreeFlyModeFlag ) {
// for now we're only interested in cab controls
return;
}
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 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 ) {
// 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
}
}
}
}
}
void
keyboard_input::poll() {
m_updateaccumulator += Timer::GetDeltaRenderTime();
if( m_updateaccumulator < 0.2 ) {
// too early for any work
return;
}
m_updateaccumulator -= 0.2;
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
keyboard_input::default_bindings() {
@@ -446,182 +357,6 @@ const int k_WalkMode = 73;
bind();
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::trainbrakedecrease,
user_command::trainbrakeincrease } },
{ "localbrake:", {
user_command::independentbrakedecrease,
user_command::independentbrakeincrease } },
{ "manualbrake:", {
user_command::none,
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 } },
{ "cablight_sw:", {
user_command::interiorlighttoggle,
user_command::none } },
{ "cablightdim_sw:", {
user_command::interiorlightdimtoggle,
user_command::none } },
{ "battery_sw:", {
user_command::batterytoggle,
user_command::none } }
};
}
void

View File

@@ -27,11 +27,7 @@ public:
bool
key( int const Key, int const Action );
void
mouse( double const Mousex, double const Mousey );
void
mouse( int const Button, int const Action );
void
poll();
poll() {}
private:
// types
@@ -49,18 +45,6 @@ private:
typedef std::vector<command_setup> commandsetup_sequence;
typedef std::unordered_map<int, user_command> usercommand_map;
struct mouse_commands {
user_command left;
user_command right;
mouse_commands( user_command const Left, user_command const Right ):
left(Left), right(Right)
{}
};
typedef std::unordered_map<std::string, mouse_commands> controlcommands_map;
struct bindings_cache {
int forward{ -1 };
@@ -82,13 +66,9 @@ private:
// members
commandsetup_sequence m_commands;
usercommand_map m_bindings;
controlcommands_map m_mousecommands;
user_command m_mousecommandleft { user_command::none }; // last if any command issued with mouse
user_command m_mousecommandright { user_command::none };
command_relay m_relay;
bool m_shift{ false };
bool m_ctrl{ false };
double m_updateaccumulator { 0.0 };
bindings_cache m_bindingscache;
std::array<char, GLFW_KEY_LAST + 1> m_keys;
};

View File

@@ -225,6 +225,9 @@
<ClCompile Include="openglgeometrybank.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="mouseinput.cpp">
<Filter>Source Files\input</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Globals.h">
@@ -440,6 +443,9 @@
<ClInclude Include="openglgeometrybank.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="mouseinput.h">
<Filter>Header Files\input</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="maszyna.rc">

335
mouseinput.cpp Normal file
View File

@@ -0,0 +1,335 @@
/*
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 "globals.h"
#include "timer.h"
#include "world.h"
#include "train.h"
#include "renderer.h"
extern TWorld World;
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 ) {
// for now we're only interested in cab controls
return;
}
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, stop view panning
if( Button == GLFW_MOUSE_BUTTON_RIGHT ) {
m_pickmodepanning = 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
if( mousecommand == user_command::mastercontrollerincrease ) {
m_updateaccumulator -= 0.15; // extra pause on first increase of master controller
}
}
}
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();
if( m_updateaccumulator < 0.1 ) {
// too early for any work
return;
}
m_updateaccumulator -= 0.1;
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::none,
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 } },
{ "cablight_sw:", {
user_command::interiorlighttoggle,
user_command::none } },
{ "cablightdim_sw:", {
user_command::interiorlightdimtoggle,
user_command::none } },
{ "battery_sw:", {
user_command::batterytoggle,
user_command::none } }
};
}
//---------------------------------------------------------------------------

60
mouseinput.h Normal file
View File

@@ -0,0 +1,60 @@
/*
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 <unordered_map>
#include <array>
#include "command.h"
class mouse_input {
public:
// constructors
mouse_input() { default_bindings(); }
// methods
bool
init() { return true; }
void
move( double const Mousex, double const Mousey );
void
button( int const Button, int const Action );
void
poll();
private:
// types
struct mouse_commands {
user_command left;
user_command right;
mouse_commands( user_command const Left, user_command const Right ):
left(Left), right(Right)
{}
};
typedef std::unordered_map<std::string, mouse_commands> controlcommands_map;
// methods
void
default_bindings();
// members
controlcommands_map m_mousecommands;
user_command m_mousecommandleft { user_command::none }; // last if any command issued with left mouse button
user_command m_mousecommandright { user_command::none }; // last if any command issued with right mouse button
command_relay m_relay;
double m_updateaccumulator { 0.0 };
bool m_pickmodepanning { false }; // indicates mouse is in view panning mode
glm::dvec2 m_cursorposition; // stored last mouse position, used for panning
};
//---------------------------------------------------------------------------

View File

@@ -206,8 +206,10 @@ opengl_renderer::Render_pass( rendermode const Mode ) {
// TODO: run shadowmap pass before color
// ::glViewport( 0, 0, Global::ScreenWidth, Global::ScreenHeight );
auto const skydomecolour = World.Environment.m_skydome.GetAverageColor();
::glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 0.0f ); // kolor nieba
if( World.InitPerformed() ) {
auto const skydomecolour = World.Environment.m_skydome.GetAverageColor();
::glClearColor( skydomecolour.x, skydomecolour.y, skydomecolour.z, 0.0f ); // kolor nieba
}
::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
if( World.InitPerformed() ) {
@@ -1972,6 +1974,7 @@ opengl_renderer::Update_Pick_Control() {
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
}
#endif
m_pickcontrolitem = control;
return control;
}
@@ -2015,6 +2018,7 @@ opengl_renderer::Update_Pick_Node() {
::glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
}
#endif
m_picksceneryitem = node;
return node;
}
@@ -2080,7 +2084,7 @@ opengl_renderer::Update( double const Deltatime ) {
if( ( true == Global::ControlPicking )
&& ( false == FreeFlyModeFlag ) ) {
m_pickcontrolitem = Update_Pick_Control();
Update_Pick_Control();
}
else {
m_pickcontrolitem = nullptr;
@@ -2089,7 +2093,7 @@ opengl_renderer::Update( double const Deltatime ) {
if( ( true == Global::ControlPicking )
&& ( true == DebugModeFlag )
&& ( true == FreeFlyModeFlag ) ) {
m_picksceneryitem = Update_Pick_Node();
Update_Pick_Node();
}
else {
m_picksceneryitem = nullptr;

View File

@@ -143,7 +143,29 @@ ui_layer::render_progress() {
float4( 8.0f / 255.0f, 160.0f / 255.0f, 8.0f / 255.0f, 1.0f ) );
}
glPopAttrib();
if( false == m_progresstext.empty() ) {
float const screenratio = static_cast<float>( Global::iWindowWidth ) / Global::iWindowHeight;
float const width =
( screenratio >= (4.0f/3.0f) ?
( 4.0f / 3.0f ) * Global::iWindowHeight :
Global::iWindowWidth );
float const heightratio =
( screenratio >= ( 4.0f / 3.0f ) ?
Global::iWindowHeight / 768.0 :
Global::iWindowHeight / 768.0 * screenratio / ( 4.0f / 3.0f ) );
float const height = 768.0f * heightratio;
::glColor4f( 216.0f / 255.0f, 216.0f / 255.0f, 216.0f / 255.0f, 1.0f );
auto const charsize = 9.0f;
auto const textwidth = m_progresstext.size() * charsize;
auto const textheight = 12.0f;
::glRasterPos2f(
( 0.5f * ( Global::iWindowWidth - width ) + origin.x * heightratio ) + ( ( size.x * heightratio - textwidth ) * 0.5f * heightratio ),
( 0.5f * ( Global::iWindowHeight - height ) + origin.y * heightratio ) + ( charsize ) + ( ( size.y * heightratio - textheight ) * 0.5f * heightratio ) );
print( m_progresstext );
}
glPopAttrib();
}
void

View File

@@ -47,6 +47,8 @@ public:
// stores operation progress
void
set_progress( float const Progress = 0.0f, float const Subtaskprogress = 0.0f );
void
set_progress( std::string const &Text ) { m_progresstext = Text; }
// sets the ui background texture, if any
void
set_background( std::string const &Filename = "" );

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 17
#define VERSION_MINOR 708
#define VERSION_MINOR 710
#define VERSION_REVISION 0