mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-20 09:09:19 +02:00
Merge pull request #83 from Unofficial-MaSzyna-Developement/new-features-feb-25
New features done in february 2025
This commit is contained in:
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,3 +1,7 @@
|
||||
[submodule "ref/asio"]
|
||||
path = ref/asio
|
||||
url = https://github.com/chriskohlhoff/asio.git
|
||||
[submodule "ref/discord-rpc"]
|
||||
path = ref/discord-rpc
|
||||
url = https://github.com/discord/discord-rpc.git
|
||||
branch = v3.4.0
|
||||
|
||||
@@ -429,6 +429,12 @@ target_link_libraries(${PROJECT_NAME} Threads::Threads)
|
||||
find_package(GLM REQUIRED)
|
||||
include_directories(${GLM_INCLUDE_DIR})
|
||||
|
||||
# add ref/discord-rpc to the project in the same way other dependencies are added
|
||||
add_subdirectory(ref/discord-rpc)
|
||||
target_link_libraries(${PROJECT_NAME} discord-rpc)
|
||||
|
||||
|
||||
|
||||
find_package(OpenAL REQUIRED)
|
||||
if (TARGET OpenAL::OpenAL)
|
||||
target_link_libraries(${PROJECT_NAME} OpenAL::OpenAL)
|
||||
|
||||
161
DynObj.cpp
161
DynObj.cpp
@@ -97,8 +97,110 @@ void TAnimPant::AKP_4E()
|
||||
fHeightExtra[3] = -0.07f; //+0.3048
|
||||
fHeightExtra[4] = -0.15f; //+0.3810
|
||||
};
|
||||
void TAnimPant::WBL85()
|
||||
{ // ustawienie wymiarów dla pantografu WBL88
|
||||
vPos = Math3D::vector3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów
|
||||
|
||||
// mnozniki animacji ramion dla pantografu WBL88
|
||||
rd1rf = 1.f;
|
||||
rd2rf = 1.2;
|
||||
rg1rf = 0.875;
|
||||
rg2rf = 1.0;
|
||||
slizgrf = 1.f;
|
||||
|
||||
fLenL1 = 1.98374;
|
||||
fLenU1 = 2.14199;
|
||||
fHoriz = 0.142; // 0.54555075 przesunięcie ślizgu w długości pojazdu względem
|
||||
// osi obrotu dolnego ramienia
|
||||
fHeight = 0.09353; // wysokość ślizgu ponad oś obrotu
|
||||
fWidth = 0.4969; // połowa szerokości ślizgu
|
||||
fAngleL0 = DegToRad(2.8547285515689267247882521833308);
|
||||
fAngleL = fAngleL0; // początkowy kąt dolnego ramienia
|
||||
// fAngleU0=acos((1.22*cos(fAngleL)+0.535)/1.755); //górne ramię
|
||||
fAngleU0 = acos((fLenL1 * cos(fAngleL) + fHoriz) / fLenU1); // górne ramię
|
||||
fAngleU = fAngleU0; // początkowy kąt
|
||||
// PantWys=1.22*sin(fAngleL)+1.755*sin(fAngleU); //wysokość początkowa
|
||||
PantWys = fLenL1 * sin(fAngleL) + fLenU1 * sin(fAngleU) + fHeight; // wysokość początkowa
|
||||
PantTraction = PantWys;
|
||||
hvPowerWire = NULL;
|
||||
fWidthExtra = 0.381f; //(2.032m-1.027)/2
|
||||
// poza obszarem roboczym jest aproksymacja łamaną o 5 odcinkach
|
||||
fHeightExtra[0] = 0.0f; //+0.0762
|
||||
fHeightExtra[1] = -0.01f; //+0.1524
|
||||
fHeightExtra[2] = -0.03f; //+0.2286
|
||||
fHeightExtra[3] = -0.07f; //+0.3048
|
||||
fHeightExtra[4] = -0.15f; //+0.3810
|
||||
};
|
||||
void TAnimPant::EC160_200()
|
||||
{ // ustawienie wymiarów dla pantografow EC160 lub EC200
|
||||
vPos = Math3D::vector3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów
|
||||
|
||||
// mnozniki animacji ramion dla pantografow EC160 lub EC200
|
||||
rd1rf = 1.f;
|
||||
rd2rf = 0.85;
|
||||
rg1rf = 1.f;
|
||||
rg2rf = 1.f; // 0.833
|
||||
slizgrf = 1.f;
|
||||
|
||||
fLenL1 = 1.98374;
|
||||
fLenU1 = 2.14199;
|
||||
fHoriz = 0.142; // 0.54555075 przesunięcie ślizgu w długości pojazdu względem
|
||||
// osi obrotu dolnego ramienia
|
||||
fHeight = 0.09353; // wysokość ślizgu ponad oś obrotu
|
||||
fWidth = 0.4969; // połowa szerokości ślizgu
|
||||
fAngleL0 = DegToRad(2.8547285515689267247882521833308);
|
||||
fAngleL = fAngleL0; // początkowy kąt dolnego ramienia
|
||||
// fAngleU0=acos((1.22*cos(fAngleL)+0.535)/1.755); //górne ramię
|
||||
fAngleU0 = acos((fLenL1 * cos(fAngleL) + fHoriz) / fLenU1); // górne ramię
|
||||
fAngleU = fAngleU0; // początkowy kąt
|
||||
// PantWys=1.22*sin(fAngleL)+1.755*sin(fAngleU); //wysokość początkowa
|
||||
PantWys = fLenL1 * sin(fAngleL) + fLenU1 * sin(fAngleU) + fHeight; // wysokość początkowa
|
||||
PantTraction = PantWys;
|
||||
hvPowerWire = NULL;
|
||||
fWidthExtra = 0.381f; //(2.032m-1.027)/2
|
||||
// poza obszarem roboczym jest aproksymacja łamaną o 5 odcinkach
|
||||
fHeightExtra[0] = 0.0f; //+0.0762
|
||||
fHeightExtra[1] = -0.01f; //+0.1524
|
||||
fHeightExtra[2] = -0.03f; //+0.2286
|
||||
fHeightExtra[3] = -0.07f; //+0.3048
|
||||
fHeightExtra[4] = -0.15f; //+0.3810
|
||||
};
|
||||
void TAnimPant::DSAx()
|
||||
{ // ustawienie wymiarów dla pantografow z rodziny DSA
|
||||
vPos = Math3D::vector3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów
|
||||
|
||||
// mnozniki animacji ramion dla pantografow z rodziny DSA
|
||||
rd1rf = 1.f;
|
||||
rd2rf = 1.025;
|
||||
rg1rf = 0.875;
|
||||
rg2rf = 1.f;
|
||||
slizgrf = 1.f;
|
||||
|
||||
fLenL1 = 1.98374;
|
||||
fLenU1 = 2.14199;
|
||||
fHoriz = 0.142; // 0.54555075 przesunięcie ślizgu w długości pojazdu względem
|
||||
// osi obrotu dolnego ramienia
|
||||
fHeight = 0.09353; // wysokość ślizgu ponad oś obrotu
|
||||
fWidth = 0.4969; // połowa szerokości ślizgu
|
||||
fAngleL0 = DegToRad(2.8547285515689267247882521833308);
|
||||
fAngleL = fAngleL0; // początkowy kąt dolnego ramienia
|
||||
// fAngleU0=acos((1.22*cos(fAngleL)+0.535)/1.755); //górne ramię
|
||||
fAngleU0 = acos((fLenL1 * cos(fAngleL) + fHoriz) / fLenU1); // górne ramię
|
||||
fAngleU = fAngleU0; // początkowy kąt
|
||||
// PantWys=1.22*sin(fAngleL)+1.755*sin(fAngleU); //wysokość początkowa
|
||||
PantWys = fLenL1 * sin(fAngleL) + fLenU1 * sin(fAngleU) + fHeight; // wysokość początkowa
|
||||
PantTraction = PantWys;
|
||||
hvPowerWire = NULL;
|
||||
fWidthExtra = 0.381f; //(2.032m-1.027)/2
|
||||
// poza obszarem roboczym jest aproksymacja łamaną o 5 odcinkach
|
||||
fHeightExtra[0] = 0.0f; //+0.0762
|
||||
fHeightExtra[1] = -0.01f; //+0.1524
|
||||
fHeightExtra[2] = -0.03f; //+0.2286
|
||||
fHeightExtra[3] = -0.07f; //+0.3048
|
||||
fHeightExtra[4] = -0.15f; //+0.3810
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
int TAnim::TypeSet(int i, int fl)
|
||||
int TAnim::TypeSet(int i, TMoverParameters currentMover, int fl)
|
||||
{ // ustawienie typu animacji i zależnej od niego ilości animowanych submodeli
|
||||
fMaxDist = -1.0; // normalnie nie pokazywać
|
||||
switch (i)
|
||||
@@ -127,7 +229,21 @@ int TAnim::TypeSet(int i, int fl)
|
||||
case 5: // 5-pantograf - 5 submodeli
|
||||
iFlags = 0x055;
|
||||
fParamPants = new TAnimPant();
|
||||
fParamPants->AKP_4E();
|
||||
switch (currentMover.EnginePowerSource.CollectorParameters.PantographType) {
|
||||
case (TPantType::AKP_4E):
|
||||
fParamPants->AKP_4E();
|
||||
break;
|
||||
case(TPantType::DSAx):
|
||||
fParamPants->DSAx();
|
||||
break;
|
||||
case(TPantType::EC160_200):
|
||||
fParamPants->EC160_200();
|
||||
break;
|
||||
case(TPantType::WBL85):
|
||||
fParamPants->WBL85();
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 6:
|
||||
iFlags = 0x068;
|
||||
@@ -576,20 +692,20 @@ void TDynamicObject::UpdateDoorPlug(TAnim *pAnim) {
|
||||
|
||||
void TDynamicObject::UpdatePant(TAnim *pAnim)
|
||||
{ // animacja pantografu - 4 obracane ramiona, ślizg piąty
|
||||
float a, b, c;
|
||||
a = RadToDeg(pAnim->fParamPants->fAngleL - pAnim->fParamPants->fAngleL0);
|
||||
b = RadToDeg(pAnim->fParamPants->fAngleU - pAnim->fParamPants->fAngleU0);
|
||||
c = a + b;
|
||||
if (pAnim->smElement[0])
|
||||
pAnim->smElement[0]->SetRotate(float3(-1, 0, 0), a); // dolne ramię
|
||||
if (pAnim->smElement[1])
|
||||
pAnim->smElement[1]->SetRotate(float3(1, 0, 0), a);
|
||||
if (pAnim->smElement[2])
|
||||
pAnim->smElement[2]->SetRotate(float3(1, 0, 0), c); // górne ramię
|
||||
if (pAnim->smElement[3])
|
||||
pAnim->smElement[3]->SetRotate(float3(-1, 0, 0), c);
|
||||
if (pAnim->smElement[4])
|
||||
pAnim->smElement[4]->SetRotate(float3(-1, 0, 0), b); //ślizg
|
||||
float a, b, c;
|
||||
a = RadToDeg(pAnim->fParamPants->fAngleL - pAnim->fParamPants->fAngleL0);
|
||||
b = RadToDeg(pAnim->fParamPants->fAngleU - pAnim->fParamPants->fAngleU0);
|
||||
c = a + b;
|
||||
if (pAnim->smElement[0])
|
||||
pAnim->smElement[0]->SetRotate(float3(-1, 0, 0), a); // dolne ramie 1
|
||||
if (pAnim->smElement[1])
|
||||
pAnim->smElement[1]->SetRotate(float3(1, 0, 0), a * pAnim->fParamPants->rd2rf); // dolne ramie 2
|
||||
if (pAnim->smElement[2])
|
||||
pAnim->smElement[2]->SetRotate(float3(1, 0, 0), c); // górne ramie 1
|
||||
if (pAnim->smElement[3])
|
||||
pAnim->smElement[3]->SetRotate(float3(-1, 0, 0), c * pAnim->fParamPants->rg2rf); // gorne ramie 2
|
||||
if (pAnim->smElement[4])
|
||||
pAnim->smElement[4]->SetRotate(float3(-1, 0, 0), b * pAnim->fParamPants->slizgrf); // ślizg
|
||||
}
|
||||
|
||||
// doorstep animation, shift
|
||||
@@ -5041,7 +5157,8 @@ TDynamicObject::radius() const {
|
||||
// McZapkie-250202
|
||||
// wczytywanie pliku z danymi multimedialnymi (dzwieki)
|
||||
void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string const &ReplacableSkin ) {
|
||||
|
||||
rTypeName = TypeName;
|
||||
rReplacableSkin = ReplacableSkin;
|
||||
Global.asCurrentDynamicPath = asBaseDir;
|
||||
std::string asFileName = asBaseDir + TypeName + ".mmd";
|
||||
std::string asAnimName;
|
||||
@@ -5142,8 +5259,8 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
if (iAnimType[ANIM_PANTS]) // o ile jakieś pantografy są (a domyślnie są)
|
||||
pants = &pAnimations[k]; // zapamiętanie na potrzeby wyszukania submodeli
|
||||
pAnimations[k].iShift = sm; // przesunięcie do przydzielenia wskaźnika
|
||||
sm += pAnimations[k++].TypeSet(j); // ustawienie typu animacji i zliczanie tablicowanych submodeli
|
||||
}
|
||||
sm += pAnimations[k++].TypeSet(j, *MoverParameters); // ustawienie typu animacji i zliczanie tablicowanych submodeli
|
||||
}
|
||||
if (sm) // o ile są bardziej złożone animacje
|
||||
{
|
||||
pAnimated = new TSubModel *[sm]; // tabela na animowane submodele
|
||||
@@ -7740,9 +7857,9 @@ TDynamicObject::update_shake( double const Timedelta ) {
|
||||
if( iVel > 0.5 ) {
|
||||
// acceleration-driven base shake
|
||||
shakevector += Math3D::vector3(
|
||||
-MoverParameters->AccN * Timedelta * 5.0, // highlight side sway
|
||||
-MoverParameters->AccVert * Timedelta,
|
||||
-MoverParameters->AccSVBased * Timedelta * 1.5); // accent acceleration/deceleration
|
||||
-MoverParameters->AccN * Timedelta * 5.0 * Global.ShakingMultiplierRL, // highlight side sway
|
||||
-MoverParameters->AccVert * Timedelta * Global.ShakingMultiplierUD,
|
||||
-MoverParameters->AccSVBased * Timedelta * 1.5 * Global.ShakingMultiplierBF); // accent acceleration/deceleration
|
||||
}
|
||||
|
||||
auto shake { 1.25 * ShakeSpring.ComputateForces( shakevector, ShakeState.offset ) };
|
||||
|
||||
23
DynObj.h
23
DynObj.h
@@ -103,7 +103,17 @@ class TAnimPant
|
||||
float fWidthExtra; // dodatkowy rozmiar poziomy poza część roboczą (fWidth)
|
||||
float fHeightExtra[5]; //łamana symulująca kształt nabieżnika
|
||||
// double fHorizontal; //Ra 2015-01: położenie drutu względem osi pantografu
|
||||
|
||||
// factory ktore mozna nadpisac z fiza
|
||||
float rd1rf{1.f}; // mnoznik obrotu ramienia dolnego 1
|
||||
float rd2rf{1.f}; // mnoznik obrotu ramienia dolnego 2
|
||||
float rg1rf{1.f}; // mnoznik obrotu ramienia gornego 1
|
||||
float rg2rf{1.f}; // mnoznik obrotu ramienia gornego 2
|
||||
float slizgrf{1.f}; // mnoznik obrotu slizgacza
|
||||
void AKP_4E();
|
||||
void WBL85();
|
||||
void DSAx();
|
||||
void EC160_200();
|
||||
};
|
||||
|
||||
class TAnim
|
||||
@@ -115,8 +125,8 @@ public:
|
||||
// destructor
|
||||
~TAnim();
|
||||
// methods
|
||||
int TypeSet( int i, int fl = 0 ); // ustawienie typu
|
||||
// members
|
||||
int TypeSet(int i, TMoverParameters currentMover, int fl = 0); // ustawienie typu
|
||||
// members
|
||||
union
|
||||
{
|
||||
TSubModel *smAnimated; // animowany submodel (jeśli tylko jeden, np. oś)
|
||||
@@ -209,7 +219,11 @@ public:
|
||||
inline TDynamicObject *PrevConnected() const { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||
inline int NextConnectedNo() const { return MoverParameters->Neighbours[ end::rear ].vehicle_end; }
|
||||
inline int PrevConnectedNo() const { return MoverParameters->Neighbours[ end::front ].vehicle_end; }
|
||||
// double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
|
||||
|
||||
// Dev tools
|
||||
void Reload();
|
||||
|
||||
// double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
|
||||
|
||||
// modele składowe pojazdu
|
||||
TModel3d *mdModel; // model pudła
|
||||
@@ -573,6 +587,9 @@ private:
|
||||
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler ) const;
|
||||
void ABuCheckMyTrack();
|
||||
|
||||
std::string rTypeName; // nazwa typu pojazdu
|
||||
std::string rReplacableSkin; // nazwa tekstury pojazdu
|
||||
|
||||
public:
|
||||
bool DimHeadlights{ false }; // status of the headlight dimming toggle. NOTE: single toggle for all lights is a simplification. TODO: separate per-light switches
|
||||
bool HighBeamLights { false }; // status of the highbeam toggle
|
||||
|
||||
@@ -213,6 +213,15 @@ global_settings::ConfigParse(cParser &Parser) {
|
||||
{
|
||||
Parser.getTokens();
|
||||
Parser >> MultipleLogs;
|
||||
}
|
||||
else if (token == "shakefactor")
|
||||
{
|
||||
Parser.getTokens();
|
||||
Parser >> ShakingMultiplierBF;
|
||||
Parser.getTokens();
|
||||
Parser >> ShakingMultiplierRL;
|
||||
Parser.getTokens();
|
||||
Parser >> ShakingMultiplierUD;
|
||||
}
|
||||
else if (token == "logs.filter")
|
||||
{
|
||||
|
||||
12
Globals.h
12
Globals.h
@@ -16,6 +16,9 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "light.h"
|
||||
#include "utilities.h"
|
||||
#include "motiontelemetry.h"
|
||||
#include "ref/discord-rpc/include/discord_rpc.h"
|
||||
#include <map>
|
||||
|
||||
#ifdef WITH_UART
|
||||
#include "uart.h"
|
||||
#endif
|
||||
@@ -27,6 +30,11 @@ struct global_settings {
|
||||
// members
|
||||
// data items
|
||||
// TODO: take these out of the settings
|
||||
|
||||
/// <summary>
|
||||
/// Mapa z watkami w formacie <std::string nazwa, std::thread watek>
|
||||
/// </summary>
|
||||
std::map<std::string, std::thread> threads = {};
|
||||
bool shiftState{ false }; //m7todo: brzydko
|
||||
bool ctrlState{ false };
|
||||
bool altState{ false };
|
||||
@@ -118,7 +126,9 @@ struct global_settings {
|
||||
glm::ivec2 window_size; // main window size in platform-specific virtual pixels
|
||||
glm::ivec2 cursor_pos; // cursor position in platform-specific virtual pixels
|
||||
glm::ivec2 fb_size; // main window framebuffer size
|
||||
|
||||
float ShakingMultiplierBF {1.f}; // mnożnik bujania kamera przod/tyl
|
||||
float ShakingMultiplierRL {1.f}; // mnożnik bujania kamera lewo/prawo
|
||||
float ShakingMultiplierUD {1.f}; // mnożnik bujania kamera gora/dol
|
||||
float fDistanceFactor{ 1.f }; // baza do przeliczania odległości dla LoD
|
||||
float targetfps{ 0.0f };
|
||||
bool bFullScreen{ false };
|
||||
|
||||
118
Logs.cpp
118
Logs.cpp
@@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "winheaders.h"
|
||||
#include "utilities.h"
|
||||
#include "uilayer.h"
|
||||
#include <deque>
|
||||
|
||||
std::ofstream output; // standardowy "log.txt", można go wyłączyć
|
||||
std::ofstream errors; // lista błędów "errors.txt", zawsze działa
|
||||
@@ -68,61 +69,88 @@ std::string filename_scenery() {
|
||||
}
|
||||
}
|
||||
|
||||
// log service stacks
|
||||
std::deque<char *> InfoStack;
|
||||
std::deque<char *> ErrorStack;
|
||||
|
||||
|
||||
void LogService()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
// loop for logging
|
||||
|
||||
// write logs and log.txt
|
||||
while (!InfoStack.empty())
|
||||
{
|
||||
char *msg = InfoStack.front(); // get first element of stack
|
||||
InfoStack.pop_front();
|
||||
if (Global.iWriteLogEnabled & 1)
|
||||
{
|
||||
if (!output.is_open())
|
||||
{
|
||||
|
||||
std::string const filename = (Global.MultipleLogs ? "logs/log (" + filename_scenery() + ") " + filename_date() + ".txt" : "log.txt");
|
||||
output.open(filename, std::ios::trunc);
|
||||
}
|
||||
output << msg << "\n";
|
||||
output.flush();
|
||||
}
|
||||
|
||||
log_scrollback.emplace_back(std::string(msg));
|
||||
if (log_scrollback.size() > 200)
|
||||
log_scrollback.pop_front();
|
||||
|
||||
if (Global.iWriteLogEnabled & 2)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
|
||||
DWORD wr = 0;
|
||||
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), msg, (DWORD)strlen(msg), &wr, NULL);
|
||||
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), endstring, (DWORD)strlen(endstring), &wr, NULL);
|
||||
#else
|
||||
printf("%s\n", msg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// write to errors.txt
|
||||
while (!ErrorStack.empty())
|
||||
{
|
||||
char *msg = ErrorStack.front();
|
||||
ErrorStack.pop_front();
|
||||
|
||||
if (!(Global.iWriteLogEnabled & 1))
|
||||
return;
|
||||
|
||||
if (!errors.is_open())
|
||||
{
|
||||
|
||||
std::string const filename = (Global.MultipleLogs ? "logs/errors (" + filename_scenery() + ") " + filename_date() + ".txt" : "errors.txt");
|
||||
errors.open(filename, std::ios::trunc);
|
||||
errors << "EU07.EXE " + Global.asVersion << "\n";
|
||||
}
|
||||
|
||||
errors << msg << "\n";
|
||||
errors.flush();
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5)); // dont burn cpu so much
|
||||
}
|
||||
}
|
||||
|
||||
void WriteLog( const char *str, logtype const Type ) {
|
||||
|
||||
if( str == nullptr ) { return; }
|
||||
if( true == TestFlag( Global.DisabledLogTypes, static_cast<unsigned int>( Type ) ) ) { return; }
|
||||
|
||||
if (Global.iWriteLogEnabled & 1) {
|
||||
if( !output.is_open() ) {
|
||||
|
||||
std::string const filename =
|
||||
( Global.MultipleLogs ?
|
||||
"logs/log (" + filename_scenery() + ") " + filename_date() + ".txt" :
|
||||
"log.txt" );
|
||||
output.open( filename, std::ios::trunc );
|
||||
}
|
||||
output << str << "\n";
|
||||
output.flush();
|
||||
}
|
||||
|
||||
log_scrollback.emplace_back(std::string(str));
|
||||
if (log_scrollback.size() > 200)
|
||||
log_scrollback.pop_front();
|
||||
|
||||
if( Global.iWriteLogEnabled & 2 ) {
|
||||
#ifdef _WIN32
|
||||
// hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana
|
||||
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN | FOREGROUND_INTENSITY );
|
||||
DWORD wr = 0;
|
||||
WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), str, (DWORD)strlen( str ), &wr, NULL );
|
||||
WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), endstring, (DWORD)strlen( endstring ), &wr, NULL );
|
||||
#else
|
||||
printf("%s\n", str);
|
||||
#endif
|
||||
}
|
||||
InfoStack.emplace_back(strdup(str));
|
||||
}
|
||||
|
||||
void ErrorLog( const char *str, logtype const Type ) {
|
||||
|
||||
if( str == nullptr ) { return; }
|
||||
if( true == TestFlag( Global.DisabledLogTypes, static_cast<unsigned int>( Type ) ) ) { return; }
|
||||
|
||||
if (!(Global.iWriteLogEnabled & 1))
|
||||
return;
|
||||
|
||||
if (!errors.is_open()) {
|
||||
|
||||
std::string const filename =
|
||||
( Global.MultipleLogs ?
|
||||
"logs/errors (" + filename_scenery() + ") " + filename_date() + ".txt" :
|
||||
"errors.txt" );
|
||||
errors.open( filename, std::ios::trunc );
|
||||
errors << "EU07.EXE " + Global.asVersion << "\n";
|
||||
}
|
||||
|
||||
errors << str << "\n";
|
||||
errors.flush();
|
||||
ErrorStack.emplace_back(strdup(str));
|
||||
};
|
||||
|
||||
void Error(const std::string &asMessage, bool box)
|
||||
|
||||
2
Logs.h
2
Logs.h
@@ -23,7 +23,7 @@ enum class logtype : unsigned int {
|
||||
traction = ( 1 << 9 ),
|
||||
powergrid = ( 1 << 10 ),
|
||||
};
|
||||
|
||||
void LogService();
|
||||
void WriteLog( const char *str, logtype const Type = logtype::generic );
|
||||
void Error( const std::string &asMessage, bool box = false );
|
||||
void Error( const char* &asMessage, bool box = false );
|
||||
|
||||
@@ -469,6 +469,13 @@ struct TBoilerType {
|
||||
//}
|
||||
};
|
||||
/*rodzaj odbieraka pradu*/
|
||||
enum TPantType
|
||||
{
|
||||
AKP_4E,
|
||||
DSAx,
|
||||
EC160_200,
|
||||
WBL85
|
||||
};
|
||||
struct TCurrentCollector {
|
||||
long CollectorsNo; //musi być tu, bo inaczej się kopie
|
||||
double MinH; double MaxH; //zakres ruchu pantografu, nigdzie nie używany
|
||||
@@ -480,6 +487,7 @@ struct TCurrentCollector {
|
||||
double MaxPress; //maksymalne ciśnienie za reduktorem
|
||||
bool FakePower;
|
||||
int PhysicalLayout;
|
||||
TPantType PantographType;
|
||||
//inline TCurrentCollector() {
|
||||
// CollectorsNo = 0;
|
||||
// MinH, MaxH, CSW, MinV, MaxV = 0.0;
|
||||
@@ -1069,6 +1077,8 @@ class TMoverParameters
|
||||
};
|
||||
|
||||
public:
|
||||
std::string chkPath;
|
||||
bool reload_FIZ();
|
||||
double dMoveLen = 0.0;
|
||||
/*---opis lokomotywy, wagonu itp*/
|
||||
/*--opis serii--*/
|
||||
@@ -1138,6 +1148,9 @@ class TMoverParameters
|
||||
int UniversalBrakeButtonFlag[3] = {0, 0, 0}; /* mozliwe działania przycisków hamulcowych */
|
||||
int UniversalResetButtonFlag[3] = {0, 0, 0}; // customizable reset buttons assignments
|
||||
int TurboTest = 0;
|
||||
bool isBatteryButtonImpulse = false; // czy przelacznik baterii traktowac jako pojedynczy przycisk
|
||||
bool shouldHoldBatteryButton = false; // czy nalezy przytrzymac przycisk baterii aby wlaczyc/wylaczyc baterie
|
||||
float BatteryButtonHoldTime = 1.f; // minimalny czas przytrzymania przycisku baterii
|
||||
double MaxBrakeForce = 0.0; /*maksymalna sila nacisku hamulca*/
|
||||
double MaxBrakePress[5]; // pomocniczy, proz, sred, lad, pp
|
||||
double P2FTrans = 0.0;
|
||||
@@ -1213,6 +1226,8 @@ class TMoverParameters
|
||||
double SpringBrakeDriveEmergencyVel{-1};
|
||||
bool HideDirStatusWhenMoving{false}; // Czy gasic lampki kierunku powyzej predkosci zdefiniowanej przez HideDirStatusSpeed
|
||||
int HideDirStatusSpeed{1}; // Predkosc od ktorej lampki kierunku sa wylaczane
|
||||
bool isDoubleClickForMeasureNeeded = {false}; // czy rozpoczecie pomiaru odleglosci odbywa sie po podwojnym wcisnienciu przycisku?
|
||||
float DistanceCounterDoublePressPeriod = {1.f}; // czas w jakim nalezy podwojnie wcisnac przycisk, aby rozpoczac pomiar odleglosci
|
||||
TSecuritySystem SecuritySystem;
|
||||
int EmergencyBrakeWarningSignal{0}; // combined with basic WarningSignal when manual emergency brake is active
|
||||
TUniversalCtrlTable UniCtrlList; /*lista pozycji uniwersalnego nastawnika*/
|
||||
|
||||
@@ -9444,6 +9444,7 @@ void TMoverParameters::BrakeSubsystemDecode()
|
||||
// *************************************************************************************************
|
||||
bool TMoverParameters::LoadFIZ(std::string chkpath)
|
||||
{
|
||||
chkPath = chkpath; // assign class path for reloading
|
||||
const int param_ok = 1;
|
||||
const int wheels_ok = 2;
|
||||
const int dimensions_ok = 4;
|
||||
@@ -10625,6 +10626,12 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
||||
|
||||
extract_value(HideDirStatusWhenMoving, "HideDirStatusWhenMoving", line, "");
|
||||
extract_value(HideDirStatusSpeed, "HideDirStatusSpeed", line, "");
|
||||
extract_value(isDoubleClickForMeasureNeeded, "DCMB", line, "");
|
||||
extract_value(DistanceCounterDoublePressPeriod, "DCDPP", line, "");
|
||||
|
||||
extract_value(isBatteryButtonImpulse, "IBTB", line, "");
|
||||
extract_value(shouldHoldBatteryButton, "SBBBH", line, "");
|
||||
extract_value(BatteryButtonHoldTime, "BBHT", line, "");
|
||||
|
||||
std::map<std::string, start_t> starts {
|
||||
{ "Disabled", start_t::disabled },
|
||||
@@ -11331,6 +11338,17 @@ void TMoverParameters::LoadFIZ_PowerParamsDecode( TPowerParameters &Powerparamet
|
||||
auto &collectorparameters = Powerparameters.CollectorParameters;
|
||||
|
||||
collectorparameters = TCurrentCollector { 0, 0, 0, 0, 0, 0, false, 0, 0, 0, false, 0 };
|
||||
|
||||
std::string PantType = "";
|
||||
extract_value(PantType, "PantType", Line, "");
|
||||
if (PantType == "AKP_4E")
|
||||
collectorparameters.PantographType = TPantType::AKP_4E;
|
||||
if (PantType._Starts_with("DSA")) // zakladam ze wszystkie pantografy DSA sa takie same
|
||||
collectorparameters.PantographType = TPantType::DSAx;
|
||||
if (PantType == "EC160" || PantType == "EC200")
|
||||
collectorparameters.PantographType = TPantType::EC160_200;
|
||||
if (PantType == "WBL85")
|
||||
collectorparameters.PantographType = TPantType::WBL85;
|
||||
|
||||
extract_value( collectorparameters.CollectorsNo, "CollectorsNo", Line, "" );
|
||||
extract_value( collectorparameters.MinH, "MinH", Line, "" );
|
||||
@@ -12467,6 +12485,24 @@ double TMoverParameters::ShowCurrentP(int AmpN) const
|
||||
}
|
||||
}
|
||||
|
||||
bool TMoverParameters::reload_FIZ() {
|
||||
WriteLog("[DEV] Reloading FIZ for " + Name);
|
||||
// pause simulation
|
||||
Global.iPause |= 0b1000;
|
||||
bool result = LoadFIZ(chkPath);
|
||||
if (result == true)
|
||||
{
|
||||
// jesli sie udalo przeladowac FIZ
|
||||
Global.iPause &= 0b0111;
|
||||
WriteLog("[DEV] FIZ reloaded for " + Name);
|
||||
}
|
||||
else {
|
||||
// failed to reload - exit simulator
|
||||
ErrorLog("[DEV] Failed to reload fiz for vehicle " + Name);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace simulation {
|
||||
|
||||
weights_table Weights;
|
||||
|
||||
@@ -40,7 +40,7 @@ Math3D::vector3 TSpring::ComputateForces( Math3D::vector3 const &pPosition1, Mat
|
||||
|
||||
// ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector
|
||||
// ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force
|
||||
springForce = deltaP / dist * ( -( Hterm + Dterm ) );
|
||||
springForce = deltaP / dist * ( -( Hterm + Dterm ));
|
||||
// VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1
|
||||
// VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2
|
||||
}
|
||||
|
||||
278
Train.cpp
278
Train.cpp
@@ -1317,7 +1317,17 @@ void TTrain::OnCommand_distancecounteractivate( TTrain *Train, command_data cons
|
||||
// visual feedback
|
||||
Train->ggDistanceCounterButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
// activate or start anew
|
||||
Train->m_distancecounter = 0.f;
|
||||
if (Train->mvOccupied->isDoubleClickForMeasureNeeded) {
|
||||
// handler tempomatu dla podwojnego kliku
|
||||
if (Train->trainLenghtMeasureTimer >= 0.f) // jesli zdazylismy w czasie sekundy
|
||||
Train->m_distancecounter = 0.f; // rozpoczynamy pomiar
|
||||
else
|
||||
Train->trainLenghtMeasureTimer = Train->mvOccupied->DistanceCounterDoublePressPeriod; // odpalamy zegarek od nowa
|
||||
}
|
||||
else {
|
||||
// dla pojedynczego kliku
|
||||
Train->m_distancecounter = 0.f;
|
||||
}
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
// visual feedback
|
||||
@@ -2388,7 +2398,8 @@ void TTrain::OnCommand_cabsignalacknowledge( TTrain *Train, command_data const &
|
||||
|
||||
void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command )
|
||||
{
|
||||
if( Command.action != GLFW_REPEAT ) {
|
||||
if (Train->allowBatteryToggle || Command.action != GLFW_REPEAT)
|
||||
{
|
||||
// keep the switch from flipping back and forth if key is held down
|
||||
if( false == Train->mvOccupied->Power24vIsAvailable ) {
|
||||
// turn on
|
||||
@@ -2402,44 +2413,160 @@ void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_batteryenable( TTrain *Train, command_data const &Command ) {
|
||||
if (!Train->mvOccupied->isBatteryButtonImpulse)
|
||||
{ // regular button behavior
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOnButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue( 1.0f, Train->dsbSwitch );
|
||||
Train->ggBatteryOnButton.UpdateValue( 1.0f, Train->dsbSwitch );
|
||||
|
||||
Train->mvOccupied->BatterySwitch( true );
|
||||
|
||||
// side-effects
|
||||
if( Train->mvOccupied->LightsPosNo > 0 ) {
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
Train->mvOccupied->BatterySwitch(true);
|
||||
Train->allowBatteryToggle = false;
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
if (Train->ggBatteryButton.type() == TGaugeType::push)
|
||||
{
|
||||
// return the switch to neutral position
|
||||
Train->ggBatteryButton.UpdateValue(0.5f);
|
||||
}
|
||||
Train->ggBatteryOnButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->allowBatteryToggle = true;
|
||||
}
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
if( Train->ggBatteryButton.type() == TGaugeType::push ) {
|
||||
// return the switch to neutral position
|
||||
Train->ggBatteryButton.UpdateValue( 0.5f );
|
||||
else // impulse button behavior
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
if (Train->mvOccupied->shouldHoldBatteryButton)
|
||||
{
|
||||
// jesli przycisk trzeba przytrzymac
|
||||
Train->ggBatteryButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOnButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->fBatteryTimer = Train->mvOccupied->BatteryButtonHoldTime; // start timer
|
||||
}
|
||||
else
|
||||
{
|
||||
// jesli przycisk dziala od razu
|
||||
Train->mvOccupied->BatterySwitch(true);
|
||||
Train->allowBatteryToggle = false;
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOnButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
Train->ggBatteryOnButton.UpdateValue( 0.0f, Train->dsbSwitch );
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOnButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->fBatteryTimer = -1.f; //
|
||||
Train->allowBatteryToggle = true;
|
||||
}
|
||||
else if (Command.action == GLFW_REPEAT && Train->mvOccupied->shouldHoldBatteryButton)
|
||||
{
|
||||
// trzymamy przycisk
|
||||
if (Train->fBatteryTimer <= 0.0 && Train->mvOccupied->Battery == false) {
|
||||
Train->mvOccupied->BatterySwitch(true);
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
Train->allowBatteryToggle = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_batterydisable( TTrain *Train, command_data const &Command ) {
|
||||
// TBD, TODO: ewentualnie zablokować z FIZ, np. w samochodach się nie odłącza akumulatora
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue( 0.0f, Train->dsbSwitch );
|
||||
Train->ggBatteryOffButton.UpdateValue( 1.0f, Train->dsbSwitch );
|
||||
if (!Train->mvOccupied->isBatteryButtonImpulse)
|
||||
{ // regular button behavior
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOffButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
|
||||
Train->mvOccupied->BatterySwitch( false );
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
if( Train->ggBatteryButton.type() == TGaugeType::push ) {
|
||||
// return the switch to neutral position
|
||||
Train->ggBatteryButton.UpdateValue( 0.5f );
|
||||
}
|
||||
Train->ggBatteryOffButton.UpdateValue( 0.0f, Train->dsbSwitch );
|
||||
}
|
||||
Train->mvOccupied->BatterySwitch(false);
|
||||
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
if (Train->ggBatteryButton.type() == TGaugeType::push)
|
||||
{
|
||||
// return the switch to neutral position
|
||||
Train->ggBatteryButton.UpdateValue(0.5f);
|
||||
}
|
||||
Train->ggBatteryOffButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else // impulse button behavior
|
||||
{
|
||||
if (Command.action == GLFW_PRESS)
|
||||
{
|
||||
if (Train->mvOccupied->shouldHoldBatteryButton)
|
||||
{
|
||||
// jesli przycisk trzeba przytrzymac
|
||||
Train->ggBatteryButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOffButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->fBatteryTimer = Train->mvOccupied->BatteryButtonHoldTime; // start timer
|
||||
}
|
||||
else
|
||||
{
|
||||
// jesli przycisk dziala od razu
|
||||
Train->mvOccupied->BatterySwitch(false);
|
||||
Train->allowBatteryToggle = false;
|
||||
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOffButton.UpdateValue(1.0f, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if (Command.action == GLFW_RELEASE)
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggBatteryButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->ggBatteryOffButton.UpdateValue(0.0f, Train->dsbSwitch);
|
||||
Train->allowBatteryToggle = true;
|
||||
}
|
||||
else if (Command.action == GLFW_REPEAT && Train->mvOccupied->shouldHoldBatteryButton)
|
||||
{
|
||||
// trzymamy przycisk
|
||||
if (Train->fBatteryTimer <= 0.0 && Train->mvOccupied->Battery == true) {
|
||||
Train->mvOccupied->BatterySwitch(false);
|
||||
Train->allowBatteryToggle = false;
|
||||
// side-effects
|
||||
if (Train->mvOccupied->LightsPosNo > 0)
|
||||
{
|
||||
Train->Dynamic()->SetLights();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_cabactivationtoggle(TTrain *Train, command_data const &Command) {
|
||||
@@ -2848,23 +2975,43 @@ void TTrain::change_pantograph_selection( int const Change ) {
|
||||
|
||||
void TTrain::OnCommand_pantographvalvesupdate( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
bool hasSeparateSwitches = Train->m_controlmapper.contains("pantvalvesupdate_bt:") &&
|
||||
Train->m_controlmapper.contains("pantvalvesoff_bt:");
|
||||
|
||||
if( Command.action == GLFW_REPEAT ) { return; }
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// implement action
|
||||
Train->update_pantograph_valves();
|
||||
// visual feedback
|
||||
Train->ggPantValvesButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
if (hasSeparateSwitches)
|
||||
{
|
||||
// implement action
|
||||
Train->update_pantograph_valves();
|
||||
// visual feedback
|
||||
Train->ggPantValvesUpdate.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
|
||||
// Old logic to maintain compatibility
|
||||
else
|
||||
{
|
||||
Train->update_pantograph_valves();
|
||||
Train->ggPantValvesButton.UpdateValue(1.0, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
// visual feedback
|
||||
// NOTE: pantvalves_sw: is a specialized button, with no toggle behavior support
|
||||
Train->ggPantValvesButton.UpdateValue( 0.5, Train->dsbSwitch );
|
||||
if (hasSeparateSwitches)
|
||||
Train->ggPantValvesUpdate.UpdateValue(0.5, Train->dsbSwitch);
|
||||
|
||||
// Old logic to maintain compatibility
|
||||
else
|
||||
Train->ggPantValvesButton.UpdateValue(0.5, Train->dsbSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_pantographvalvesoff( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
bool hasSeparateSwitches = Train->m_controlmapper.contains("pantvalvesupdate_bt:") && Train->m_controlmapper.contains("pantvalvesoff_bt:");
|
||||
|
||||
if( Command.action == GLFW_REPEAT ) { return; }
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
@@ -2872,12 +3019,18 @@ void TTrain::OnCommand_pantographvalvesoff( TTrain *Train, command_data const &C
|
||||
Train->mvOccupied->OperatePantographValve( end::front, operation_t::disable );
|
||||
Train->mvOccupied->OperatePantographValve( end::rear, operation_t::disable );
|
||||
// visual feedback
|
||||
Train->ggPantValvesButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
if (hasSeparateSwitches)
|
||||
Train->ggPantValvesOff.UpdateValue(1.0, Train->dsbSwitch);
|
||||
else
|
||||
Train->ggPantValvesButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
// visual feedback
|
||||
// NOTE: pantvalves_sw: is a specialized button, with no toggle behavior support
|
||||
Train->ggPantValvesButton.UpdateValue( 0.5, Train->dsbSwitch );
|
||||
// NOTE: pantvalves_sw: is a speciali zed button, with no toggle behavior support
|
||||
if (hasSeparateSwitches)
|
||||
Train->ggPantValvesOff.UpdateValue(0.f, Train->dsbSwitch);
|
||||
else
|
||||
Train->ggPantValvesButton.UpdateValue( 0.5, Train->dsbSwitch );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6926,6 +7079,21 @@ bool TTrain::Update( double const Deltatime )
|
||||
mvOccupied->OperateDoors( static_cast<side>( idx ), true );
|
||||
}
|
||||
}
|
||||
|
||||
// train measurement timer
|
||||
if (trainLenghtMeasureTimer >= 0.f) {
|
||||
trainLenghtMeasureTimer -= Deltatime;
|
||||
if (trainLenghtMeasureTimer < 0.f)
|
||||
trainLenghtMeasureTimer = -1.f;
|
||||
}
|
||||
|
||||
// battery timer
|
||||
if (fBatteryTimer >= 0.f) {
|
||||
fBatteryTimer -= Deltatime;
|
||||
if (fBatteryTimer < 0.f)
|
||||
fBatteryTimer = -1.f;
|
||||
}
|
||||
|
||||
// helper variables
|
||||
if( DynamicObject->Mechanik != nullptr ) {
|
||||
m_doors = (
|
||||
@@ -7435,6 +7603,12 @@ bool TTrain::Update( double const Deltatime )
|
||||
else
|
||||
btCompressors.Turn(false);
|
||||
|
||||
// Lampka zezwolenia na hamowanie ED
|
||||
if (mvControlled->EpFuse)
|
||||
btEDenabled.Turn(true);
|
||||
else
|
||||
btEDenabled.Turn(false);
|
||||
|
||||
// Lampka aktywowanej kabiny
|
||||
if (mvControlled->CabActive != 0) {
|
||||
btCabActived.Turn(true);
|
||||
@@ -7448,6 +7622,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
else
|
||||
btAKLVents.Turn(false);
|
||||
|
||||
|
||||
if( true == lowvoltagepower ) {
|
||||
// McZapkie-141102: SHP i czuwak, TODO: sygnalizacja kabinowa
|
||||
if( mvOccupied->SecuritySystem.is_vigilance_blinking() ) {
|
||||
@@ -8079,6 +8254,9 @@ bool TTrain::Update( double const Deltatime )
|
||||
ggPantCompressorButton.Update();
|
||||
ggPantCompressorValve.Update();
|
||||
|
||||
ggPantValvesOff.Update();
|
||||
ggPantValvesUpdate.Update();
|
||||
|
||||
ggLightsButton.Update();
|
||||
ggUpperLightButton.Update();
|
||||
ggLeftLightButton.Update();
|
||||
@@ -9572,6 +9750,10 @@ void TTrain::clear_cab_controls()
|
||||
ggPantValvesButton.Clear();
|
||||
ggPantCompressorButton.Clear();
|
||||
ggPantCompressorValve.Clear();
|
||||
|
||||
ggPantValvesOff.Clear();
|
||||
ggPantValvesUpdate.Clear();
|
||||
|
||||
ggI1B.Clear();
|
||||
ggI2B.Clear();
|
||||
ggI3B.Clear();
|
||||
@@ -9723,6 +9905,16 @@ void TTrain::set_cab_controls( int const Cab ) {
|
||||
ggModernLightDimSw.PutValue(mvOccupied->modernDimmerState - 1);
|
||||
}
|
||||
|
||||
// Init separate buttons
|
||||
if (ggPantValvesUpdate.SubModel != nullptr)
|
||||
{
|
||||
ggPantValvesUpdate.PutValue(0.f);
|
||||
}
|
||||
if (ggPantValvesOff.SubModel != nullptr)
|
||||
{
|
||||
ggPantValvesOff.PutValue(0.f);
|
||||
}
|
||||
|
||||
// motor connectors
|
||||
ggStLinOffButton.PutValue(
|
||||
( mvControlled->StLinSwitchOff ?
|
||||
@@ -9781,6 +9973,7 @@ void TTrain::set_cab_controls( int const Cab ) {
|
||||
0.f ) );
|
||||
}
|
||||
ggPantValvesButton.PutValue( 0.5f );
|
||||
|
||||
// auxiliary compressor
|
||||
ggPantCompressorValve.PutValue(
|
||||
mvControlled->bPantKurek3 ?
|
||||
@@ -10164,7 +10357,8 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
{ "i-universal9:", btUniversals[ 9 ] },
|
||||
{ "i-cabactived:", btCabActived },
|
||||
{"i-aklvents:", btAKLVents},
|
||||
{"i-compressorany:", btCompressors }
|
||||
{"i-compressorany:", btCompressors },
|
||||
{"i-edenabled", btEDenabled },
|
||||
};
|
||||
{
|
||||
auto lookup = lights.find( Label );
|
||||
@@ -10396,6 +10590,8 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "invertertoggle10_bt:", ggInverterToggleButtons[9] },
|
||||
{ "invertertoggle11_bt:", ggInverterToggleButtons[10] },
|
||||
{ "invertertoggle12_bt:", ggInverterToggleButtons[11] },
|
||||
{"pantvalvesupdate_bt:", ggPantValvesUpdate},
|
||||
{"pantvalvesoff_bt:", ggPantValvesOff}
|
||||
};
|
||||
{
|
||||
auto const lookup { gauges.find( Label ) };
|
||||
|
||||
6
Train.h
6
Train.h
@@ -663,6 +663,8 @@ public: // reszta może by?publiczna
|
||||
TGauge ggPantValvesButton;
|
||||
TGauge ggPantCompressorButton;
|
||||
TGauge ggPantCompressorValve;
|
||||
TGauge ggPantValvesUpdate;
|
||||
TGauge ggPantValvesOff;
|
||||
// Winger 020304 - wlacznik ogrzewania
|
||||
TGauge ggTrainHeatingButton;
|
||||
TGauge ggSignallingButton;
|
||||
@@ -777,6 +779,7 @@ public: // reszta może by?publiczna
|
||||
TButton btCabActived;
|
||||
TButton btAKLVents;
|
||||
TButton btCompressors; // lampka pracy jakiejkolwiek sprezarki
|
||||
TButton btEDenabled; // czy wlaczony jest hamulec ED (czy dostepny)
|
||||
// other
|
||||
TButton btLampkaMalfunction;
|
||||
TButton btLampkaMalfunctionB;
|
||||
@@ -840,6 +843,8 @@ private:
|
||||
float fHaslerTimer;
|
||||
float fConverterTimer; // hunter-261211: dla przekaznika
|
||||
float fMainRelayTimer; // hunter-141211: zalaczanie WSa z opoznieniem
|
||||
float fBatteryTimer = {-1.f}; // Hirek: zalaczanie baterii z opoznieniem (tylko gdy zdefiniowano takie zachowanie w fiz)
|
||||
bool allowBatteryToggle = true; // Hirek: zabezpieczenie przed przelaczaniem bateri on/off
|
||||
int ScreenUpdateRate { 0 }; // vehicle specific python screen update rate override
|
||||
|
||||
// McZapkie-240302 - przyda sie do tachometru
|
||||
@@ -882,6 +887,7 @@ private:
|
||||
bool m_dirbackward{ false }; // helper, true if direction set to backward
|
||||
bool m_doorpermits{ false }; // helper, true if any door permit is active
|
||||
float m_doorpermittimers[2] = { -1.f, -1.f };
|
||||
float trainLenghtMeasureTimer = { -1.f };
|
||||
// ld substitute
|
||||
bool m_couplingdisconnect { false };
|
||||
bool m_couplingdisconnectback { false };
|
||||
|
||||
@@ -29,6 +29,9 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Timer.h"
|
||||
#include "dictionary.h"
|
||||
#include "version_info.h"
|
||||
#include "ref/discord-rpc/include/discord_rpc.h"
|
||||
#include <chrono>
|
||||
#include "translation.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma comment (lib, "dsound.lib")
|
||||
@@ -174,6 +177,83 @@ int eu07_application::run_crashgui()
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
void eu07_application::DiscordRPCService()
|
||||
{
|
||||
// initialize discord-rpc
|
||||
WriteLog("Initializing Discord Rich Presence...");
|
||||
static const char *discord_app_id = "1343662664504840222";
|
||||
DiscordEventHandlers handlers;
|
||||
memset(&handlers, 0, sizeof(handlers));
|
||||
Discord_Initialize(discord_app_id, &handlers, 1, nullptr);
|
||||
|
||||
std::string rpcScnName = Global.SceneryFile;
|
||||
if (rpcScnName[0] == '$')
|
||||
rpcScnName.erase(0, 1);
|
||||
rpcScnName.erase(rpcScnName.size() - 4, 4);
|
||||
if (rpcScnName.find('_') != std::string::npos)
|
||||
{
|
||||
std::replace(rpcScnName.begin(), rpcScnName.end(), '_', ' ');
|
||||
}
|
||||
|
||||
// calculate startup timestamp
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto now_c = std::chrono::system_clock::to_time_t(now);
|
||||
|
||||
// Init RPC object
|
||||
static DiscordRichPresence discord_rpc;
|
||||
memset(&discord_rpc, 0, sizeof(discord_rpc));
|
||||
// realworld timestamp from datetime
|
||||
discord_rpc.startTimestamp = static_cast<int64_t>(now_c);
|
||||
static std::string state = Translations.lookup_s("Scenery: ") + rpcScnName;
|
||||
discord_rpc.state = state.c_str();
|
||||
discord_rpc.details = Translations.lookup_c("Loading scenery...");
|
||||
discord_rpc.largeImageKey = "logo";
|
||||
discord_rpc.largeImageText = "MaSzyna";
|
||||
|
||||
// First RPC upload
|
||||
Discord_UpdatePresence(&discord_rpc);
|
||||
|
||||
// run loop
|
||||
while (!glfwWindowShouldClose(m_windows.front()) && !m_modestack.empty())
|
||||
{
|
||||
// Discord RPC updater
|
||||
if (simulation::is_ready)
|
||||
{
|
||||
std::string PlayerVehicle;
|
||||
if (simulation::Train != nullptr)
|
||||
{
|
||||
PlayerVehicle = simulation::Train->name();
|
||||
// make to upper
|
||||
for (auto &c : PlayerVehicle)
|
||||
c = toupper(c);
|
||||
|
||||
PlayerVehicle = Translations.lookup_s("Driving: ") + PlayerVehicle;
|
||||
discord_rpc.details = PlayerVehicle.c_str();
|
||||
|
||||
uint16_t playerTrainVelocity = simulation::Train->Dynamic()->GetVelocity();
|
||||
if (playerTrainVelocity > 1)
|
||||
{
|
||||
// ikonka ze jedziemy i nie spimy
|
||||
discord_rpc.smallImageKey = "driving";
|
||||
std::string smallText = Translations.lookup_s("Speed: ") + std::to_string(playerTrainVelocity) + " km/h";
|
||||
discord_rpc.smallImageText = smallText.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
// krecimy postoj
|
||||
discord_rpc.smallImageKey = "halt";
|
||||
discord_rpc.smallImageText = Translations.lookup_c("Stopped");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Discord_UpdatePresence(&discord_rpc);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(5000)); // update RPC every 5 secs
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
eu07_application::init( int Argc, char *Argv[] ) {
|
||||
@@ -186,6 +266,10 @@ eu07_application::init( int Argc, char *Argv[] ) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// start logging service
|
||||
std::thread sLoggingService(LogService);
|
||||
Global.threads.emplace("LogService", std::move(sLoggingService));
|
||||
|
||||
WriteLog( "Starting MaSzyna rail vehicle simulator (release: " + Global.asVersion + ")" );
|
||||
WriteLog( "For online documentation and additional files refer to: http://eu07.pl" );
|
||||
WriteLog( "Authors: Marcin_EU, McZapkie, ABu, Winger, Tolaris, nbmx, OLO_EU, Bart, Quark-t, "
|
||||
@@ -239,9 +323,15 @@ eu07_application::init( int Argc, char *Argv[] ) {
|
||||
if (!init_network())
|
||||
return -1;
|
||||
|
||||
// Run DiscordRPC service
|
||||
std::thread sDiscordRPC(&eu07_application::DiscordRPCService, this);
|
||||
Global.threads.emplace("DiscordRPC", std::move(sDiscordRPC));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double eu07_application::generate_sync() {
|
||||
if (Timer::GetDeltaTime() == 0.0)
|
||||
return 0.0;
|
||||
@@ -433,7 +523,8 @@ eu07_application::run() {
|
||||
std::this_thread::sleep_for( Global.minframetime - frametime );
|
||||
}
|
||||
}
|
||||
|
||||
Global.threads["LogService"].~thread(); // kill log service
|
||||
Global.threads["DiscordRPC"].~thread(); // kill DiscordRPC service
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ public:
|
||||
int
|
||||
run();
|
||||
// issues request for a worker thread to perform specified task. returns: true if task was scheduled
|
||||
|
||||
void eu07_application::DiscordRPCService(); // discord rich presence service function (runs as separate thread)
|
||||
bool
|
||||
request( python_taskqueue::task_request const &Task );
|
||||
// ensures the main thread holds the python gil and can safely execute python calls
|
||||
|
||||
@@ -3,10 +3,10 @@ image: Visual Studio 2017
|
||||
clone_depth: 1
|
||||
build_script:
|
||||
- ps: >-
|
||||
git submodule update --init --recursive
|
||||
|
||||
cd ref
|
||||
|
||||
git clone "https://github.com/chriskohlhoff/asio" --depth 1 --branch asio-1-16-1 -q
|
||||
|
||||
|
||||
curl -o crashpad86.zip "http://get.backtrace.io/crashpad/builds/release/x86/crashpad-2020-07-01-release-x86-558c9614e3819179f30b92541450f5ac643afce5.zip"
|
||||
|
||||
7z x crashpad86.zip
|
||||
|
||||
@@ -854,6 +854,12 @@ drivermouse_input::default_bindings() {
|
||||
{ "pantvalves_sw:", {
|
||||
user_command::pantographvalvesupdate,
|
||||
user_command::pantographvalvesoff } },
|
||||
{ "pantvalvesupdate_bt:", {
|
||||
user_command::pantographvalvesupdate,
|
||||
user_command::none}},
|
||||
{ "pantvalvesoff_bt:", {
|
||||
user_command::pantographvalvesoff,
|
||||
user_command::none}},
|
||||
{ "pantcompressor_sw:", {
|
||||
user_command::pantographcompressoractivate,
|
||||
user_command::none } },
|
||||
|
||||
@@ -620,8 +620,9 @@ debug_panel::render() {
|
||||
ImGui::Checkbox( "Debug Traction", &DebugTractionFlag );
|
||||
}
|
||||
render_section( "Camera", m_cameralines );
|
||||
render_section( "Gfx Renderer", m_rendererlines );
|
||||
render_section( "Gfx Renderer / Statistics", m_rendererlines );
|
||||
render_section_settings();
|
||||
render_section_developer(); // Developer tools
|
||||
#ifdef WITH_UART
|
||||
if(true == render_section( "UART", m_uartlines)) {
|
||||
int ports_num = UartStatus.available_ports.size();
|
||||
@@ -1469,6 +1470,14 @@ debug_panel::update_section_renderer( std::vector<text_line> &Output ) {
|
||||
// renderer stats
|
||||
Output.emplace_back( GfxRenderer->info_times(), Global.UITextColor );
|
||||
Output.emplace_back( GfxRenderer->info_stats(), Global.UITextColor );
|
||||
|
||||
// CPU related
|
||||
Output.emplace_back("CPU:", Global.UITextColor);
|
||||
|
||||
// thread counter
|
||||
textline = "Running threads: " + std::to_string(Global.threads.size() + 1);
|
||||
Output.emplace_back(textline, Global.UITextColor);
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -1492,6 +1501,19 @@ debug_panel::render_section( std::vector<text_line> const &Lines ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool debug_panel::render_section_developer()
|
||||
{
|
||||
if (false == ImGui::CollapsingHeader("Developer tools"))
|
||||
return false;
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, {Global.UITextColor.r, Global.UITextColor.g, Global.UITextColor.b, Global.UITextColor.a});
|
||||
ImGui::TextUnformatted("Warning! These tools are only for developers.\nDo not use them if you are NOT sure what they do!");
|
||||
ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "These settings may crash your simulator!");
|
||||
if (ImGui::Button("Reload current vehicle .fiz") == true)
|
||||
{
|
||||
m_input.vehicle->MoverParameters->reload_FIZ(); // reload fiz
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
debug_panel::render_section_settings() {
|
||||
|
||||
|
||||
@@ -104,7 +104,8 @@ private:
|
||||
bool render_section_uart();
|
||||
#endif
|
||||
bool render_section_settings();
|
||||
// members
|
||||
bool render_section_developer();
|
||||
// members
|
||||
std::array<char, 1024> m_buffer;
|
||||
std::array<char, 128> m_eventsearch;
|
||||
input_data m_input;
|
||||
|
||||
@@ -206,7 +206,7 @@ editor_mode::on_key( int const Key, int const Scancode, int const Action, int co
|
||||
|
||||
m_node = nullptr;
|
||||
m_dragging = false;
|
||||
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
//Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
static_cast<editor_ui*>( m_userinterface.get() )->set_node(nullptr);
|
||||
|
||||
simulation::State.delete_model(model);
|
||||
@@ -318,10 +318,14 @@ editor_mode::on_mouse_button( int const Button, int const Action, int const Mods
|
||||
if( Action == GLFW_PRESS ) {
|
||||
// left button press
|
||||
auto const mode = static_cast<editor_ui*>( m_userinterface.get() )->mode();
|
||||
auto const rotation_mode = static_cast<editor_ui*>( m_userinterface.get() )->rot_mode();
|
||||
auto const fixed_rotation_value =
|
||||
static_cast<editor_ui *>(m_userinterface.get())->rot_val();
|
||||
|
||||
m_node = nullptr;
|
||||
|
||||
GfxRenderer->Pick_Node_Callback([this, mode,Action,Button](scene::basic_node *node) {
|
||||
GfxRenderer->Pick_Node_Callback([this, mode, rotation_mode, fixed_rotation_value,
|
||||
Action, Button](scene::basic_node *node) {
|
||||
editor_ui *ui = static_cast<editor_ui *>(m_userinterface.get());
|
||||
|
||||
if (mode == nodebank_panel::MODIFY) {
|
||||
@@ -329,10 +333,10 @@ editor_mode::on_mouse_button( int const Button, int const Action, int const Mods
|
||||
return;
|
||||
|
||||
m_node = node;
|
||||
if( m_node )
|
||||
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
else
|
||||
m_dragging = false;
|
||||
//if( m_node )
|
||||
//Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
//else
|
||||
//m_dragging = false;
|
||||
ui->set_node(m_node);
|
||||
}
|
||||
else if (mode == nodebank_panel::COPY) {
|
||||
@@ -360,8 +364,24 @@ editor_mode::on_mouse_button( int const Button, int const Action, int const Mods
|
||||
if (!m_dragging)
|
||||
return;
|
||||
|
||||
m_node = cloned;
|
||||
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
|
||||
m_node = cloned;
|
||||
|
||||
if (rotation_mode == functions_panel::RANDOM)
|
||||
{
|
||||
auto const rotation{glm::vec3{0, LocalRandom(0.0, 360.0), 0}};
|
||||
|
||||
m_editor.rotate(m_node, rotation, 1);
|
||||
}
|
||||
else if (rotation_mode == functions_panel::FIXED)
|
||||
{
|
||||
|
||||
auto const rotation{glm::vec3{0, fixed_rotation_value, 0}};
|
||||
|
||||
m_editor.rotate(m_node, rotation, 0);
|
||||
|
||||
}
|
||||
//Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
ui->set_node( m_node );
|
||||
}
|
||||
});
|
||||
@@ -370,8 +390,8 @@ editor_mode::on_mouse_button( int const Button, int const Action, int const Mods
|
||||
}
|
||||
else {
|
||||
// left button release
|
||||
if( m_node )
|
||||
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
//if( m_node )
|
||||
//Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||
m_dragging = false;
|
||||
// prime history stack for another snapshot
|
||||
m_takesnapshot = true;
|
||||
|
||||
@@ -21,6 +21,7 @@ editor_ui::editor_ui() {
|
||||
|
||||
add_external_panel( &m_itempropertiespanel );
|
||||
add_external_panel( &m_nodebankpanel );
|
||||
add_external_panel( &m_functionspanel );
|
||||
}
|
||||
|
||||
// updates state of UI elements
|
||||
@@ -41,6 +42,7 @@ editor_ui::update() {
|
||||
|
||||
ui_layer::update();
|
||||
m_itempropertiespanel.update( m_node );
|
||||
m_functionspanel.update( m_node );
|
||||
}
|
||||
|
||||
void
|
||||
@@ -63,3 +65,17 @@ nodebank_panel::edit_mode
|
||||
editor_ui::mode() {
|
||||
return m_nodebankpanel.mode;
|
||||
}
|
||||
|
||||
functions_panel::rotation_mode
|
||||
editor_ui::rot_mode() {
|
||||
return m_functionspanel.rot_mode;
|
||||
}
|
||||
float
|
||||
editor_ui::rot_val() {
|
||||
return m_functionspanel.rot_value;
|
||||
}
|
||||
bool
|
||||
editor_ui::rot_from_last()
|
||||
{
|
||||
return m_functionspanel.rot_from_last;
|
||||
}
|
||||
@@ -31,6 +31,12 @@ public:
|
||||
set_node( scene::basic_node * Node );
|
||||
void
|
||||
add_node_template(const std::string &desc);
|
||||
float
|
||||
rot_val();
|
||||
bool
|
||||
rot_from_last();
|
||||
functions_panel::rotation_mode
|
||||
rot_mode();
|
||||
const std::string *
|
||||
get_active_node_template();
|
||||
nodebank_panel::edit_mode
|
||||
@@ -39,6 +45,7 @@ public:
|
||||
private:
|
||||
// members
|
||||
itemproperties_panel m_itempropertiespanel { "Node Properties", true };
|
||||
functions_panel m_functionspanel { "Functions", true };
|
||||
nodebank_panel m_nodebankpanel{ "Node Bank", true };
|
||||
scene::basic_node * m_node { nullptr }; // currently bound scene node, if any
|
||||
};
|
||||
|
||||
@@ -420,8 +420,6 @@ nodebank_panel::render() {
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("Insert from bank", (int*)&mode, ADD);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("Brush", (int*)&mode, BRUSH);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton( "Copy to bank", (int*)&mode, COPY );
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Reload Nodebank"))
|
||||
@@ -493,3 +491,64 @@ nodebank_panel::generate_node_label( std::string Input ) const {
|
||||
model :
|
||||
model + " (" + texture + ")" );
|
||||
}
|
||||
|
||||
void functions_panel::update(scene::basic_node const *Node)
|
||||
{
|
||||
m_node = Node;
|
||||
|
||||
if (false == is_open)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
text_lines.clear();
|
||||
m_grouplines.clear();
|
||||
|
||||
std::string textline;
|
||||
|
||||
// scenario inspector
|
||||
auto const *node{Node};
|
||||
auto const &camera{Global.pCamera};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
functions_panel::render() {
|
||||
|
||||
if( false == is_open ) { return; }
|
||||
|
||||
auto flags =
|
||||
ImGuiWindowFlags_NoFocusOnAppearing
|
||||
| ImGuiWindowFlags_NoCollapse
|
||||
| ( size.x > 0 ? ImGuiWindowFlags_NoResize : 0 );
|
||||
|
||||
if( size.x > 0 ) {
|
||||
ImGui::SetNextWindowSize( ImVec2S( size.x, size.y ) );
|
||||
}
|
||||
if( size_min.x > 0 ) {
|
||||
ImGui::SetNextWindowSizeConstraints( ImVec2S( size_min.x, size_min.y ), ImVec2( size_max.x, size_max.y ) );
|
||||
}
|
||||
auto const panelname { (
|
||||
title.empty() ?
|
||||
m_name :
|
||||
title )
|
||||
+ "###" + m_name };
|
||||
if( true == ImGui::Begin( panelname.c_str(), nullptr, flags ) ) {
|
||||
// header section
|
||||
|
||||
ImGui::RadioButton("Random rotation", (int *)&rot_mode, RANDOM);
|
||||
ImGui::RadioButton("Fixed rotation", (int *)&rot_mode, FIXED);
|
||||
if(rot_mode == FIXED){
|
||||
//ImGui::Checkbox("Get rotation from last object", &rot_from_last);
|
||||
ImGui::SliderFloat("Rotation Value", &rot_value, 0.0f, 360.0f, "%.1f");
|
||||
};
|
||||
ImGui::RadioButton("Default rotation", (int *)&rot_mode, DEFAULT);
|
||||
for( auto const &line : text_lines ) {
|
||||
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
@@ -73,3 +73,35 @@ private:
|
||||
char m_nodesearch[ 128 ];
|
||||
std::shared_ptr<std::string> m_selectedtemplate;
|
||||
};
|
||||
|
||||
class functions_panel : public ui_panel
|
||||
{
|
||||
|
||||
public:
|
||||
enum rotation_mode
|
||||
{
|
||||
RANDOM,
|
||||
FIXED,
|
||||
DEFAULT
|
||||
};
|
||||
rotation_mode rot_mode = DEFAULT;
|
||||
|
||||
float rot_value = 0.0f;
|
||||
bool rot_from_last = false;
|
||||
|
||||
functions_panel(std::string const &Name, bool const Isopen) : ui_panel(Name, Isopen) {}
|
||||
|
||||
void update(scene::basic_node const *Node);
|
||||
void render() override;
|
||||
|
||||
|
||||
private:
|
||||
// methods
|
||||
|
||||
|
||||
// members
|
||||
scene::basic_node const *m_node{nullptr}; // scene node bound to the panel
|
||||
scene::group_handle m_grouphandle{null_handle}; // scene group bound to the panel
|
||||
std::string m_groupprefix;
|
||||
std::vector<text_line> m_grouplines;
|
||||
};
|
||||
1
ref/discord-rpc
Submodule
1
ref/discord-rpc
Submodule
Submodule ref/discord-rpc added at 963aa9f3e5
2
thread_list.txt
Normal file
2
thread_list.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
- DiscordRPC - Thread for refreshing discord rich presence
|
||||
- LogService - Service that logs data to files and console
|
||||
@@ -283,6 +283,8 @@ std::string locale::label_cab_control(std::string const &Label)
|
||||
{ "pantselectedoff_sw:", STRN("selected pantograph") },
|
||||
{ "pantselect_sw:", STRN("selected pantograph") },
|
||||
{ "pantvalves_sw:", STRN("selected pantograph") },
|
||||
{ "pantvalvesoff_bt:", STRN("all pantographs down") },
|
||||
{ "pantvalvesupdate_bt:", STRN("selected pantographs up") },
|
||||
{ "pantcompressor_sw:", STRN("pantograph compressor") },
|
||||
{ "pantcompressorvalve_sw:", STRN("pantograph 3 way valve") },
|
||||
{ "trainheating_sw:", STRN("heating") },
|
||||
|
||||
Reference in New Issue
Block a user