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

Merge branch 'tmj-dev' into nogfx

This commit is contained in:
milek7
2017-08-31 21:29:44 +02:00
29 changed files with 1769 additions and 1681 deletions

View File

@@ -42,9 +42,9 @@ void TAirCoupler::Init(std::string const &asName, TModel3d *pModel)
{ // wyszukanie submodeli { // wyszukanie submodeli
if (!pModel) if (!pModel)
return; // nie ma w czym szukać return; // nie ma w czym szukać
pModelOn = pModel->GetFromName( (asName + "_on").c_str() ); // połączony na wprost pModelOn = pModel->GetFromName( asName + "_on" ); // połączony na wprost
pModelOff = pModel->GetFromName( (asName + "_off").c_str() ); // odwieszony pModelOff = pModel->GetFromName( asName + "_off" ); // odwieszony
pModelxOn = pModel->GetFromName( (asName + "_xon").c_str() ); // połączony na skos pModelxOn = pModel->GetFromName( asName + "_xon" ); // połączony na skos
} }
void TAirCoupler::Load(cParser *Parser, TModel3d *pModel) void TAirCoupler::Load(cParser *Parser, TModel3d *pModel)

View File

@@ -523,11 +523,11 @@ bool TAnimModel::Load(cParser *parser, bool ter)
return true; return true;
} }
TAnimContainer * TAnimModel::AddContainer(char *pName) TAnimContainer * TAnimModel::AddContainer(std::string const &Name)
{ // dodanie sterowania submodelem dla egzemplarza { // dodanie sterowania submodelem dla egzemplarza
if (!pModel) if (!pModel)
return NULL; return NULL;
TSubModel *tsb = pModel->GetFromName(pName); TSubModel *tsb = pModel->GetFromName(Name);
if (tsb) if (tsb)
{ {
TAnimContainer *tmp = new TAnimContainer(); TAnimContainer *tmp = new TAnimContainer();
@@ -539,16 +539,16 @@ TAnimContainer * TAnimModel::AddContainer(char *pName)
return NULL; return NULL;
} }
TAnimContainer * TAnimModel::GetContainer(char *pName) TAnimContainer * TAnimModel::GetContainer(std::string const &Name)
{ // szukanie/dodanie sterowania submodelem dla egzemplarza { // szukanie/dodanie sterowania submodelem dla egzemplarza
if (!pName) if (true == Name.empty())
return pRoot; // pobranie pierwszego (dla obrotnicy) return pRoot; // pobranie pierwszego (dla obrotnicy)
TAnimContainer *pCurrent; TAnimContainer *pCurrent;
for (pCurrent = pRoot; pCurrent != NULL; pCurrent = pCurrent->pNext) for (pCurrent = pRoot; pCurrent != NULL; pCurrent = pCurrent->pNext)
// if (pCurrent->GetName()==pName) // if (pCurrent->GetName()==pName)
if (std::string(pName) == pCurrent->NameGet()) if (Name == pCurrent->NameGet())
return pCurrent; return pCurrent;
return AddContainer(pName); return AddContainer(Name);
} }
// przeliczenie animacji - jednorazowo na klatkę // przeliczenie animacji - jednorazowo na klatkę

View File

@@ -163,8 +163,8 @@ private:
bool Init(TModel3d *pNewModel); bool Init(TModel3d *pNewModel);
bool Init(std::string const &asName, std::string const &asReplacableTexture); bool Init(std::string const &asName, std::string const &asReplacableTexture);
bool Load(cParser *parser, bool ter = false); bool Load(cParser *parser, bool ter = false);
TAnimContainer * AddContainer(char *pName); TAnimContainer * AddContainer(std::string const &Name);
TAnimContainer * GetContainer(char *pName); TAnimContainer * GetContainer(std::string const &Name = "");
int Flags(); int Flags();
void RaAnglesSet(double a, double b, double c) void RaAnglesSet(double a, double b, double c)
{ {

View File

@@ -28,8 +28,8 @@ void TButton::Init(std::string const &asName, TModel3d *pModel, bool bNewOn)
{ {
if( pModel == nullptr ) { return; } if( pModel == nullptr ) { return; }
pModelOn = pModel->GetFromName( (asName + "_on").c_str() ); pModelOn = pModel->GetFromName( asName + "_on" );
pModelOff = pModel->GetFromName( (asName + "_off").c_str() ); pModelOff = pModel->GetFromName( asName + "_off" );
m_state = bNewOn; m_state = bNewOn;
Update(); Update();
}; };

2556
Driver.cpp

File diff suppressed because it is too large Load Diff

View File

@@ -217,7 +217,6 @@ class TController
double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi
double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations
TAction eAction = actSleep; // aktualny stan TAction eAction = actSleep; // aktualny stan
bool HelpMeFlag = false; // wystawiane True jesli cos niedobrego sie dzieje
public: public:
inline TAction GetAction() inline TAction GetAction()
{ {
@@ -320,7 +319,7 @@ class TController
const TLocation &NewLocation, TStopReason reason = stopComm); const TLocation &NewLocation, TStopReason reason = stopComm);
bool PutCommand(std::string NewCommand, double NewValue1, double NewValue2, bool PutCommand(std::string NewCommand, double NewValue1, double NewValue2,
const vector3 *NewLocation, TStopReason reason = stopComm); const vector3 *NewLocation, TStopReason reason = stopComm);
bool UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę
// procedury dotyczace rozkazow dla maszynisty // procedury dotyczace rozkazow dla maszynisty
void SetVelocity(double NewVel, double NewVelNext, void SetVelocity(double NewVel, double NewVelNext,
TStopReason r = stopNone); // uaktualnia informacje o prędkości TStopReason r = stopNone); // uaktualnia informacje o prędkości

View File

@@ -1957,14 +1957,14 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
compartmentindex < 10 ? compartmentindex < 10 ?
"0" + std::to_string( compartmentindex ) : "0" + std::to_string( compartmentindex ) :
std::to_string( compartmentindex ) ); std::to_string( compartmentindex ) );
submodel = mdLowPolyInt->GetFromName( compartmentname.c_str() ); submodel = mdLowPolyInt->GetFromName( compartmentname );
if( submodel != nullptr ) { if( submodel != nullptr ) {
// if specified compartment was found we check also for potential matching section in the currently assigned load // if specified compartment was found we check also for potential matching section in the currently assigned load
// NOTE: if the load gets changed this will invalidate stored pointers. TODO: rebuild the table on load change // NOTE: if the load gets changed this will invalidate stored pointers. TODO: rebuild the table on load change
SectionLightLevels.emplace_back( SectionLightLevels.emplace_back(
submodel, submodel,
( mdLoad != nullptr ? ( mdLoad != nullptr ?
mdLoad->GetFromName( compartmentname.c_str() ): mdLoad->GetFromName( compartmentname ):
nullptr ), nullptr ),
0.0f ); 0.0f );
} }
@@ -1977,11 +1977,11 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
asAnimName = std::string("buffer_left0") + to_string(i + 1); asAnimName = std::string("buffer_left0") + to_string(i + 1);
smBuforLewy[i] = mdModel->GetFromName(asAnimName.c_str()); smBuforLewy[i] = mdModel->GetFromName(asAnimName);
if (smBuforLewy[i]) if (smBuforLewy[i])
smBuforLewy[i]->WillBeAnimated(); // ustawienie flagi animacji smBuforLewy[i]->WillBeAnimated(); // ustawienie flagi animacji
asAnimName = std::string("buffer_right0") + to_string(i + 1); asAnimName = std::string("buffer_right0") + to_string(i + 1);
smBuforPrawy[i] = mdModel->GetFromName(asAnimName.c_str()); smBuforPrawy[i] = mdModel->GetFromName(asAnimName);
if (smBuforPrawy[i]) if (smBuforPrawy[i])
smBuforPrawy[i]->WillBeAnimated(); smBuforPrawy[i]->WillBeAnimated();
} }
@@ -4243,7 +4243,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for (int i = 0; i < iAnimType[ANIM_PANTS]; i++) for (int i = 0; i < iAnimType[ANIM_PANTS]; i++)
{ // Winger 160204: wyszukiwanie max 2 patykow o nazwie str* { // Winger 160204: wyszukiwanie max 2 patykow o nazwie str*
asAnimName = token + std::to_string(i + 1); asAnimName = token + std::to_string(i + 1);
sm = mdModel->GetFromName(asAnimName.c_str()); sm = mdModel->GetFromName(asAnimName);
pants[i].smElement[0] = sm; // jak NULL, to nie będzie animowany pants[i].smElement[0] = sm; // jak NULL, to nie będzie animowany
if (sm) if (sm)
{ // w EP09 wywalało się tu z powodu NULL { // w EP09 wywalało się tu z powodu NULL
@@ -4335,7 +4335,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) { for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) {
// Winger 160204: wyszukiwanie max 2 patykow o nazwie str* // Winger 160204: wyszukiwanie max 2 patykow o nazwie str*
asAnimName = token + std::to_string( i + 1 ); asAnimName = token + std::to_string( i + 1 );
sm = mdModel->GetFromName( asAnimName.c_str() ); sm = mdModel->GetFromName( asAnimName );
pants[ i ].smElement[ 1 ] = sm; // jak NULL, to nie będzie animowany pants[ i ].smElement[ 1 ] = sm; // jak NULL, to nie będzie animowany
if( sm ) { // w EP09 wywalało się tu z powodu NULL if( sm ) { // w EP09 wywalało się tu z powodu NULL
sm->WillBeAnimated(); sm->WillBeAnimated();
@@ -4369,7 +4369,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) { for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) {
// Winger 160204: wyszukiwanie max 2 patykow o nazwie str* // Winger 160204: wyszukiwanie max 2 patykow o nazwie str*
asAnimName = token + std::to_string( i + 1 ); asAnimName = token + std::to_string( i + 1 );
pants[ i ].smElement[ 2 ] = mdModel->GetFromName( asAnimName.c_str() ); pants[ i ].smElement[ 2 ] = mdModel->GetFromName( asAnimName );
pants[ i ].smElement[ 2 ]->WillBeAnimated(); pants[ i ].smElement[ 2 ]->WillBeAnimated();
} }
} }
@@ -4382,7 +4382,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) { for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) {
// Winger 160204: wyszukiwanie max 2 patykow o nazwie str* // Winger 160204: wyszukiwanie max 2 patykow o nazwie str*
asAnimName = token + std::to_string( i + 1 ); asAnimName = token + std::to_string( i + 1 );
pants[ i ].smElement[ 3 ] = mdModel->GetFromName( asAnimName.c_str() ); pants[ i ].smElement[ 3 ] = mdModel->GetFromName( asAnimName );
pants[ i ].smElement[ 3 ]->WillBeAnimated(); pants[ i ].smElement[ 3 ]->WillBeAnimated();
} }
} }
@@ -4395,7 +4395,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) { for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) {
// Winger 160204: wyszukiwanie max 2 patykow o nazwie str* // Winger 160204: wyszukiwanie max 2 patykow o nazwie str*
asAnimName = token + std::to_string( i + 1 ); asAnimName = token + std::to_string( i + 1 );
pants[ i ].smElement[ 4 ] = mdModel->GetFromName( asAnimName.c_str() ); pants[ i ].smElement[ 4 ] = mdModel->GetFromName( asAnimName );
pants[ i ].smElement[ 4 ]->WillBeAnimated(); pants[ i ].smElement[ 4 ]->WillBeAnimated();
/* pants[ i ].yUpdate = UpdatePant; /* pants[ i ].yUpdate = UpdatePant;
*/ pants[ i ].yUpdate = std::bind( &TDynamicObject::UpdatePant, this, std::placeholders::_1 ); */ pants[ i ].yUpdate = std::bind( &TDynamicObject::UpdatePant, this, std::placeholders::_1 );
@@ -4529,7 +4529,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
for (int i = 1; i <= 4; i++) for (int i = 1; i <= 4; i++)
{ // McZapkie-050402: wyszukiwanie max 4 wahaczy o nazwie str* { // McZapkie-050402: wyszukiwanie max 4 wahaczy o nazwie str*
asAnimName = token + std::to_string(i); asAnimName = token + std::to_string(i);
smWahacze[i - 1] = mdModel->GetFromName(asAnimName.c_str()); smWahacze[i - 1] = mdModel->GetFromName(asAnimName);
smWahacze[i - 1]->WillBeAnimated(); smWahacze[i - 1]->WillBeAnimated();
} }
parser.getTokens(); parser >> token; parser.getTokens(); parser >> token;
@@ -4566,7 +4566,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
{ // NBMX wrzesien 2003: wyszukiwanie drzwi o nazwie str* { // NBMX wrzesien 2003: wyszukiwanie drzwi o nazwie str*
asAnimName = token + std::to_string(i + 1); asAnimName = token + std::to_string(i + 1);
pAnimations[i + j].smAnimated = pAnimations[i + j].smAnimated =
mdModel->GetFromName(asAnimName.c_str()); // ustalenie submodelu mdModel->GetFromName(asAnimName); // ustalenie submodelu
if (pAnimations[i + j].smAnimated) if (pAnimations[i + j].smAnimated)
{ //++iAnimatedDoors; { //++iAnimatedDoors;
pAnimations[i + j].smAnimated->WillBeAnimated(); // wyłączenie optymalizacji transformu pAnimations[i + j].smAnimated->WillBeAnimated(); // wyłączenie optymalizacji transformu

View File

@@ -176,6 +176,7 @@ public: // parametry położenia pojazdu dostępne publicznie
int NextConnectedNo; // numer sprzęgu podłączonego z tyłu int NextConnectedNo; // numer sprzęgu podłączonego z tyłu
int PrevConnectedNo; // numer sprzęgu podłączonego z przodu int PrevConnectedNo; // numer sprzęgu podłączonego z przodu
double fScanDist; // odległość skanowania torów na obecność innych pojazdów double fScanDist; // odległość skanowania torów na obecność innych pojazdów
double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
TPowerSource ConnectedEnginePowerSource( TDynamicObject const *Caller ) const; TPowerSource ConnectedEnginePowerSource( TDynamicObject const *Caller ) const;
@@ -364,8 +365,6 @@ public: // modele składowe pojazdu
public: public:
int *iLights; // wskaźnik na bity zapalonych świateł (własne albo innego członu) int *iLights; // wskaźnik na bity zapalonych świateł (własne albo innego członu)
bool DimHeadlights{ false }; // status of the headlight dimming toggle. NOTE: single toggle for all lights is a simplification. TODO: separate per-light switches bool DimHeadlights{ false }; // status of the headlight dimming toggle. NOTE: single toggle for all lights is a simplification. TODO: separate per-light switches
double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym
// pojazdem)
TDynamicObject * PrevAny(); TDynamicObject * PrevAny();
TDynamicObject * Prev(); TDynamicObject * Prev();
TDynamicObject * Next(); TDynamicObject * Next();

View File

@@ -78,7 +78,7 @@ void TEvent::Conditions(cParser *parser, std::string s)
if (!asNodeName.empty()) if (!asNodeName.empty())
{ // podczepienie łańcucha, jeśli nie jest pusty { // podczepienie łańcucha, jeśli nie jest pusty
// BUG: source of a memory leak -- the array never gets deleted. fix the destructor // BUG: source of a memory leak -- the array never gets deleted. fix the destructor
Params[9].asText = new char[asNodeName.length() + 1]; // usuwane i zamieniane na Params[9].asText = new char[asNodeName.size() + 1]; // usuwane i zamieniane na
// wskaźnik // wskaźnik
strcpy(Params[9].asText, asNodeName.c_str()); strcpy(Params[9].asText, asNodeName.c_str());
} }
@@ -103,7 +103,7 @@ void TEvent::Conditions(cParser *parser, std::string s)
str = token; str = token;
if (str != "*") //"*" - nie brac command pod uwage if (str != "*") //"*" - nie brac command pod uwage
{ // zapamiętanie łańcucha do porównania { // zapamiętanie łańcucha do porównania
Params[10].asText = new char[255]; Params[10].asText = new char[str.size() + 1];
strcpy(Params[10].asText, str.c_str()); strcpy(Params[10].asText, str.c_str());
iFlags |= conditional_memstring; iFlags |= conditional_memstring;
} }
@@ -144,7 +144,6 @@ void TEvent::Load(cParser *parser, vector3 *org)
int ti; int ti;
std::string token; std::string token;
//string str; //string str;
char *ptr;
bEnabled = true; // zmieniane na false dla eventów używanych do skanowania sygnałów bEnabled = true; // zmieniane na false dla eventów używanych do skanowania sygnałów
@@ -222,14 +221,12 @@ void TEvent::Load(cParser *parser, vector3 *org)
// if (Type==tp_UpdateValues) iFlags=0; //co modyfikować // if (Type==tp_UpdateValues) iFlags=0; //co modyfikować
parser->getTokens(1, false); // case sensitive parser->getTokens(1, false); // case sensitive
*parser >> token; *parser >> token;
// str = AnsiString(token.c_str()); Params[0].asText = new char[token.size() + 1]; // BUG: source of memory leak
Params[0].asText = new char[token.length() + 1]; // BUG: source of memory leak
strcpy(Params[0].asText, token.c_str()); strcpy(Params[0].asText, token.c_str());
if (token != "*") // czy ma zostać bez zmian? if (token != "*") // czy ma zostać bez zmian?
iFlags |= update_memstring; iFlags |= update_memstring;
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> token;
// str = AnsiString(token.c_str());
if (token != "*") // czy ma zostać bez zmian? if (token != "*") // czy ma zostać bez zmian?
{ {
Params[1].asdouble = atof(token.c_str()); Params[1].asdouble = atof(token.c_str());
@@ -239,7 +236,6 @@ void TEvent::Load(cParser *parser, vector3 *org)
Params[1].asdouble = 0; Params[1].asdouble = 0;
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> token;
// str = AnsiString(token.c_str());
if (token != "*") // czy ma zostać bez zmian? if (token != "*") // czy ma zostać bez zmian?
{ {
Params[2].asdouble = atof(token.c_str()); Params[2].asdouble = atof(token.c_str());
@@ -262,7 +258,7 @@ void TEvent::Load(cParser *parser, vector3 *org)
switch (++i) switch (++i)
{ // znaczenie kolejnych parametrów { // znaczenie kolejnych parametrów
case 1: // nazwa drugiej komórki (źródłowej) case 1: // nazwa drugiej komórki (źródłowej)
Params[9].asText = new char[token.length() + 1]; // usuwane i zamieniane na wskaźnik Params[9].asText = new char[token.size() + 1]; // usuwane i zamieniane na wskaźnik
strcpy(Params[9].asText, token.c_str()); strcpy(Params[9].asText, token.c_str());
break; break;
case 2: // maska wartości case 2: // maska wartości
@@ -353,7 +349,7 @@ void TEvent::Load(cParser *parser, vector3 *org)
} }
else else
Params[6].asCommand = cm_Unknown; Params[6].asCommand = cm_Unknown;
Params[0].asText = new char[token.length() + 1]; Params[0].asText = new char[token.size() + 1];
strcpy(Params[0].asText, token.c_str()); strcpy(Params[0].asText, token.c_str());
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> token;
@@ -561,7 +557,7 @@ void TEvent::Load(cParser *parser, vector3 *org)
{ // eventy rozpoczynające się od "none_" są ignorowane { // eventy rozpoczynające się od "none_" są ignorowane
if (token != "else") if (token != "else")
{ {
Params[i].asText = new char[255]; Params[i].asText = new char[token.size() + 1];
strcpy(Params[i].asText, token.c_str()); strcpy(Params[i].asText, token.c_str());
if (ti) if (ti)
iFlags |= conditional_else << i; // oflagowanie dla eventów "else" iFlags |= conditional_else << i; // oflagowanie dla eventów "else"

View File

@@ -15,8 +15,7 @@ http://mozilla.org/MPL/2.0/.
using namespace Math3D; using namespace Math3D;
typedef enum enum TEventType {
{
tp_Unknown, tp_Unknown,
tp_Sound, tp_Sound,
tp_SoundPos, tp_SoundPos,
@@ -41,7 +40,7 @@ typedef enum
tp_Voltage, tp_Voltage,
tp_Message, tp_Message,
tp_Friction tp_Friction
} TEventType; };
const int update_memstring = 0x0000001; // zmodyfikować tekst (UpdateValues) const int update_memstring = 0x0000001; // zmodyfikować tekst (UpdateValues)
const int update_memval1 = 0x0000002; // zmodyfikować pierwszą wartosć const int update_memval1 = 0x0000002; // zmodyfikować pierwszą wartosć

View File

@@ -85,7 +85,7 @@ bool TGauge::Load(cParser &Parser, TModel3d *md1, TModel3d *md2, double mul) {
} }
scale *= mul; scale *= mul;
TSubModel *submodel = md1->GetFromName( submodelname.c_str() ); TSubModel *submodel = md1->GetFromName( submodelname );
if( scale == 0.0 ) { if( scale == 0.0 ) {
ErrorLog( "Scale of 0.0 defined for sub-model \"" + submodelname + "\" in 3d model \"" + md1->NameGet() + "\". Forcing scale of 1.0 to prevent division by 0" ); ErrorLog( "Scale of 0.0 defined for sub-model \"" + submodelname + "\" in 3d model \"" + md1->NameGet() + "\". Forcing scale of 1.0 to prevent division by 0" );
scale = 1.0; scale = 1.0;
@@ -93,7 +93,7 @@ bool TGauge::Load(cParser &Parser, TModel3d *md1, TModel3d *md2, double mul) {
if (submodel) // jeśli nie znaleziony if (submodel) // jeśli nie znaleziony
md2 = nullptr; // informacja, że znaleziony md2 = nullptr; // informacja, że znaleziony
else if (md2) // a jest podany drugi model (np. zewnętrzny) else if (md2) // a jest podany drugi model (np. zewnętrzny)
submodel = md2->GetFromName(submodelname.c_str()); // to może tam będzie, co za różnica gdzie submodel = md2->GetFromName(submodelname); // to może tam będzie, co za różnica gdzie
if( submodel == nullptr ) { if( submodel == nullptr ) {
ErrorLog( "Failed to locate sub-model \"" + submodelname + "\" in 3d model \"" + md1->NameGet() + "\"" ); ErrorLog( "Failed to locate sub-model \"" + submodelname + "\" in 3d model \"" + md1->NameGet() + "\"" );
} }

View File

@@ -1598,7 +1598,7 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
importedvertices.emplace_back( vertex0 ); importedvertices.emplace_back( vertex0 );
} }
if( importedvertices.size() % 2 != 0 ) { if( importedvertices.size() % 2 != 0 ) {
ErrorLog( "Lines node specified odd number of vertices, encountered in file \"" + parser->Name() + "\"" ); ErrorLog( "Lines node specified odd number of vertices, encountered in file \"" + parser->Name() + "\" (line " + std::to_string( parser->Line() - 1 ) + ")" );
importedvertices.pop_back(); importedvertices.pop_back();
} }
tmp->iType = GL_LINES; tmp->iType = GL_LINES;
@@ -1653,6 +1653,8 @@ TSubRect * TGround::GetSubRect(int iCol, int iRow)
TEvent * TGround::FindEvent(const std::string &asEventName) TEvent * TGround::FindEvent(const std::string &asEventName)
{ {
if( asEventName.empty() ) { return nullptr; }
auto const lookup = m_eventmap.find( asEventName ); auto const lookup = m_eventmap.find( asEventName );
return ( return (
lookup != m_eventmap.end() ? lookup != m_eventmap.end() ?
@@ -1867,7 +1869,7 @@ bool TGround::Init(std::string File)
} }
else else
{ {
ErrorLog("Scene parsing error in file \"" + parser.Name() + "\", unexpected token \"" + token + "\""); ErrorLog("Scene parsing error in file \"" + parser.Name() + "\" (line " + std::to_string( parser.Line() ) + "), unexpected token \"" + token + "\"");
// break; // break;
} }
} }
@@ -2207,7 +2209,7 @@ bool TGround::Init(std::string File)
bool TGround::InitEvents() bool TGround::InitEvents()
{ //łączenie eventów z pozostałymi obiektami { //łączenie eventów z pozostałymi obiektami
TGroundNode *tmp, *trk; TGroundNode *tmp, *trk;
char buff[ 255 ]; std::string cellastext; std::string cellastext;
int i; int i;
for (TEvent *Current = RootEvent; Current; Current = Current->evNext2) for (TEvent *Current = RootEvent; Current; Current = Current->evNext2)
{ {
@@ -2215,19 +2217,16 @@ bool TGround::InitEvents()
{ {
case tp_AddValues: // sumowanie wartości case tp_AddValues: // sumowanie wartości
case tp_UpdateValues: // zmiana wartości case tp_UpdateValues: // zmiana wartości
tmp = FindGroundNode(Current->asNodeName, tmp = FindGroundNode(Current->asNodeName, TP_MEMCELL); // nazwa komórki powiązanej z eventem
TP_MEMCELL); // nazwa komórki powiązanej z eventem
if (tmp) if (tmp)
{ // McZapkie-100302 { // McZapkie-100302
if (Current->iFlags & (conditional_trackoccupied | conditional_trackfree)) if (Current->iFlags & (conditional_trackoccupied | conditional_trackfree))
{ // jeśli chodzi o zajetosc toru (tor może być inny, niż wpisany w komórce) { // jeśli chodzi o zajetosc toru (tor może być inny, niż wpisany w komórce)
trk = FindGroundNode(Current->asNodeName, trk = FindGroundNode(Current->asNodeName, TP_TRACK); // nazwa toru ta sama, co nazwa komórki
TP_TRACK); // nazwa toru ta sama, co nazwa komórki
if (trk) if (trk)
Current->Params[9].asTrack = trk->pTrack; Current->Params[9].asTrack = trk->pTrack;
if (!Current->Params[9].asTrack) if (!Current->Params[9].asTrack)
ErrorLog("Bad event: track \"" + Current->asNodeName + ErrorLog("Bad event: track \"" + Current->asNodeName + "\" referenced in event \"" + Current->asName + "\" doesn't exist");
"\" does not exists in \"" + Current->asName + "\"");
} }
Current->Params[4].nGroundNode = tmp; Current->Params[4].nGroundNode = tmp;
Current->Params[5].asMemCell = tmp->MemCell; // komórka do aktualizacji Current->Params[5].asMemCell = tmp->MemCell; // komórka do aktualizacji
@@ -2240,8 +2239,7 @@ bool TGround::InitEvents()
if (trk) if (trk)
Current->Params[6].asTrack = trk->pTrack; Current->Params[6].asTrack = trk->pTrack;
else else
ErrorLog("Bad memcell: track \"" + tmp->MemCell->asTrackName + ErrorLog("Bad memcell: track \"" + tmp->MemCell->asTrackName + "\" referenced in memcell \"" + tmp->asName + "\" doesn't exist");
"\" not exists in memcell \"" + tmp->asName + "\"");
} }
else else
Current->Params[6].asTrack = NULL; Current->Params[6].asTrack = NULL;
@@ -2249,8 +2247,7 @@ bool TGround::InitEvents()
else else
{ // nie ma komórki, to nie będzie działał poprawnie { // nie ma komórki, to nie będzie działał poprawnie
Current->Type = tp_Ignored; // deaktywacja Current->Type = tp_Ignored; // deaktywacja
ErrorLog("Bad event: \"" + Current->asName + "\" cannot find memcell \"" + ErrorLog("Bad event: event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"");
Current->asNodeName + "\"");
} }
break; break;
case tp_LogValues: // skojarzenie z memcell case tp_LogValues: // skojarzenie z memcell
@@ -2274,8 +2271,7 @@ bool TGround::InitEvents()
else else
{ // nie ma komórki, to nie będzie działał poprawnie { // nie ma komórki, to nie będzie działał poprawnie
Current->Type = tp_Ignored; // deaktywacja Current->Type = tp_Ignored; // deaktywacja
ErrorLog("Bad event: \"" + Current->asName + "\" cannot find memcell \"" + ErrorLog("Bad event: event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"");
Current->asNodeName + "\"");
} }
break; break;
case tp_CopyValues: // skopiowanie komórki do innej case tp_CopyValues: // skopiowanie komórki do innej
@@ -2291,15 +2287,13 @@ bool TGround::InitEvents()
if (trk) if (trk)
Current->Params[6].asTrack = trk->pTrack; Current->Params[6].asTrack = trk->pTrack;
else else
ErrorLog("Bad memcell: track \"" + tmp->MemCell->asTrackName + ErrorLog("Bad memcell: track \"" + tmp->MemCell->asTrackName + "\" referenced in memcell \"" + tmp->asName + "\" doesn't exists");
"\" not exists in memcell \"" + tmp->asName + "\"");
} }
else else
Current->Params[6].asTrack = NULL; Current->Params[6].asTrack = NULL;
} }
else else
ErrorLog("Bad copyvalues: event \"" + Current->asName + ErrorLog("Bad event: copyvalues event \"" + Current->asName + "\" cannot find memcell \"" + Current->asNodeName + "\"");
"\" cannot find memcell \"" + Current->asNodeName + "\"");
cellastext = Current->Params[ 9 ].asText; cellastext = Current->Params[ 9 ].asText;
SafeDeleteArray(Current->Params[9].asText); // usunięcie nazwy komórki SafeDeleteArray(Current->Params[9].asText); // usunięcie nazwy komórki
tmp = FindGroundNode( cellastext, TP_MEMCELL); // komórka źódłowa tmp = FindGroundNode( cellastext, TP_MEMCELL); // komórka źódłowa
@@ -2308,22 +2302,19 @@ bool TGround::InitEvents()
Current->Params[9].asMemCell = tmp->MemCell; // komórka źródłowa Current->Params[9].asMemCell = tmp->MemCell; // komórka źródłowa
} }
else else
ErrorLog("Bad copyvalues: event \"" + Current->asName + ErrorLog("Bad event: copyvalues event \"" + Current->asName + "\" cannot find memcell \"" + cellastext + "\"");
"\" cannot find memcell \"" + cellastext + "\"");
break; break;
case tp_Animation: // animacja modelu case tp_Animation: // animacja modelu
tmp = FindGroundNode(Current->asNodeName, TP_MODEL); // egzemplarza modelu do animowania tmp = FindGroundNode(Current->asNodeName, TP_MODEL); // egzemplarza modelu do animowania
if (tmp) if (tmp)
{ {
strcpy( cellastext = Current->Params[9].asText; // skopiowanie nazwy submodelu do bufora roboczego
buff,
Current->Params[9].asText); // skopiowanie nazwy submodelu do bufora roboczego
SafeDeleteArray(Current->Params[9].asText); // usunięcie nazwy submodelu SafeDeleteArray(Current->Params[9].asText); // usunięcie nazwy submodelu
if (Current->Params[0].asInt == 4) if (Current->Params[0].asInt == 4)
Current->Params[9].asModel = tmp->Model; // model dla całomodelowych animacji Current->Params[9].asModel = tmp->Model; // model dla całomodelowych animacji
else else
{ // standardowo przypisanie submodelu { // standardowo przypisanie submodelu
Current->Params[9].asAnimContainer = tmp->Model->GetContainer(buff); // submodel Current->Params[9].asAnimContainer = tmp->Model->GetContainer(cellastext); // submodel
if (Current->Params[9].asAnimContainer) if (Current->Params[9].asAnimContainer)
{ {
Current->Params[9].asAnimContainer->WillBeAnimated(); // oflagowanie Current->Params[9].asAnimContainer->WillBeAnimated(); // oflagowanie
@@ -2331,13 +2322,12 @@ bool TGround::InitEvents()
if (!Current->Params[9] if (!Current->Params[9]
.asAnimContainer->Event()) // nie szukać, gdy znaleziony .asAnimContainer->Event()) // nie szukać, gdy znaleziony
Current->Params[9].asAnimContainer->EventAssign( Current->Params[9].asAnimContainer->EventAssign(
FindEvent(Current->asNodeName + "." + buff + ":done")); FindEvent(Current->asNodeName + "." + cellastext + ":done"));
} }
} }
} }
else else
ErrorLog("Bad animation: event \"" + Current->asName + "\" cannot find model \"" + ErrorLog("Bad event: animation event \"" + Current->asName + "\" cannot find model \"" + Current->asNodeName + "\"");
Current->asNodeName + "\"");
Current->asNodeName = ""; Current->asNodeName = "";
break; break;
case tp_Lights: // zmiana świeteł modelu case tp_Lights: // zmiana świeteł modelu
@@ -2345,8 +2335,7 @@ bool TGround::InitEvents()
if (tmp) if (tmp)
Current->Params[9].asModel = tmp->Model; Current->Params[9].asModel = tmp->Model;
else else
ErrorLog("Bad lights: event \"" + Current->asName + "\" cannot find model \"" + ErrorLog("Bad event: lights event \"" + Current->asName + "\" cannot find model \"" + Current->asNodeName + "\"");
Current->asNodeName + "\"");
Current->asNodeName = ""; Current->asNodeName = "";
break; break;
case tp_Visible: // ukrycie albo przywrócenie obiektu case tp_Visible: // ukrycie albo przywrócenie obiektu
@@ -2358,8 +2347,7 @@ bool TGround::InitEvents()
if (tmp) if (tmp)
Current->Params[9].nGroundNode = tmp; Current->Params[9].nGroundNode = tmp;
else else
ErrorLog("Bad visibility: event \"" + Current->asName + "\" cannot find model \"" + ErrorLog("Bad event: visibility event \"" + Current->asName + "\" cannot find model \"" + Current->asNodeName + "\"");
Current->asNodeName + "\"");
Current->asNodeName = ""; Current->asNodeName = "";
break; break;
case tp_Switch: // przełożenie zwrotnicy albo zmiana stanu obrotnicy case tp_Switch: // przełożenie zwrotnicy albo zmiana stanu obrotnicy
@@ -2377,8 +2365,7 @@ bool TGround::InitEvents()
Current->Params[2].asdouble); // przesłanie parametrów Current->Params[2].asdouble); // przesłanie parametrów
} }
else else
ErrorLog("Bad switch: event \"" + Current->asName + "\" cannot find track \"" + ErrorLog("Bad event: switch event \"" + Current->asName + "\" cannot find track \"" + Current->asNodeName + "\"");
Current->asNodeName + "\"");
Current->asNodeName = ""; Current->asNodeName = "";
break; break;
case tp_Sound: // odtworzenie dźwięku case tp_Sound: // odtworzenie dźwięku
@@ -2386,8 +2373,7 @@ bool TGround::InitEvents()
if (tmp) if (tmp)
Current->Params[9].tsTextSound = tmp->tsStaticSound; Current->Params[9].tsTextSound = tmp->tsStaticSound;
else else
ErrorLog("Bad sound: event \"" + Current->asName + ErrorLog("Bad event: sound event \"" + Current->asName + "\" cannot find static sound \"" + Current->asNodeName + "\"");
"\" cannot find static sound \"" + Current->asNodeName + "\"");
Current->asNodeName = ""; Current->asNodeName = "";
break; break;
case tp_TrackVel: // ustawienie prędkości na torze case tp_TrackVel: // ustawienie prędkości na torze
@@ -2401,8 +2387,7 @@ bool TGround::InitEvents()
Current->Params[9].asTrack = tmp->pTrack; Current->Params[9].asTrack = tmp->pTrack;
} }
else else
ErrorLog("Bad velocity: event \"" + Current->asName + ErrorLog("Bad event: track velocity event \"" + Current->asName + "\" cannot find track \"" + Current->asNodeName + "\"");
"\" cannot find track \"" + Current->asNodeName + "\"");
} }
Current->asNodeName = ""; Current->asNodeName = "";
break; break;
@@ -2415,54 +2400,53 @@ bool TGround::InitEvents()
if (tmp) if (tmp)
Current->Params[9].asDynamic = tmp->DynamicObject; Current->Params[9].asDynamic = tmp->DynamicObject;
else else
Error("Event \"" + Current->asName + "\" cannot find dynamic \"" + Error("Bad event: vehicle velocity event \"" + Current->asName + "\" cannot find vehicle \"" + Current->asNodeName + "\"");
Current->asNodeName + "\"");
} }
Current->asNodeName = ""; Current->asNodeName = "";
break; break;
case tp_Multiple: case tp_Multiple:
if (Current->Params[9].asText != NULL) if (Current->Params[9].asText != NULL)
{ // przepisanie nazwy do bufora { // przepisanie nazwy do bufora
strcpy(buff, Current->Params[9].asText); cellastext = Current->Params[ 9 ].asText;
SafeDeleteArray(Current->Params[9].asText); SafeDeleteArray(Current->Params[9].asText);
Current->Params[9].asPointer = NULL; // zerowanie wskaźnika, aby wykryć brak obeiktu Current->Params[9].asPointer = NULL; // zerowanie wskaźnika, aby wykryć brak obeiktu
} }
else else
buff[0] = '\0'; cellastext = "";
if (Current->iFlags & (conditional_trackoccupied | conditional_trackfree)) if (Current->iFlags & (conditional_trackoccupied | conditional_trackfree))
{ // jeśli chodzi o zajetosc toru { // jeśli chodzi o zajetosc toru
tmp = FindGroundNode(buff, TP_TRACK); tmp = FindGroundNode(cellastext, TP_TRACK);
if (tmp) if (tmp)
Current->Params[9].asTrack = tmp->pTrack; Current->Params[9].asTrack = tmp->pTrack;
if (!Current->Params[9].asTrack) if (!Current->Params[9].asTrack)
{ {
ErrorLog("Bad event: Track \"" + std::string(buff) + "\" does not exist in \"" + Current->asName + "\""); ErrorLog("Bad event: Track \"" + cellastext + "\" does not exist in \"" + Current->asName + "\"");
Current->iFlags &= ~(conditional_trackoccupied | conditional_trackfree); // zerowanie flag Current->iFlags &= ~(conditional_trackoccupied | conditional_trackfree); // zerowanie flag
} }
} }
else if (Current->iFlags & (conditional_memstring | conditional_memval1 | conditional_memval2)) else if (Current->iFlags & (conditional_memstring | conditional_memval1 | conditional_memval2))
{ // jeśli chodzi o komorke pamieciową { // jeśli chodzi o komorke pamieciową
tmp = FindGroundNode(buff, TP_MEMCELL); tmp = FindGroundNode(cellastext, TP_MEMCELL);
if (tmp) if (tmp)
Current->Params[9].asMemCell = tmp->MemCell; Current->Params[9].asMemCell = tmp->MemCell;
if (!Current->Params[9].asMemCell) if (!Current->Params[9].asMemCell)
{ {
ErrorLog("Bad event: MemCell \"" + std::string(buff) + "\" does not exist in \"" + Current->asName + "\""); ErrorLog("Bad event: MemCell \"" + cellastext + "\" does not exist in \"" + Current->asName + "\"");
Current->iFlags &= ~(conditional_memstring | conditional_memval1 | conditional_memval2); Current->iFlags &= ~(conditional_memstring | conditional_memval1 | conditional_memval2);
} }
} }
for (i = 0; i < 8; i++) for (i = 0; i < 8; ++i)
{ {
if (Current->Params[i].asText != NULL) if (Current->Params[i].asText != NULL)
{ {
strcpy(buff, Current->Params[i].asText); cellastext = Current->Params[ i ].asText;
SafeDeleteArray(Current->Params[i].asText); SafeDeleteArray(Current->Params[i].asText);
Current->Params[i].asEvent = FindEvent(buff); Current->Params[i].asEvent = FindEvent(cellastext);
if( !Current->Params[ i ].asEvent ) { // Ra: tylko w logu informacja o braku if( !Current->Params[ i ].asEvent ) { // Ra: tylko w logu informacja o braku
if( ( Current->Params[ i ].asText == NULL ) if( ( Current->Params[ i ].asText == NULL )
|| ( std::string( Current->Params[ i ].asText ).substr( 0, 5 ) != "none_" ) ) { || ( std::string( Current->Params[ i ].asText ).substr( 0, 5 ) != "none_" ) ) {
WriteLog( "Event \"" + std::string( buff ) + "\" does not exist" ); WriteLog( "Event \"" + cellastext + "\" does not exist" );
ErrorLog( "Missed event: " + std::string( buff ) + " in multiple " + Current->asName ); ErrorLog( "Missed event: " + cellastext + " in multiple " + Current->asName );
} }
} }
} }
@@ -2471,13 +2455,11 @@ bool TGround::InitEvents()
case tp_Voltage: // zmiana napięcia w zasilaczu (TractionPowerSource) case tp_Voltage: // zmiana napięcia w zasilaczu (TractionPowerSource)
if (!Current->asNodeName.empty()) if (!Current->asNodeName.empty())
{ {
tmp = FindGroundNode(Current->asNodeName, tmp = FindGroundNode(Current->asNodeName, TP_TRACTIONPOWERSOURCE); // podłączenie zasilacza
TP_TRACTIONPOWERSOURCE); // podłączenie zasilacza
if (tmp) if (tmp)
Current->Params[9].psPower = tmp->psTractionPowerSource; Current->Params[9].psPower = tmp->psTractionPowerSource;
else else
ErrorLog("Bad voltage: event \"" + Current->asName + ErrorLog("Bad event: voltage event \"" + Current->asName + "\" cannot find power source \"" + Current->asNodeName + "\"");
"\" cannot find power source \"" + Current->asNodeName + "\"");
} }
Current->asNodeName = ""; Current->asNodeName = "";
break; break;
@@ -2500,43 +2482,32 @@ void TGround::InitTracks()
TTrack *tmp; // znaleziony tor TTrack *tmp; // znaleziony tor
TTrack *Track; TTrack *Track;
int iConnection; int iConnection;
std::string name;
// tracks=tracksfar=0;
for (Current = nRootOfType[TP_TRACK]; Current; Current = Current->nNext)
{
Track = Current->pTrack;
if (Global::iHiddenEvents & 1)
if (!Current->asName.empty())
{ // jeśli podana jest nazwa torów, można szukać eventów skojarzonych przez nazwę
if (Track->asEvent0Name.empty())
if (FindEvent(Current->asName + ":event0"))
Track->asEvent0Name = Current->asName + ":event0";
if (Track->asEvent1Name.empty())
if (FindEvent(Current->asName + ":event1"))
Track->asEvent1Name = Current->asName + ":event1";
if (Track->asEvent2Name.empty())
if (FindEvent(Current->asName + ":event2"))
Track->asEvent2Name = Current->asName + ":event2";
if (Track->asEventall0Name.empty()) for (Current = nRootOfType[TP_TRACK]; Current; Current = Current->nNext) {
if (FindEvent(Current->asName + ":eventall0"))
Track->asEventall0Name = Current->asName + ":eventall0"; Track = Current->pTrack;
if (Track->asEventall1Name.empty()) // assign track events
if (FindEvent(Current->asName + ":eventall1"))
Track->asEventall1Name = Current->asName + ":eventall1";
if (Track->asEventall2Name.empty())
if (FindEvent(Current->asName + ":eventall2"))
Track->asEventall2Name = Current->asName + ":eventall2";
}
Track->AssignEvents( Track->AssignEvents(
Track->asEvent0Name.empty() ? NULL : FindEvent(Track->asEvent0Name), FindEvent( Track->asEvent0Name ),
Track->asEvent1Name.empty() ? NULL : FindEventScan(Track->asEvent1Name), FindEvent( Track->asEvent1Name ),
Track->asEvent2Name.empty() ? NULL : FindEventScan(Track->asEvent2Name)); FindEvent( Track->asEvent2Name ) );
Track->AssignallEvents( Track->AssignallEvents(
Track->asEventall0Name.empty() ? NULL : FindEvent(Track->asEventall0Name), FindEvent( Track->asEventall0Name ),
Track->asEventall1Name.empty() ? NULL : FindEvent(Track->asEventall1Name), FindEvent( Track->asEventall1Name ),
Track->asEventall2Name.empty() ? NULL : FindEvent( Track->asEventall2Name ) );
FindEvent(Track->asEventall2Name)); // MC-280503 if( ( Global::iHiddenEvents & 1 )
&& ( false == Current->asName.empty() ) ) {
// jeśli podana jest nazwa torów, można szukać eventów skojarzonych przez nazwę
Track->AssignEvents(
FindEvent( Current->asName + ":event0" ),
FindEvent( Current->asName + ":event1" ),
FindEvent( Current->asName + ":event2" ) );
Track->AssignallEvents(
FindEvent( Current->asName + ":eventall0" ),
FindEvent( Current->asName + ":eventall1" ),
FindEvent( Current->asName + ":eventall2" ) );
}
switch (Track->eType) switch (Track->eType)
{ {
case tt_Table: // obrotnicę też łączymy na starcie z innymi torami case tt_Table: // obrotnicę też łączymy na starcie z innymi torami
@@ -2634,7 +2605,7 @@ void TGround::InitTracks()
FindEvent(Current->asName + ":forced-")); FindEvent(Current->asName + ":forced-"));
break; break;
} }
name = Track->IsolatedName(); // pobranie nazwy odcinka izolowanego std::string const name = Track->IsolatedName(); // pobranie nazwy odcinka izolowanego
if (!name.empty()) // jeśli została zwrócona nazwa if (!name.empty()) // jeśli została zwrócona nazwa
Track->IsolatedEventsAssign(FindEvent(name + ":busy"), FindEvent(name + ":free")); Track->IsolatedEventsAssign(FindEvent(name + ":busy"), FindEvent(name + ":free"));
if (Current->asName.substr(0, 1) == if (Current->asName.substr(0, 1) ==

View File

@@ -867,7 +867,8 @@ public:
/* /*
int BrakeStatus = b_off; //0 - odham, 1 - ham., 2 - uszk., 4 - odluzniacz, 8 - antyposlizg, 16 - uzyte EP, 32 - pozycja R, 64 - powrot z R int BrakeStatus = b_off; //0 - odham, 1 - ham., 2 - uszk., 4 - odluzniacz, 8 - antyposlizg, 16 - uzyte EP, 32 - pozycja R, 64 - powrot z R
*/ */
bool EmergencyBrakeFlag = false; /*hamowanie nagle*/ bool AlarmChainFlag = false; // manual emergency brake
bool RadioStopFlag = false; /*hamowanie nagle*/
int BrakeDelayFlag = 0; /*nastawa opoznienia ham. osob/towar/posp/exp 0/1/2/4*/ int BrakeDelayFlag = 0; /*nastawa opoznienia ham. osob/towar/posp/exp 0/1/2/4*/
int BrakeDelays = 0; /*nastawy mozliwe do uzyskania*/ int BrakeDelays = 0; /*nastawy mozliwe do uzyskania*/
int BrakeOpModeFlag = 0; /*nastawa trybu pracy PS/PN/EP/MED 1/2/4/8*/ int BrakeOpModeFlag = 0; /*nastawa trybu pracy PS/PN/EP/MED 1/2/4/8*/
@@ -1082,7 +1083,8 @@ public:
bool IncManualBrakeLevel(int CtrlSpeed); bool IncManualBrakeLevel(int CtrlSpeed);
bool DecManualBrakeLevel(int CtrlSpeed); bool DecManualBrakeLevel(int CtrlSpeed);
bool DynamicBrakeSwitch(bool Switch); bool DynamicBrakeSwitch(bool Switch);
bool EmergencyBrakeSwitch(bool Switch); bool RadiostopSwitch(bool Switch);
bool AlarmChainSwitch( bool const State );
bool AntiSlippingBrake(void); bool AntiSlippingBrake(void);
bool BrakeReleaser(int state); bool BrakeReleaser(int state);
bool SwitchEPBrake(int state); bool SwitchEPBrake(int state);

View File

@@ -1081,7 +1081,7 @@ void TMoverParameters::CollisionDetect(int CouplerN, double dt)
EventFlag = true; EventFlag = true;
if ((coupler.CouplingFlag & ctrain_pneumatic) == ctrain_pneumatic) if ((coupler.CouplingFlag & ctrain_pneumatic) == ctrain_pneumatic)
EmergencyBrakeFlag = true; // hamowanie nagle - zerwanie przewodow hamulcowych AlarmChainFlag = true; // hamowanie nagle - zerwanie przewodow hamulcowych
coupler.CouplingFlag = 0; coupler.CouplingFlag = 0;
switch (CouplerN) // wyzerowanie flag podlaczenia ale ciagle sa wirtualnie polaczone switch (CouplerN) // wyzerowanie flag podlaczenia ale ciagle sa wirtualnie polaczone
@@ -2187,7 +2187,7 @@ void TMoverParameters::SecuritySystemCheck(double dt)
// obsady // obsady
// poza tym jest zdefiniowany we wszystkich 3 członach EN57 // poza tym jest zdefiniowany we wszystkich 3 członach EN57
if ((!Radio)) if ((!Radio))
EmergencyBrakeSwitch(false); RadiostopSwitch(false);
if ((SecuritySystem.SystemType > 0) && (SecuritySystem.Status > 0) && if ((SecuritySystem.SystemType > 0) && (SecuritySystem.Status > 0) &&
(Battery)) // Ra: EZT ma teraz czuwak w rozrządczym (Battery)) // Ra: EZT ma teraz czuwak w rozrządczym
@@ -2258,7 +2258,7 @@ void TMoverParameters::SecuritySystemCheck(double dt)
} }
else if (!Battery) else if (!Battery)
{ // wyłączenie baterii deaktywuje sprzęt { // wyłączenie baterii deaktywuje sprzęt
EmergencyBrakeSwitch(false); RadiostopSwitch(false);
// SecuritySystem.Status = 0; //deaktywacja czuwaka // SecuritySystem.Status = 0; //deaktywacja czuwaka
} }
} }
@@ -2776,34 +2776,49 @@ bool TMoverParameters::DynamicBrakeSwitch(bool Switch)
// Q: 20160711 // Q: 20160711
// włączenie / wyłączenie hamowania awaryjnego // włączenie / wyłączenie hamowania awaryjnego
// ************************************************************************************************* // *************************************************************************************************
bool TMoverParameters::EmergencyBrakeSwitch(bool Switch) bool TMoverParameters::RadiostopSwitch(bool Switch)
{ {
bool EBS; bool EBS;
if ((BrakeSystem != Individual) && (BrakeCtrlPosNo > 0)) if( ( BrakeSystem != Individual )
{ && ( BrakeCtrlPosNo > 0 ) ) {
if ((!EmergencyBrakeFlag) && Switch)
{ if( ( true == Switch )
EmergencyBrakeFlag = Switch; && ( false == RadioStopFlag ) ) {
RadioStopFlag = Switch;
EBS = true; EBS = true;
} }
else else {
{ if( ( Switch == false )
if ((abs(V) < 0.1) && && ( std::abs( V ) < 0.1 ) ) {
(Switch == false)) // odblokowanie hamulca bezpieczenistwa tylko po zatrzymaniu // odblokowanie hamulca bezpieczenistwa tylko po zatrzymaniu
{ RadioStopFlag = Switch;
EmergencyBrakeFlag = Switch;
EBS = true; EBS = true;
} }
else else {
EBS = false; EBS = false;
}
} }
} }
else else {
EBS = false; // nie ma hamulca bezpieczenstwa gdy nie ma hamulca zesp. // nie ma hamulca bezpieczenstwa gdy nie ma hamulca zesp.
EBS = false;
}
return EBS; return EBS;
} }
bool TMoverParameters::AlarmChainSwitch( bool const State ) {
bool stateswitched { false };
if( AlarmChainFlag != State ) {
// simple routine for the time being
AlarmChainFlag = State;
stateswitched = true;
}
return stateswitched;
}
// ************************************************************************************************* // *************************************************************************************************
// Q: 20160710 // Q: 20160710
// hamowanie przeciwpoślizgowe // hamowanie przeciwpoślizgowe
@@ -3281,12 +3296,19 @@ void TMoverParameters::UpdatePipePressure(double dt)
Pipe2->Flow(dpMainValve); Pipe2->Flow(dpMainValve);
} }
// if(EmergencyBrakeFlag)and(BrakeCtrlPosNo=0)then //ulepszony hamulec bezp. // ulepszony hamulec bezp.
if ((EmergencyBrakeFlag) || (TestFlag(SecuritySystem.Status, s_SHPebrake)) || if( ( true == RadioStopFlag )
(TestFlag(SecuritySystem.Status, s_CAebrake)) || || ( true == AlarmChainFlag )
(s_CAtestebrake == true) || || ( true == TestFlag( SecuritySystem.Status, s_SHPebrake ) )
(TestFlag(EngDmgFlag, 32)) /* or (not Battery)*/) // ulepszony hamulec bezp. || ( true == TestFlag( SecuritySystem.Status, s_CAebrake ) )
dpMainValve = dpMainValve + PF(0, PipePress, 0.15) * dt; /*
// NOTE: disabled because 32 is 'load destroyed' flag, what does this have to do with emergency brake?
// (if it's supposed to be broken coupler, such event sets alarmchainflag instead when appropriate)
|| ( true == TestFlag( EngDmgFlag, 32 ) )
*/
|| ( true == s_CAtestebrake ) ) {
dpMainValve = dpMainValve + PF( 0, PipePress, 0.15 ) * dt;
}
// 0.2*Spg // 0.2*Spg
Pipe->Flow(-dpMainValve); Pipe->Flow(-dpMainValve);
Pipe->Flow(-(PipePress)*0.001 * dt); Pipe->Flow(-(PipePress)*0.001 * dt);
@@ -8266,7 +8288,7 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
} }
else if (Command == "Emergency_brake") else if (Command == "Emergency_brake")
{ {
if (EmergencyBrakeSwitch(floor(CValue1) == 1)) // YB: czy to jest potrzebne? if (RadiostopSwitch(floor(CValue1) == 1)) // YB: czy to jest potrzebne?
OK = true; OK = true;
else else
OK = false; OK = false;

View File

@@ -836,23 +836,18 @@ struct ToLower
}; };
TSubModel *TSubModel::GetFromName(std::string const &search, bool i) TSubModel *TSubModel::GetFromName(std::string const &search, bool i)
{
return GetFromName(search.c_str(), i);
};
TSubModel *TSubModel::GetFromName(char const *search, bool i)
{ {
TSubModel *result; TSubModel *result;
// std::transform(search.begin(),search.end(),search.begin(),ToLower()); // std::transform(search.begin(),search.end(),search.begin(),ToLower());
// search=search.LowerCase(); // search=search.LowerCase();
// AnsiString name=AnsiString(); // AnsiString name=AnsiString();
std::string search_lc = std::string(search); std::string search_lc = search;
if (i) if (i)
std::transform(search_lc.begin(), search_lc.end(), search_lc.begin(), ::tolower); std::transform(search_lc.begin(), search_lc.end(), search_lc.begin(), ::tolower);
std::string pName_lc = pName; std::string pName_lc = pName;
if (i) if (i)
std::transform(pName_lc.begin(), pName_lc.end(), pName_lc.begin(), ::tolower); std::transform(pName_lc.begin(), pName_lc.end(), pName_lc.begin(), ::tolower);
if (pName.size() && search) if (pName.size() && search.size())
if (pName_lc == search_lc) if (pName_lc == search_lc)
return this; return this;
if (Next) if (Next)
@@ -1147,23 +1142,19 @@ TModel3d::TModel3d()
Root = NULL; Root = NULL;
iFlags = 0; iFlags = 0;
iSubModelsCount = 0; iSubModelsCount = 0;
iModel = NULL; // tylko jak wczytany model binarny
iNumVerts = 0; // nie ma jeszcze wierzchołków iNumVerts = 0; // nie ma jeszcze wierzchołków
}; };
TModel3d::~TModel3d() TModel3d::~TModel3d() {
{
// SafeDeleteArray(Materials); if (iFlags & 0x0200) {
if (iFlags & 0x0200) // wczytany z pliku tekstowego, submodele sprzątają same
{ // wczytany z pliku tekstowego, submodele sprzątają same Root = nullptr;
SafeDelete(Root); // submodele się usuną rekurencyjnie
} }
else else {
{ // wczytano z pliku binarnego (jest właścicielem tablic) // wczytano z pliku binarnego (jest właścicielem tablic)
Root = nullptr; SafeDeleteArray( Root ); // submodele się usuną rekurencyjnie
delete[] iModel; // usuwamy cały wczytany plik i to wystarczy }
}
// później się jeszcze usuwa obiekt z którego dziedziczymy tabelę VBO
}; };
TSubModel *TModel3d::AddToNamed(const char *Name, TSubModel *SubModel) TSubModel *TModel3d::AddToNamed(const char *Name, TSubModel *SubModel)
@@ -1190,16 +1181,16 @@ void TModel3d::AddTo(TSubModel *tmp, TSubModel *SubModel)
iFlags |= 0x0200; // submodele są oddzielne iFlags |= 0x0200; // submodele są oddzielne
}; };
TSubModel *TModel3d::GetFromName(const char *sName) TSubModel *TModel3d::GetFromName(std::string const &Name)
{ // wyszukanie submodelu po nazwie { // wyszukanie submodelu po nazwie
if (!sName) if (Name.empty())
return Root; // potrzebne do terenu z E3D return Root; // potrzebne do terenu z E3D
if (iFlags & 0x0200) // wczytany z pliku tekstowego, wyszukiwanie rekurencyjne if (iFlags & 0x0200) // wczytany z pliku tekstowego, wyszukiwanie rekurencyjne
return Root ? Root->GetFromName(sName) : nullptr; return Root ? Root->GetFromName(Name) : nullptr;
else // wczytano z pliku binarnego, można wyszukać iteracyjnie else // wczytano z pliku binarnego, można wyszukać iteracyjnie
{ {
// for (int i=0;i<iSubModelsCount;++i) // for (int i=0;i<iSubModelsCount;++i)
return Root ? Root->GetFromName(sName) : nullptr; return Root ? Root->GetFromName(Name) : nullptr;
} }
}; };
@@ -1455,7 +1446,6 @@ void TSubModel::deserialize(std::istream &s)
void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic) void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
{ {
Root = nullptr; Root = nullptr;
float4x4 *tm = nullptr;
if( m_geometrybank == null_handle ) { if( m_geometrybank == null_handle ) {
m_geometrybank = GfxRenderer.Create_Bank(); m_geometrybank = GfxRenderer.Create_Bank();
} }
@@ -1478,7 +1468,7 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
iSubModelsCount = (int)sm_cnt; iSubModelsCount = (int)sm_cnt;
Root = new TSubModel[sm_cnt]; Root = new TSubModel[sm_cnt];
size_t pos = s.tellg(); size_t pos = s.tellg();
for (size_t i = 0; i < sm_cnt; i++) for (size_t i = 0; i < sm_cnt; ++i)
{ {
s.seekg(pos + sm_size * i); s.seekg(pos + sm_size * i);
Root[i].deserialize(s); Root[i].deserialize(s);
@@ -1493,18 +1483,13 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
size_t vt_cnt = size / 32; size_t vt_cnt = size / 32;
iNumVerts = (int)vt_cnt; iNumVerts = (int)vt_cnt;
m_nVertexCount = (int)vt_cnt; m_nVertexCount = (int)vt_cnt;
#ifdef EU07_USE_OLD_VERTEXBUFFER
assert( m_pVNT == nullptr );
m_pVNT = new basic_vertex[vt_cnt];
#else
m_pVNT.resize( vt_cnt ); m_pVNT.resize( vt_cnt );
#endif
for (size_t i = 0; i < vt_cnt; i++) for (size_t i = 0; i < vt_cnt; i++)
m_pVNT[i].deserialize(s); m_pVNT[i].deserialize(s);
*/ */
// we rely on the SUB chunk coming before the vertex data, and on the overall vertex count matching the size of data in the chunk // we rely on the SUB chunk coming before the vertex data, and on the overall vertex count matching the size of data in the chunk.
// geometry associated with chunks isn't stored in the same order as the chunks themselves, so we need to sort that out first // geometry associated with chunks isn't stored in the same order as the chunks themselves, so we need to sort that out first
std::vector< std::pair<int, int> > submodeloffsets; std::vector< std::pair<int, int> > submodeloffsets; // vertex data offset, submodel index
submodeloffsets.reserve( iSubModelsCount ); submodeloffsets.reserve( iSubModelsCount );
for( int submodelindex = 0; submodelindex < iSubModelsCount; ++submodelindex ) { for( int submodelindex = 0; submodelindex < iSubModelsCount; ++submodelindex ) {
auto const &submodel = Root[ submodelindex ]; auto const &submodel = Root[ submodelindex ];
@@ -1546,23 +1531,23 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
} }
else if (type == MAKE_ID4('T', 'R', 'A', '0')) else if (type == MAKE_ID4('T', 'R', 'A', '0'))
{ {
if (tm != nullptr) if( false == Matrices.empty() )
throw std::runtime_error("e3d: duplicated TRA chunk"); throw std::runtime_error("e3d: duplicated TRA chunk");
size_t t_cnt = size / 64; size_t t_cnt = size / 64;
tm = new float4x4[t_cnt]; Matrices.resize(t_cnt);
for (size_t i = 0; i < t_cnt; i++) for (size_t i = 0; i < t_cnt; ++i)
tm[i].deserialize_float32(s); Matrices[i].deserialize_float32(s);
} }
else if (type == MAKE_ID4('T', 'R', 'A', '1')) else if (type == MAKE_ID4('T', 'R', 'A', '1'))
{ {
if (tm != nullptr) if( false == Matrices.empty() )
throw std::runtime_error("e3d: duplicated TRA chunk"); throw std::runtime_error("e3d: duplicated TRA chunk");
size_t t_cnt = size / 128; size_t t_cnt = size / 128;
tm = new float4x4[t_cnt]; Matrices.resize( t_cnt );
for (size_t i = 0; i < t_cnt; i++) for (size_t i = 0; i < t_cnt; ++i)
tm[i].deserialize_float64(s); Matrices[i].deserialize_float64(s);
} }
else if (type == MAKE_ID4('T', 'E', 'X', '0')) else if (type == MAKE_ID4('T', 'E', 'X', '0'))
{ {
@@ -1584,17 +1569,10 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
if (!Root) if (!Root)
throw std::runtime_error("e3d: no submodels"); throw std::runtime_error("e3d: no submodels");
/*
#ifdef EU07_USE_OLD_VERTEXBUFFER for (size_t i = 0; (int)i < iSubModelsCount; ++i)
if (!m_pVNT)
#else
if(m_pVNT.empty() )
#endif
throw std::runtime_error("e3d: no vertices");
*/
for (size_t i = 0; (int)i < iSubModelsCount; ++i)
{ {
Root[i].BinInit( Root, tm, &Textures, &Names, dynamic ); Root[i].BinInit( Root, Matrices.data(), &Textures, &Names, dynamic );
if (Root[i].ChildGet()) if (Root[i].ChildGet())
Root[i].ChildGet()->Parent = &Root[i]; Root[i].ChildGet()->Parent = &Root[i];

View File

@@ -174,8 +174,7 @@ public:
void SetTranslate(vector3 vNewTransVector); void SetTranslate(vector3 vNewTransVector);
void SetTranslate(float3 vNewTransVector); void SetTranslate(float3 vNewTransVector);
void SetRotateIK1(float3 vNewAngles); void SetRotateIK1(float3 vNewAngles);
TSubModel * GetFromName(std::string const &search, bool i = true); TSubModel * GetFromName( std::string const &search, bool i = true );
TSubModel * GetFromName(char const *search, bool i = true);
inline float4x4 * GetMatrix() { return fMatrix; }; inline float4x4 * GetMatrix() { return fMatrix; };
inline void Hide() { iVisible = 0; }; inline void Hide() { iVisible = 0; };
@@ -234,7 +233,7 @@ public: // Ra: tymczasowo
private: private:
std::vector<std::string> Textures; // nazwy tekstur std::vector<std::string> Textures; // nazwy tekstur
std::vector<std::string> Names; // nazwy submodeli std::vector<std::string> Names; // nazwy submodeli
int *iModel; // zawartość pliku binarnego std::vector<float4x4> Matrices; // submodel matrices
int iSubModelsCount; // Ra: używane do tworzenia binarnych int iSubModelsCount; // Ra: używane do tworzenia binarnych
std::string asBinary; // nazwa pod którą zapisać model binarny std::string asBinary; // nazwa pod którą zapisać model binarny
std::string m_filename; std::string m_filename;
@@ -242,7 +241,7 @@ public:
inline TSubModel * GetSMRoot() { return (Root); }; inline TSubModel * GetSMRoot() { return (Root); };
TModel3d(); TModel3d();
~TModel3d(); ~TModel3d();
TSubModel * GetFromName(const char *sName); TSubModel * GetFromName(std::string const &Name);
TSubModel * AddToNamed(const char *Name, TSubModel *SubModel); TSubModel * AddToNamed(const char *Name, TSubModel *SubModel);
void AddTo(TSubModel *tmp, TSubModel *SubModel); void AddTo(TSubModel *tmp, TSubModel *SubModel);
void LoadFromTextFile(std::string const &FileName, bool dynamic); void LoadFromTextFile(std::string const &FileName, bool dynamic);

View File

@@ -429,7 +429,7 @@ void TPythonScreens::init(cParser &parser, TModel3d *model, std::string const &n
>> asPyClassName; >> asPyClassName;
std::string subModelName = ToLower( asSubModelName ); std::string subModelName = ToLower( asSubModelName );
std::string pyClassName = ToLower( asPyClassName ); std::string pyClassName = ToLower( asPyClassName );
TSubModel *subModel = model->GetFromName(subModelName.c_str()); TSubModel *subModel = model->GetFromName(subModelName);
if (subModel == NULL) if (subModel == NULL)
{ {
WriteLog( "Python Screen: submodel " + subModelName + " not found - Ignoring screen" ); WriteLog( "Python Screen: submodel " + subModelName + " not found - Ignoring screen" );

186
Track.cpp
View File

@@ -778,145 +778,127 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
} }
} }
// TODO: refactor this mess
bool TTrack::AssignEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2) bool TTrack::AssignEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2)
{ {
bool bError = false; bool bError = false;
if (!evEvent0)
{ if( NewEvent0 == nullptr ) {
if (NewEvent0) if( false == asEvent0Name.empty() ) {
{ ErrorLog( "Bad event: event \"" + asEvent0Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
}
else {
if( evEvent0 == nullptr ) {
evEvent0 = NewEvent0; evEvent0 = NewEvent0;
asEvent0Name = ""; asEvent0Name = "";
iEvents |= 1; // sumaryczna informacja o eventach iEvents |= 1; // sumaryczna informacja o eventach
} }
else else {
{ ErrorLog( "Bad track: event \"" + NewEvent0->asName + "\" cannot be assigned to track, track already has one" );
if (!asEvent0Name.empty()) bError = true;
{
ErrorLog("Bad track: Event0 \"" + asEvent0Name +
"\" does not exist");
bError = true;
}
} }
} }
else
{ if( NewEvent1 == nullptr ) {
ErrorLog( "Bad track: Event0 cannot be assigned to track, track already has one"); if( false == asEvent1Name.empty() ) {
bError = true; ErrorLog( "Bad event: event \"" + asEvent1Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
} }
if (!evEvent1) else {
{ if( evEvent1 == nullptr ) {
if (NewEvent1)
{
evEvent1 = NewEvent1; evEvent1 = NewEvent1;
asEvent1Name = ""; asEvent1Name = "";
iEvents |= 2; // sumaryczna informacja o eventach iEvents |= 2; // sumaryczna informacja o eventach
} }
else if (!asEvent1Name.empty()) else {
{ // Ra: tylko w logu informacja ErrorLog( "Bad track: event \"" + NewEvent1->asName + "\" cannot be assigned to track, track already has one" );
ErrorLog("Bad track: Event1 \"" + asEvent1Name + "\" does not exist");
bError = true; bError = true;
} }
} }
else
{ if( NewEvent2 == nullptr ) {
ErrorLog("Bad track: Event1 cannot be assigned to track, track already has one"); if( false == asEvent2Name.empty() ) {
bError = true; ErrorLog( "Bad event: event \"" + asEvent2Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
} }
if (!evEvent2) else {
{ if( evEvent2 == nullptr ) {
if (NewEvent2)
{
evEvent2 = NewEvent2; evEvent2 = NewEvent2;
asEvent2Name = ""; asEvent2Name = "";
iEvents |= 4; // sumaryczna informacja o eventach iEvents |= 4; // sumaryczna informacja o eventach
} }
else if (!asEvent2Name.empty()) else {
{ // Ra: tylko w logu informacja ErrorLog( "Bad track: event \"" + NewEvent2->asName + "\" cannot be assigned to track, track already has one" );
ErrorLog("Bad track: Event2 \"" + asEvent2Name + "\" does not exist");
bError = true; bError = true;
} }
} }
else
{ return ( bError == false );
ErrorLog("Bad track: Event2 cannot be assigned to track, track already has one");
bError = true;
}
return !bError;
} }
bool TTrack::AssignallEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2) bool TTrack::AssignallEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2)
{ {
bool bError = false; bool bError = false;
if (!evEventall0)
{ if( NewEvent0 == nullptr ) {
if (NewEvent0) if( false == asEventall0Name.empty() ) {
{ ErrorLog( "Bad event: event \"" + asEventall0Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
}
else {
if( evEventall0 == nullptr ) {
evEventall0 = NewEvent0; evEventall0 = NewEvent0;
asEventall0Name = ""; asEventall0Name = "";
iEvents |= 8; // sumaryczna informacja o eventach iEvents |= 8; // sumaryczna informacja o eventach
} }
else else {
{ ErrorLog( "Bad track: event \"" + NewEvent0->asName + "\" cannot be assigned to track, track already has one" );
if (!asEvent0Name.empty()) bError = true;
{
Error("Eventall0 \"" + asEventall0Name +
"\" does not exist");
bError = true;
}
} }
} }
else
{ if( NewEvent1 == nullptr ) {
Error("Eventall0 cannot be assigned to track, track already has one"); if( false == asEventall1Name.empty() ) {
bError = true; ErrorLog( "Bad event: event \"" + asEventall1Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
} }
if (!evEventall1) else {
{ if( evEventall1 == nullptr ) {
if (NewEvent1) evEventall1 = NewEvent0;
{
evEventall1 = NewEvent1;
asEventall1Name = ""; asEventall1Name = "";
iEvents |= 16; // sumaryczna informacja o eventach iEvents |= 16; // sumaryczna informacja o eventach
} }
else else {
{ ErrorLog( "Bad track: event \"" + NewEvent1->asName + "\" cannot be assigned to track, track already has one" );
if (!asEvent0Name.empty()) bError = true;
{ // Ra: tylko w logu informacja
WriteLog("Eventall1 \"" + asEventall1Name + "\" does not exist");
bError = true;
}
} }
} }
else
{ if( NewEvent2 == nullptr ) {
Error("Eventall1 cannot be assigned to track, track already has one"); if( false == asEventall2Name.empty() ) {
bError = true; ErrorLog( "Bad event: event \"" + asEventall2Name + "\" assigned to track \"" + pMyNode->asName + "\" does not exist" );
bError = true;
}
} }
if (!evEventall2) else {
{ if( evEventall2 == nullptr ) {
if (NewEvent2) evEventall2 = NewEvent0;
{
evEventall2 = NewEvent2;
asEventall2Name = ""; asEventall2Name = "";
iEvents |= 32; // sumaryczna informacja o eventach iEvents |= 32; // sumaryczna informacja o eventach
} }
else else {
{ ErrorLog( "Bad track: event \"" + NewEvent2->asName + "\" cannot be assigned to track, track already has one" );
if (!asEvent0Name.empty()) bError = true;
{ // Ra: tylko w logu informacja
WriteLog("Eventall2 \"" + asEventall2Name +
"\" does not exist");
bError = true;
}
} }
} }
else
{ return ( bError == false );
Error("Eventall2 cannot be assigned to track, track already has one");
bError = true;
}
return !bError;
} }
bool TTrack::AssignForcedEvents(TEvent *NewEventPlus, TEvent *NewEventMinus) bool TTrack::AssignForcedEvents(TEvent *NewEventPlus, TEvent *NewEventMinus)
@@ -1079,8 +1061,10 @@ bool TTrack::InMovement()
if (!SwitchExtension->CurrentIndex) if (!SwitchExtension->CurrentIndex)
return false; // 0=zablokowana się nie animuje return false; // 0=zablokowana się nie animuje
// trzeba każdorazowo porównywać z kątem modelu // trzeba każdorazowo porównywać z kątem modelu
TAnimContainer *ac = TAnimContainer *ac = (
SwitchExtension->pModel ? SwitchExtension->pModel->GetContainer(NULL) : NULL; SwitchExtension->pModel ?
SwitchExtension->pModel->GetContainer() :
nullptr );
return ac ? return ac ?
(ac->AngleGet() != SwitchExtension->fOffset) || (ac->AngleGet() != SwitchExtension->fOffset) ||
!(ac->TransGet() == SwitchExtension->vTrans) : !(ac->TransGet() == SwitchExtension->vTrans) :
@@ -1090,10 +1074,7 @@ bool TTrack::InMovement()
} }
return false; return false;
}; };
void TTrack::RaAssign(TGroundNode *gn, TAnimContainer *ac){
// Ra: wiązanie toru z modelem obrotnicy
// if (eType==tt_Table) SwitchExtension->pAnim=p;
};
void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined) void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined)
{ // Ra: wiązanie toru z modelem obrotnicy { // Ra: wiązanie toru z modelem obrotnicy
if (eType == tt_Table) if (eType == tt_Table)
@@ -1104,8 +1085,8 @@ void TTrack::RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joi
SwitchExtension->evPlus = SwitchExtension->evPlus =
joined; // event potwierdzenia połączenia (gdy nie znajdzie, to się nie połączy) joined; // event potwierdzenia połączenia (gdy nie znajdzie, to się nie połączy)
if (am) if (am)
if (am->GetContainer(NULL)) // może nie być? if (am->GetContainer()) // może nie być?
am->GetContainer(NULL)->EventAssign(done); // zdarzenie zakończenia animacji am->GetContainer()->EventAssign(done); // zdarzenie zakończenia animacji
} }
}; };
@@ -2172,9 +2153,10 @@ TTrack * TTrack::RaAnimate()
SwitchExtension->CurrentIndex) // 0=zablokowana się nie animuje SwitchExtension->CurrentIndex) // 0=zablokowana się nie animuje
{ // trzeba każdorazowo porównywać z kątem modelu { // trzeba każdorazowo porównywać z kątem modelu
// //pobranie kąta z modelu // //pobranie kąta z modelu
TAnimContainer *ac = SwitchExtension->pModel ? TAnimContainer *ac = (
SwitchExtension->pModel->GetContainer(NULL) : SwitchExtension->pModel ?
NULL; // pobranie głównego submodelu SwitchExtension->pModel->GetContainer() : // pobranie głównego submodelu
nullptr );
if (ac) if (ac)
if ((ac->AngleGet() != SwitchExtension->fOffset) || if ((ac->AngleGet() != SwitchExtension->fOffset) ||
!(ac->TransGet() == !(ac->TransGet() ==

View File

@@ -230,7 +230,6 @@ public:
if (SwitchExtension) if (SwitchExtension)
SwitchExtension->pOwner = o; }; SwitchExtension->pOwner = o; };
bool InMovement(); // czy w trakcie animacji? bool InMovement(); // czy w trakcie animacji?
void RaAssign(TGroundNode *gn, TAnimContainer *ac);
void RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined); void RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined);
void RaAnimListAdd(TTrack *t); void RaAnimListAdd(TTrack *t);
TTrack * RaAnimate(); TTrack * RaAnimate();

167
Train.cpp
View File

@@ -218,6 +218,9 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::trainbrakeservice, &TTrain::OnCommand_trainbrakeservice }, { user_command::trainbrakeservice, &TTrain::OnCommand_trainbrakeservice },
{ user_command::trainbrakefullservice, &TTrain::OnCommand_trainbrakefullservice }, { user_command::trainbrakefullservice, &TTrain::OnCommand_trainbrakefullservice },
{ user_command::trainbrakeemergency, &TTrain::OnCommand_trainbrakeemergency }, { user_command::trainbrakeemergency, &TTrain::OnCommand_trainbrakeemergency },
{ user_command::manualbrakeincrease, &TTrain::OnCommand_manualbrakeincrease },
{ user_command::manualbrakedecrease, &TTrain::OnCommand_manualbrakedecrease },
{ user_command::alarmchaintoggle, &TTrain::OnCommand_alarmchaintoggle },
{ user_command::wheelspinbrakeactivate, &TTrain::OnCommand_wheelspinbrakeactivate }, { user_command::wheelspinbrakeactivate, &TTrain::OnCommand_wheelspinbrakeactivate },
{ user_command::sandboxactivate, &TTrain::OnCommand_sandboxactivate }, { user_command::sandboxactivate, &TTrain::OnCommand_sandboxactivate },
{ user_command::epbrakecontroltoggle, &TTrain::OnCommand_epbrakecontroltoggle }, { user_command::epbrakecontroltoggle, &TTrain::OnCommand_epbrakecontroltoggle },
@@ -265,6 +268,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::hornlowactivate, &TTrain::OnCommand_hornlowactivate }, { user_command::hornlowactivate, &TTrain::OnCommand_hornlowactivate },
{ user_command::hornhighactivate, &TTrain::OnCommand_hornhighactivate }, { user_command::hornhighactivate, &TTrain::OnCommand_hornhighactivate },
{ user_command::radiotoggle, &TTrain::OnCommand_radiotoggle }, { user_command::radiotoggle, &TTrain::OnCommand_radiotoggle },
{ user_command::radiostoptest, &TTrain::OnCommand_radiostoptest },
{ user_command::generictoggle0, &TTrain::OnCommand_generictoggle }, { user_command::generictoggle0, &TTrain::OnCommand_generictoggle },
{ user_command::generictoggle1, &TTrain::OnCommand_generictoggle }, { user_command::generictoggle1, &TTrain::OnCommand_generictoggle },
{ user_command::generictoggle2, &TTrain::OnCommand_generictoggle }, { user_command::generictoggle2, &TTrain::OnCommand_generictoggle },
@@ -870,7 +874,7 @@ void TTrain::OnCommand_trainbrakecharging( TTrain *Train, command_data const &Co
void TTrain::OnCommand_trainbrakerelease( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_trainbrakerelease( TTrain *Train, command_data const &Command ) {
if( Command.action != GLFW_RELEASE ) { if( Command.action == GLFW_PRESS ) {
// sound feedback // sound feedback
if( ( Train->is_eztoer() ) if( ( Train->is_eztoer() )
@@ -885,7 +889,7 @@ void TTrain::OnCommand_trainbrakerelease( TTrain *Train, command_data const &Com
void TTrain::OnCommand_trainbrakefirstservice( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_trainbrakefirstservice( TTrain *Train, command_data const &Command ) {
if( Command.action != GLFW_RELEASE ) { if( Command.action == GLFW_PRESS ) {
// sound feedback // sound feedback
if( ( Train->is_eztoer() ) if( ( Train->is_eztoer() )
@@ -900,7 +904,7 @@ void TTrain::OnCommand_trainbrakefirstservice( TTrain *Train, command_data const
void TTrain::OnCommand_trainbrakeservice( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_trainbrakeservice( TTrain *Train, command_data const &Command ) {
if( Command.action != GLFW_RELEASE ) { if( Command.action == GLFW_PRESS ) {
// sound feedback // sound feedback
if( ( Train->is_eztoer() ) if( ( Train->is_eztoer() )
@@ -913,14 +917,14 @@ void TTrain::OnCommand_trainbrakeservice( TTrain *Train, command_data const &Com
Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->BrakeLevelSet(
Train->mvOccupied->BrakeCtrlPosNo / 2 Train->mvOccupied->BrakeCtrlPosNo / 2
+ ( Train->mvOccupied->BrakeHandle == FV4a ? + ( Train->mvOccupied->BrakeHandle == FV4a ?
1 : 1 :
0 ) ); 0 ) );
} }
} }
void TTrain::OnCommand_trainbrakefullservice( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_trainbrakefullservice( TTrain *Train, command_data const &Command ) {
if( Command.action != GLFW_RELEASE ) { if( Command.action == GLFW_PRESS ) {
// sound feedback // sound feedback
if( ( Train->is_eztoer() ) if( ( Train->is_eztoer() )
@@ -935,12 +939,57 @@ void TTrain::OnCommand_trainbrakefullservice( TTrain *Train, command_data const
void TTrain::OnCommand_trainbrakeemergency( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_trainbrakeemergency( TTrain *Train, command_data const &Command ) {
if( Command.action != GLFW_RELEASE ) { if( Command.action == GLFW_PRESS ) {
Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->Handle->GetPos( bh_EB ) ); Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->Handle->GetPos( bh_EB ) );
/*
if( Train->mvOccupied->BrakeCtrlPosNo <= 0.1 ) { if( Train->mvOccupied->BrakeCtrlPosNo <= 0.1 ) {
// hamulec bezpieczeństwa dla wagonów // hamulec bezpieczeństwa dla wagonów
Train->mvOccupied->EmergencyBrakeFlag = true; Train->mvOccupied->RadioStopFlag = true;
}
*/
}
}
void TTrain::OnCommand_manualbrakeincrease( TTrain *Train, command_data const &Command ) {
if( Command.action != GLFW_RELEASE ) {
if( ( Train->mvOccupied->LocalBrake == ManualBrake )
|| ( Train->mvOccupied->MBrake == true ) ) {
Train->mvOccupied->IncManualBrakeLevel( 1 );
}
}
}
void TTrain::OnCommand_manualbrakedecrease( TTrain *Train, command_data const &Command ) {
if( Command.action != GLFW_RELEASE ) {
if( ( Train->mvOccupied->LocalBrake == ManualBrake )
|| ( Train->mvOccupied->MBrake == true ) ) {
Train->mvOccupied->DecManualBrakeLevel( 1 );
}
}
}
void TTrain::OnCommand_alarmchaintoggle( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) {
if( false == Train->mvOccupied->AlarmChainFlag ) {
// pull
Train->mvOccupied->AlarmChainSwitch( true );
// visual feedback
Train->ggAlarmChain.UpdateValue( 1.0 );
}
else {
// release
Train->mvOccupied->AlarmChainSwitch( false );
// visual feedback
Train->ggAlarmChain.UpdateValue( 0.0 );
} }
} }
} }
@@ -2071,6 +2120,10 @@ void TTrain::OnCommand_headlighttoggleleft( TTrain *Train, command_data const &C
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left; Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left;
// visual feedback // visual feedback
Train->ggLeftLightButton.UpdateValue( 1.0, Train->dsbSwitch ); Train->ggLeftLightButton.UpdateValue( 1.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable marker light
if( Train->ggLeftEndLightButton.SubModel == nullptr ) {
Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::redmarker_left;
}
} }
else { else {
//turn off //turn off
@@ -2100,6 +2153,10 @@ void TTrain::OnCommand_headlighttoggleright( TTrain *Train, command_data const &
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right; Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right;
// visual feedback // visual feedback
Train->ggRightLightButton.UpdateValue( 1.0, Train->dsbSwitch ); Train->ggRightLightButton.UpdateValue( 1.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable marker light
if( Train->ggRightEndLightButton.SubModel == nullptr ) {
Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::redmarker_right;
}
} }
else { else {
//turn off //turn off
@@ -2157,13 +2214,29 @@ void TTrain::OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &C
// turn on // turn on
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left; Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left;
// visual feedback // visual feedback
Train->ggLeftEndLightButton.UpdateValue( 1.0, Train->dsbSwitch ); if( Train->ggLeftEndLightButton.SubModel != nullptr ) {
Train->ggLeftEndLightButton.UpdateValue( 1.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggLeftLightButton.UpdateValue( -1.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable the headlight
Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::headlight_left;
}
} }
else { else {
//turn off //turn off
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left; Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left;
// visual feedback // visual feedback
Train->ggLeftEndLightButton.UpdateValue( 0.0, Train->dsbSwitch ); if( Train->ggLeftEndLightButton.SubModel != nullptr ) {
Train->ggLeftEndLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggLeftLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
} }
} }
} }
@@ -2186,13 +2259,29 @@ void TTrain::OnCommand_redmarkertoggleright( TTrain *Train, command_data const &
// turn on // turn on
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right; Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right;
// visual feedback // visual feedback
Train->ggRightEndLightButton.UpdateValue( 1.0, Train->dsbSwitch ); if( Train->ggRightEndLightButton.SubModel != nullptr ) {
Train->ggRightEndLightButton.UpdateValue( 1.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggRightLightButton.UpdateValue( -1.0, Train->dsbSwitch );
// if the light is controlled by 3-way switch, disable the headlight
Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::headlight_right;
}
} }
else { else {
//turn off //turn off
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right; Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right;
// visual feedback // visual feedback
Train->ggRightEndLightButton.UpdateValue( 0.0, Train->dsbSwitch ); if( Train->ggRightEndLightButton.SubModel != nullptr ) {
Train->ggRightEndLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
else {
// we interpret lack of dedicated switch as a sign the light is controlled with 3-way switch
// this is crude, but for now will do
Train->ggRightLightButton.UpdateValue( 0.0, Train->dsbSwitch );
}
} }
} }
} }
@@ -2766,14 +2855,21 @@ void TTrain::OnCommand_radiotoggle( TTrain *Train, command_data const &Command )
} }
} }
void TTrain::OnCommand_radiostoptest( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) {
Train->Dynamic()->RadioStop();
}
}
void TTrain::OnKeyDown(int cKey) void TTrain::OnKeyDown(int cKey)
{ // naciśnięcie klawisza { // naciśnięcie klawisza
bool isEztOer; bool const isEztOer =
isEztOer = ((mvControlled->TrainType == dt_EZT) && (mvControlled->Battery == true) && ( ( mvControlled->TrainType == dt_EZT )
(mvControlled->EpFuse == true) && (mvOccupied->BrakeSubsystem == ss_ESt) && && ( mvControlled->Battery == true )
(mvControlled->ActiveDir != 0)); // od yB && ( mvControlled->EpFuse == true )
// isEztOer=(mvControlled->TrainType==dt_EZT)&&(mvControlled->Mains)&&(mvOccupied->BrakeSubsystem==ss_ESt)&&(mvControlled->ActiveDir!=0); && ( mvOccupied->BrakeSubsystem == ss_ESt )
// isEztOer=((mvControlled->TrainType==dt_EZT)&&(mvControlled->Battery==true)&&(mvControlled->EpFuse==true)&&(mvOccupied->BrakeSubsystem==Oerlikon)&&(mvControlled->ActiveDir!=0)); && ( mvControlled->ActiveDir != 0 ) ); // od yB
if (Global::shiftState) if (Global::shiftState)
{ // wciśnięty [Shift] { // wciśnięty [Shift]
@@ -2858,6 +2954,7 @@ void TTrain::OnKeyDown(int cKey)
} }
else // McZapkie-240302 - klawisze bez shifta else // McZapkie-240302 - klawisze bez shifta
{ {
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
if( cKey == Global::Keys[ k_IncLocalBrakeLevel ] ) if( cKey == Global::Keys[ k_IncLocalBrakeLevel ] )
{ // Ra 2014-09: w { // Ra 2014-09: w
// trybie latania // trybie latania
@@ -2870,10 +2967,8 @@ void TTrain::OnKeyDown(int cKey)
{ {
mvOccupied->IncManualBrakeLevel(1); mvOccupied->IncManualBrakeLevel(1);
} }
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
else if (mvOccupied->LocalBrake != ManualBrake) else if (mvOccupied->LocalBrake != ManualBrake)
mvOccupied->IncLocalBrakeLevel(1); mvOccupied->IncLocalBrakeLevel(1);
#endif
} }
} }
else if (cKey == Global::Keys[k_DecLocalBrakeLevel]) else if (cKey == Global::Keys[k_DecLocalBrakeLevel])
@@ -2886,16 +2981,15 @@ void TTrain::OnKeyDown(int cKey)
if (Global::ctrlState) if (Global::ctrlState)
if ((mvOccupied->LocalBrake == ManualBrake) || (mvOccupied->MBrake == true)) if ((mvOccupied->LocalBrake == ManualBrake) || (mvOccupied->MBrake == true))
mvOccupied->DecManualBrakeLevel(1); mvOccupied->DecManualBrakeLevel(1);
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
else // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku - else // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku -
// odhamować jakoś trzeba // odhamować jakoś trzeba
if ((mvOccupied->LocalBrake != ManualBrake) || mvOccupied->LocalBrakePos) if ((mvOccupied->LocalBrake != ManualBrake) || mvOccupied->LocalBrakePos)
mvOccupied->DecLocalBrakeLevel(1); mvOccupied->DecLocalBrakeLevel(1);
#endif
} }
} }
else if (cKey == Global::Keys[k_Brake2]) else
{ #endif
if (cKey == Global::Keys[k_Brake2]) {
if (Global::ctrlState) if (Global::ctrlState)
mvOccupied->BrakeLevelSet( mvOccupied->BrakeLevelSet(
mvOccupied->Handle->GetPos(bh_NP)); // yB: czy ten stos funkcji nie powinien być jako oddzielna funkcja movera? mvOccupied->Handle->GetPos(bh_NP)); // yB: czy ten stos funkcji nie powinien być jako oddzielna funkcja movera?
@@ -6439,6 +6533,7 @@ void TTrain::clear_cab_controls()
ggBrakeCtrl.Clear(); ggBrakeCtrl.Clear();
ggLocalBrake.Clear(); ggLocalBrake.Clear();
ggManualBrake.Clear(); ggManualBrake.Clear();
ggAlarmChain.Clear();
ggBrakeProfileCtrl.Clear(); ggBrakeProfileCtrl.Clear();
ggBrakeProfileG.Clear(); ggBrakeProfileG.Clear();
ggBrakeProfileR.Clear(); ggBrakeProfileR.Clear();
@@ -6566,8 +6661,8 @@ void TTrain::clear_cab_controls()
ggRearUpperLightButton.Clear(); ggRearUpperLightButton.Clear();
ggRearLeftEndLightButton.Clear(); ggRearLeftEndLightButton.Clear();
ggRearRightEndLightButton.Clear(); ggRearRightEndLightButton.Clear();
btHaslerBrakes.Clear(12); // ciśnienie w cylindrach do odbijania na haslerze btHaslerBrakes.Clear(12); // ciśnienie w cylindrach do odbijania na haslerze
btHaslerCurrent.Clear(13); // prąd na silnikach do odbijania na haslerze btHaslerCurrent.Clear(13); // prąd na silnikach do odbijania na haslerze
} }
// NOTE: we can get rid of this function once we have per-cab persistent state // NOTE: we can get rid of this function once we have per-cab persistent state
@@ -6667,10 +6762,20 @@ void TTrain::set_cab_controls() {
ggUpperLightButton.PutValue( 1.0 ); ggUpperLightButton.PutValue( 1.0 );
} }
if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_left ) != 0 ) { if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_left ) != 0 ) {
ggLeftEndLightButton.PutValue( 1.0 ); if( ggLeftEndLightButton.SubModel != nullptr ) {
ggLeftEndLightButton.PutValue( 1.0 );
}
else {
ggLeftLightButton.PutValue( -1.0 );
}
} }
if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_right ) != 0 ) { if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_right ) != 0 ) {
ggRightEndLightButton.PutValue( 1.0 ); if( ggRightEndLightButton.SubModel != nullptr ) {
ggRightEndLightButton.PutValue( 1.0 );
}
else {
ggRightLightButton.PutValue( -1.0 );
}
} }
if( true == DynamicObject->DimHeadlights ) { if( true == DynamicObject->DimHeadlights ) {
ggDimHeadlightsButton.PutValue( 1.0 ); ggDimHeadlightsButton.PutValue( 1.0 );
@@ -6716,6 +6821,11 @@ void TTrain::set_cab_controls() {
1.0 : 1.0 :
0.0 ); 0.0 );
} }
// alarm chain
ggAlarmChain.PutValue(
mvControlled->AlarmChainFlag ?
1.0 :
0.0 );
// brake signalling // brake signalling
ggSignallingButton.PutValue( ggSignallingButton.PutValue(
mvControlled->Signalling ? mvControlled->Signalling ?
@@ -6984,6 +7094,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
{ "brakectrl:", ggBrakeCtrl }, { "brakectrl:", ggBrakeCtrl },
{ "localbrake:", ggLocalBrake }, { "localbrake:", ggLocalBrake },
{ "manualbrake:", ggManualBrake }, { "manualbrake:", ggManualBrake },
{ "alarmchain:", ggAlarmChain },
{ "brakeprofile_sw:", ggBrakeProfileCtrl }, { "brakeprofile_sw:", ggBrakeProfileCtrl },
{ "brakeprofileg_sw:", ggBrakeProfileG }, { "brakeprofileg_sw:", ggBrakeProfileG },
{ "brakeprofiler_sw:", ggBrakeProfileR }, { "brakeprofiler_sw:", ggBrakeProfileR },

View File

@@ -140,6 +140,9 @@ class TTrain
static void OnCommand_trainbrakeservice( TTrain *Train, command_data const &Command ); static void OnCommand_trainbrakeservice( TTrain *Train, command_data const &Command );
static void OnCommand_trainbrakefullservice( TTrain *Train, command_data const &Command ); static void OnCommand_trainbrakefullservice( TTrain *Train, command_data const &Command );
static void OnCommand_trainbrakeemergency( TTrain *Train, command_data const &Command ); static void OnCommand_trainbrakeemergency( TTrain *Train, command_data const &Command );
static void OnCommand_manualbrakeincrease( TTrain *Train, command_data const &Command );
static void OnCommand_manualbrakedecrease( TTrain *Train, command_data const &Command );
static void OnCommand_alarmchaintoggle( TTrain *Train, command_data const &Command );
static void OnCommand_wheelspinbrakeactivate( TTrain *Train, command_data const &Command ); static void OnCommand_wheelspinbrakeactivate( TTrain *Train, command_data const &Command );
static void OnCommand_sandboxactivate( TTrain *Train, command_data const &Command ); static void OnCommand_sandboxactivate( TTrain *Train, command_data const &Command );
static void OnCommand_epbrakecontroltoggle( TTrain *Train, command_data const &Command ); static void OnCommand_epbrakecontroltoggle( TTrain *Train, command_data const &Command );
@@ -187,6 +190,7 @@ class TTrain
static void OnCommand_hornlowactivate( TTrain *Train, command_data const &Command ); static void OnCommand_hornlowactivate( TTrain *Train, command_data const &Command );
static void OnCommand_hornhighactivate( TTrain *Train, command_data const &Command ); static void OnCommand_hornhighactivate( TTrain *Train, command_data const &Command );
static void OnCommand_radiotoggle( TTrain *Train, command_data const &Command ); static void OnCommand_radiotoggle( TTrain *Train, command_data const &Command );
static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command );
static void OnCommand_generictoggle( TTrain *Train, command_data const &Command ); static void OnCommand_generictoggle( TTrain *Train, command_data const &Command );
// members // members
@@ -226,6 +230,7 @@ public: // reszta może by?publiczna
TGauge ggBrakeCtrl; TGauge ggBrakeCtrl;
TGauge ggLocalBrake; TGauge ggLocalBrake;
TGauge ggManualBrake; TGauge ggManualBrake;
TGauge ggAlarmChain;
TGauge ggBrakeProfileCtrl; // nastawiacz GPR - przelacznik obrotowy TGauge ggBrakeProfileCtrl; // nastawiacz GPR - przelacznik obrotowy
TGauge ggBrakeProfileG; // nastawiacz GP - hebelek towarowy TGauge ggBrakeProfileG; // nastawiacz GP - hebelek towarowy
TGauge ggBrakeProfileR; // nastawiacz PR - hamowanie dwustopniowe TGauge ggBrakeProfileR; // nastawiacz PR - hamowanie dwustopniowe

View File

@@ -41,6 +41,9 @@ commanddescription_sequence Commands_descriptions = {
{ "trainbrakeservice", command_target::vehicle }, { "trainbrakeservice", command_target::vehicle },
{ "trainbrakefullservice", command_target::vehicle }, { "trainbrakefullservice", command_target::vehicle },
{ "trainbrakeemergency", command_target::vehicle }, { "trainbrakeemergency", command_target::vehicle },
{ "manualbrakeincrease", command_target::vehicle },
{ "manualbrakedecrease", command_target::vehicle },
{ "alarmchaintoggle", command_target::vehicle },
{ "wheelspinbrakeactivate", command_target::vehicle }, { "wheelspinbrakeactivate", command_target::vehicle },
{ "sandboxactivate", command_target::vehicle }, { "sandboxactivate", command_target::vehicle },
{ "reverserincrease", command_target::vehicle }, { "reverserincrease", command_target::vehicle },
@@ -62,6 +65,7 @@ commanddescription_sequence Commands_descriptions = {
{ "hornlowactivate", command_target::vehicle }, { "hornlowactivate", command_target::vehicle },
{ "hornhighactivate", command_target::vehicle }, { "hornhighactivate", command_target::vehicle },
{ "radiotoggle", command_target::vehicle }, { "radiotoggle", command_target::vehicle },
{ "radiostoptest", command_target::vehicle },
/* /*
const int k_FailedEngineCutOff = 35; const int k_FailedEngineCutOff = 35;
*/ */
@@ -118,10 +122,6 @@ const int k_ProgramHelp = 48;
{ "interiorlightdimtoggle", command_target::vehicle }, { "interiorlightdimtoggle", command_target::vehicle },
{ "instrumentlighttoggle", command_target::vehicle }, { "instrumentlighttoggle", command_target::vehicle },
/* /*
const int k_Univ1 = 66;
const int k_Univ2 = 67;
const int k_Univ3 = 68;
const int k_Univ4 = 69;
const int k_EndSign = 70; const int k_EndSign = 70;
const int k_Active = 71; const int k_Active = 71;
*/ */

View File

@@ -36,6 +36,9 @@ enum class user_command {
trainbrakeservice, trainbrakeservice,
trainbrakefullservice, trainbrakefullservice,
trainbrakeemergency, trainbrakeemergency,
manualbrakeincrease,
manualbrakedecrease,
alarmchaintoggle,
wheelspinbrakeactivate, wheelspinbrakeactivate,
sandboxactivate, sandboxactivate,
reverserincrease, reverserincrease,
@@ -57,6 +60,7 @@ enum class user_command {
hornlowactivate, hornlowactivate,
hornhighactivate, hornhighactivate,
radiotoggle, radiotoggle,
radiostoptest,
/* /*
const int k_FailedEngineCutOff = 35; const int k_FailedEngineCutOff = 35;
*/ */

View File

@@ -208,6 +208,12 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_KP_2 }, { GLFW_KEY_KP_2 },
// trainbrakeemergency // trainbrakeemergency
{ GLFW_KEY_KP_0 }, { GLFW_KEY_KP_0 },
// manualbrakeincrease
{ GLFW_KEY_KP_1 | keymodifier::control },
// manualbrakedecrease
{ GLFW_KEY_KP_7 | keymodifier::control },
// alarm chain toggle
{ GLFW_KEY_B | keymodifier::shift | keymodifier::control },
// wheelspinbrakeactivate, // wheelspinbrakeactivate,
{ GLFW_KEY_KP_ENTER }, { GLFW_KEY_KP_ENTER },
// sandboxactivate, // sandboxactivate,
@@ -250,6 +256,8 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_A | keymodifier::shift }, { GLFW_KEY_A | keymodifier::shift },
// radiotoggle // radiotoggle
{ GLFW_KEY_R | keymodifier::control }, { GLFW_KEY_R | keymodifier::control },
// radiostoptest
{ GLFW_KEY_R | keymodifier::shift | keymodifier::control },
// viewturn // viewturn
{ -1 }, { -1 },
// movevector // movevector

View File

@@ -211,7 +211,10 @@ mouse_input::default_bindings() {
user_command::independentbrakeincrease, user_command::independentbrakeincrease,
user_command::independentbrakedecrease } }, user_command::independentbrakedecrease } },
{ "manualbrake:", { { "manualbrake:", {
user_command::none, user_command::manualbrakeincrease,
user_command::manualbrakedecrease } },
{ "alarmchain:", {
user_command::alarmchaintoggle,
user_command::none } }, user_command::none } },
{ "brakeprofile_sw:", { { "brakeprofile_sw:", {
user_command::brakeactingspeedincrease, user_command::brakeactingspeedincrease,

View File

@@ -21,33 +21,33 @@ http://mozilla.org/MPL/2.0/.
// cParser -- generic class for parsing text data. // cParser -- generic class for parsing text data.
// constructors // constructors
cParser::cParser( std::string const &Stream, buffertype const Type, std::string Path, bool const Loadtraction ) cParser::cParser( std::string const &Stream, buffertype const Type, std::string Path, bool const Loadtraction ) :
{ mPath(Path),
LoadTraction = Loadtraction; LoadTraction( Loadtraction ) {
// build comments map // build comments map
mComments.insert(commentmap::value_type("/*", "*/")); mComments.insert(commentmap::value_type("/*", "*/"));
mComments.insert(commentmap::value_type("//", "\n")); mComments.insert(commentmap::value_type("//", "\n"));
// mComments.insert(commentmap::value_type("--","\n")); //Ra: to chyba nie używane // mComments.insert(commentmap::value_type("--","\n")); //Ra: to chyba nie używane
// store to calculate sub-sequent includes from relative path // store to calculate sub-sequent includes from relative path
mPath = Path;
if( Type == buffertype::buffer_FILE ) { if( Type == buffertype::buffer_FILE ) {
mFile = Stream; mFile = Stream;
} }
// reset pointers and attach proper type of buffer // reset pointers and attach proper type of buffer
switch (Type) switch (Type) {
{ case buffer_FILE: {
case buffer_FILE: Path.append( Stream );
Path.append(Stream); std::replace(Path.begin(), Path.end(), '\\', '/');
std::replace(Path.begin(), Path.end(), '\\', '/'); mStream = std::make_shared<std::ifstream>( Path );
mStream = new std::ifstream(Path); break;
break; }
case buffer_TEXT: case buffer_TEXT: {
mStream = new std::istringstream(Stream); mStream = std::make_shared<std::istringstream>( Stream );
break; break;
default: }
mStream = NULL; default: {
break;
}
} }
mIncludeParser = NULL;
// calculate stream size // calculate stream size
if (mStream) if (mStream)
{ {
@@ -57,19 +57,14 @@ cParser::cParser( std::string const &Stream, buffertype const Type, std::string
else { else {
mSize = mStream->rdbuf()->pubseekoff( 0, std::ios_base::end ); mSize = mStream->rdbuf()->pubseekoff( 0, std::ios_base::end );
mStream->rdbuf()->pubseekoff( 0, std::ios_base::beg ); mStream->rdbuf()->pubseekoff( 0, std::ios_base::beg );
mLine = 1;
} }
} }
else
mSize = 0;
} }
// destructor // destructor
cParser::~cParser() cParser::~cParser() {
{
if (mIncludeParser)
delete mIncludeParser;
if (mStream)
delete mStream;
mComments.clear(); mComments.clear();
} }
@@ -158,7 +153,7 @@ std::string cParser::readToken(bool ToLower, const char *Break)
// see if there's include parsing going on. clean up when it's done. // see if there's include parsing going on. clean up when it's done.
if (mIncludeParser) if (mIncludeParser)
{ {
token = (*mIncludeParser).readToken(ToLower, Break); token = mIncludeParser->readToken(ToLower, Break);
if (!token.empty()) if (!token.empty())
{ {
pos = token.find("(p"); pos = token.find("(p");
@@ -183,13 +178,12 @@ std::string cParser::readToken(bool ToLower, const char *Break)
} }
else else
{ {
delete mIncludeParser;
mIncludeParser = NULL; mIncludeParser = NULL;
parameters.clear(); parameters.clear();
} }
} }
// get the token yourself if there's no child to delegate it to. // get the token yourself if there's no child to delegate it to.
char c; char c { 0 };
do do
{ {
while (mStream->peek() != EOF && strchr(Break, c = mStream->get()) == NULL) while (mStream->peek() != EOF && strchr(Break, c = mStream->get()) == NULL)
@@ -202,6 +196,10 @@ std::string cParser::readToken(bool ToLower, const char *Break)
if (trimComments(token)) // don't glue together words separated with comment if (trimComments(token)) // don't glue together words separated with comment
break; break;
} }
if( c == '\n' ) {
// update line counter
++mLine;
}
} while (token == "" && mStream->peek() != EOF); // double check to deal with trailing spaces } while (token == "" && mStream->peek() != EOF); // double check to deal with trailing spaces
// launch child parser if include directive found. // launch child parser if include directive found.
// NOTE: parameter collecting uses default set of token separators. // NOTE: parameter collecting uses default set of token separators.
@@ -219,16 +217,18 @@ std::string cParser::readToken(bool ToLower, const char *Break)
&& (parameter.compare("end") != 0) ) && (parameter.compare("end") != 0) )
{ {
parameters.push_back(parameter); parameters.push_back(parameter);
parameter = readToken(ToLower); parameter = readToken(false);
} }
// if (trtest2.find("tr/")!=0) // if (trtest2.find("tr/")!=0)
mIncludeParser = new cParser(includefile, buffer_FILE, mPath, LoadTraction); mIncludeParser = std::make_shared<cParser>(includefile, buffer_FILE, mPath, LoadTraction);
if (mIncludeParser->mSize <= 0) if (mIncludeParser->mSize <= 0)
ErrorLog("Missed include: " + includefile); ErrorLog("Missed include: " + includefile);
} }
else else {
while (token.compare("end") != 0) while( token.compare( "end" ) != 0 ) {
token = readToken(ToLower); token = readToken( true ); // minimize risk of case mismatch on comparison
}
}
token = readToken(ToLower, Break); token = readToken(ToLower, Break);
} }
return token; return token;
@@ -236,8 +236,12 @@ std::string cParser::readToken(bool ToLower, const char *Break)
std::string cParser::readQuotes(char const Quote) { // read the stream until specified char or stream end std::string cParser::readQuotes(char const Quote) { // read the stream until specified char or stream end
std::string token = ""; std::string token = "";
char c; char c { 0 };
while( mStream->peek() != EOF && Quote != (c = mStream->get()) ) { // get all chars until the quote mark while( mStream->peek() != EOF && Quote != (c = mStream->get()) ) { // get all chars until the quote mark
if( c == '\n' ) {
// update line counter
++mLine;
}
token += c; token += c;
} }
return token; return token;
@@ -245,9 +249,16 @@ std::string cParser::readQuotes(char const Quote) { // read the stream until spe
void cParser::skipComment( std::string const &Endmark ) { // pobieranie znaków aż do znalezienia znacznika końca void cParser::skipComment( std::string const &Endmark ) { // pobieranie znaków aż do znalezienia znacznika końca
std::string input = ""; std::string input = "";
char c { 0 };
auto const endmarksize = Endmark.size(); auto const endmarksize = Endmark.size();
while( mStream->peek() != EOF ) { // o ile nie koniec pliku while( mStream->peek() != EOF ) {
input += mStream->get(); // pobranie znaku // o ile nie koniec pliku
c = mStream->get(); // pobranie znaku
if( c == '\n' ) {
// update line counter
++mLine;
}
input += c;
if( input.find( Endmark ) != std::string::npos ) // szukanie znacznika końca if( input.find( Endmark ) != std::string::npos ) // szukanie znacznika końca
break; break;
if( input.size() >= endmarksize ) { if( input.size() >= endmarksize ) {
@@ -303,7 +314,7 @@ std::size_t cParser::countTokens( std::string const &Stream, std::string Path )
std::size_t cParser::count() { std::size_t cParser::count() {
std::string token; std::string token;
size_t count{ 0 }; size_t count { 0 };
do { do {
token = ""; token = "";
token = readToken( false ); token = readToken( false );
@@ -320,8 +331,16 @@ void cParser::addCommentStyle( std::string const &Commentstart, std::string cons
// returns name of currently open file, or empty string for text type stream // returns name of currently open file, or empty string for text type stream
std::string std::string
cParser::Name() { cParser::Name() const {
if( mIncludeParser ) { return mIncludeParser->Name(); } if( mIncludeParser ) { return mIncludeParser->Name(); }
else { return mPath + mFile; } else { return mPath + mFile; }
} }
// returns number of currently processed line
std::size_t
cParser::Line() const {
if( mIncludeParser ) { return mIncludeParser->Line(); }
else { return mLine; }
}

View File

@@ -78,7 +78,9 @@ class cParser //: public std::stringstream
// add custom definition of text which should be ignored when retrieving tokens // add custom definition of text which should be ignored when retrieving tokens
void addCommentStyle( std::string const &Commentstart, std::string const &Commentend ); void addCommentStyle( std::string const &Commentstart, std::string const &Commentend );
// returns name of currently open file, or empty string for text type stream // returns name of currently open file, or empty string for text type stream
std::string Name(); std::string Name() const;
// returns number of currently processed line
std::size_t Line() const;
private: private:
// methods: // methods:
@@ -90,13 +92,14 @@ class cParser //: public std::stringstream
std::size_t count(); std::size_t count();
// members: // members:
bool LoadTraction; // load traction? bool LoadTraction; // load traction?
std::istream *mStream; // relevant kind of buffer is attached on creation. std::shared_ptr<std::istream> mStream; // relevant kind of buffer is attached on creation.
std::string mFile; // name of the open file, if any std::string mFile; // name of the open file, if any
std::string mPath; // path to open stream, for relative path lookups. std::string mPath; // path to open stream, for relative path lookups.
std::streamoff mSize; // size of open stream, for progress report. std::streamoff mSize { 0 }; // size of open stream, for progress report.
std::size_t mLine { 0 }; // currently processed line
typedef std::map<std::string, std::string> commentmap; typedef std::map<std::string, std::string> commentmap;
commentmap mComments; commentmap mComments;
cParser *mIncludeParser; // child class to handle include directives. std::shared_ptr<cParser> mIncludeParser; // child class to handle include directives.
std::vector<std::string> parameters; // parameter list for included file. std::vector<std::string> parameters; // parameter list for included file.
std::deque<std::string> tokens; std::deque<std::string> tokens;
}; };

View File

@@ -24,6 +24,7 @@ static std::unordered_map<std::string, std::string> m_cabcontrols = {
{ "brakectrl:", "train brake" }, { "brakectrl:", "train brake" },
{ "localbrake:", "independent brake" }, { "localbrake:", "independent brake" },
{ "manualbrake:", "manual brake" }, { "manualbrake:", "manual brake" },
{ "alarmchain:", "emergency brake" },
{ "brakeprofile_sw:", "brake acting speed" }, { "brakeprofile_sw:", "brake acting speed" },
{ "brakeprofileg_sw:", "brake acting speed: cargo" }, { "brakeprofileg_sw:", "brake acting speed: cargo" },
{ "brakeprofiler_sw:", "brake acting speed: rapid" }, { "brakeprofiler_sw:", "brake acting speed: rapid" },

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 17 #define VERSION_MAJOR 17
#define VERSION_MINOR 828 #define VERSION_MINOR 831
#define VERSION_REVISION 0 #define VERSION_REVISION 0