16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-20 12:39:17 +02:00

3d model-related log message filtering, diesel electric engine force calculation tweak, minor bug fixes

This commit is contained in:
tmj-fstate
2018-01-17 01:48:20 +01:00
parent 88c19b2817
commit 4dfe32f34b
14 changed files with 139 additions and 129 deletions

View File

@@ -71,7 +71,7 @@ void TButton::Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *pMod
if( ( pModelOn == nullptr )
&& ( pModelOff == nullptr ) ) {
// if we failed to locate even one state submodel, cry
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model \"" + pModel1->NameGet() + "\"" );
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model \"" + pModel1->NameGet() + "\"", logtype::model );
}
// pass submodel location to defined sounds

View File

@@ -356,16 +356,16 @@ void Console::ValueSet(int x, double y)
{
x = Global::iPoKeysPWM[x];
if (Global::iCalibrateOutDebugInfo == x)
WriteLog("CalibrateOutDebugInfo: oryginal=" + std::to_string(y), false);
WriteLog("CalibrateOutDebugInfo: oryginal=" + std::to_string(y));
if (Global::fCalibrateOutMax[x] > 0)
{
y = clamp( y, 0.0, Global::fCalibrateOutMax[x]);
if (Global::iCalibrateOutDebugInfo == x)
WriteLog(" cutted=" + std::to_string(y), false);
WriteLog(" cutted=" + std::to_string(y));
y = y / Global::fCalibrateOutMax[x]; // sprowadzenie do <0,1> jeśli podana
// maksymalna wartość
if (Global::iCalibrateOutDebugInfo == x)
WriteLog(" fraction=" + std::to_string(y), false);
WriteLog(" fraction=" + std::to_string(y));
}
double temp = (((((Global::fCalibrateOut[x][5] * y) + Global::fCalibrateOut[x][4]) * y +
Global::fCalibrateOut[x][3]) *

View File

@@ -3710,7 +3710,7 @@ void TDynamicObject::RenderSounds() {
if( brakeforceratio > 0.0 ) {
// hamulce wzmagaja halas
volume *= 1 + 0.25 * brakeforceratio;
volume *= 1 + 0.125 * brakeforceratio;
}
// scale volume by track quality
volume *= ( 20.0 + MyTrack->iDamageFlag ) / 21;
@@ -3994,9 +3994,12 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
}
else {
// Ra: tu wczytywanie modelu ładunku jest w porządku
if( false == asLoadName.empty() ) {
// try first specialized version of the load model, vehiclename_loadname
mdLoad = TModelsManager::GetModel( BaseDir + TypeName + "_" + MoverParameters->LoadType + ".t3d", true );
if( false == asLoadName.empty() ) {
// try first specialized version of the load model, vehiclename_loadname
auto const specializedloadfilename { BaseDir + TypeName + "_" + MoverParameters->LoadType + ".t3d" };
if( true == FileExists( specializedloadfilename ) ) {
mdLoad = TModelsManager::GetModel( specializedloadfilename, true );
}
if( mdLoad == nullptr ) {
// if this fails, try generic load model
mdLoad = TModelsManager::GetModel( asLoadName, true );
@@ -4246,15 +4249,15 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
{ // gdy ktoś przesadził ze skalowaniem
pants[i].fParamPants->fHeight =
0.0; // niech będzie odczyt z pantfactors:
ErrorLog("Bad model: " + asModel + ", scale of " +
(sm->pName) + " is " +
std::to_string(100.0 * det) + "%");
ErrorLog(
"Bad model: " + asModel + ", scale of " + (sm->pName) + " is " + std::to_string(100.0 * det) + "%",
logtype::model );
}
}
}
}
else
ErrorLog("Bad model: " + asFileName + " - missed submodel " + asAnimName); // brak ramienia
ErrorLog("Bad model: " + asFileName + " - missed submodel " + asAnimName, logtype::model); // brak ramienia
}
}
@@ -4288,7 +4291,7 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
}
}
else
ErrorLog( "Bad model: " + asFileName + " - missed submodel " + asAnimName ); // brak ramienia
ErrorLog( "Bad model: " + asFileName + " - missed submodel " + asAnimName, logtype::model ); // brak ramienia
}
}
}
@@ -5584,7 +5587,7 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
engine_revs_last = Vehicle.enrot * 60;
auto const enginerevfrequency { (
false == engine_revving.is_combined() ?
true == engine_revving.is_combined() ?
// if the sound contains multiple samples we reuse rpm-based calculation from the engine
frequency :
engine_revving.m_frequencyoffset + 1.f * engine_revving.m_frequencyfactor ) };

View File

@@ -99,7 +99,7 @@ bool TGauge::Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *md1,
scale *= mul;
TSubModel *submodel = md1->GetFromName( submodelname );
if( scale == 0.0 ) {
ErrorLog( "Bad model: 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( "Bad model: scale of 0.0 defined for sub-model \"" + submodelname + "\" in 3d model \"" + md1->NameGet() + "\". Forcing scale of 1.0 to prevent division by 0", logtype::model );
scale = 1.0;
}
if (submodel) // jeśli nie znaleziony
@@ -107,7 +107,7 @@ bool TGauge::Load( cParser &Parser, TDynamicObject const *Owner, TModel3d *md1,
else if (md2) // a jest podany drugi model (np. zewnętrzny)
submodel = md2->GetFromName(submodelname); // to może tam będzie, co za różnica gdzie
if( submodel == nullptr ) {
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model \"" + md1->NameGet() + "\"" );
ErrorLog( "Bad model: failed to locate sub-model \"" + submodelname + "\" in 3d model \"" + md1->NameGet() + "\"", logtype::model );
}
std::map<std::string, TGaugeType> gaugetypes {

View File

@@ -139,7 +139,8 @@ float Global::AudioVolume = 1.5f;
std::string Global::AudioRenderer;
int Global::iWriteLogEnabled = 3; // maska bitowa: 1-zapis do pliku, 2-okienko, 4-nazwy torów
bool Global::MultipleLogs{ false };
bool Global::MultipleLogs { false };
unsigned int Global::DisabledLogTypes { 0 };
// parametry do kalibracji
// kolejno współczynniki dla potęg 0, 1, 2, 3 wartości odczytanej z urządzenia
@@ -331,6 +332,10 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens();
Parser >> Global::MultipleLogs;
}
else if( token == "logs.filter" ) {
Parser.getTokens();
Parser >> Global::DisabledLogTypes;
}
else if( token == "adjustscreenfreq" )
{
// McZapkie-240403 - czestotliwosc odswiezania ekranu

View File

@@ -181,6 +181,7 @@ public:
static std::string asCurrentDynamicPath;
static int iWriteLogEnabled; // maska bitowa: 1-zapis do pliku, 2-okienko
static bool MultipleLogs;
static unsigned int DisabledLogTypes;
// McZapkie-170602: zewnetrzna definicja pojazdu uzytkownika
static std::string asHumanCtrlVehicle;
// world environment

View File

@@ -47,75 +47,50 @@ std::string filename_scenery() {
}
}
void WriteConsoleOnly(const char *str, double value) {
void WriteLog( const char *str, logtype const Type ) {
std::snprintf(logbuffer , sizeof(logbuffer), "%s %f \n", str, value);
// stdout= GetStdHandle(STD_OUTPUT_HANDLE);
DWORD wr = 0;
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), logbuffer, (DWORD)strlen(logbuffer), &wr, NULL);
// WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),endstring,strlen(endstring),&wr,NULL);
}
if( str == nullptr ) { return; }
if( true == TestFlag( Global::DisabledLogTypes, Type ) ) { return; }
void WriteConsoleOnly(const char *str, bool newline)
{
// printf("%n ffafaf /n",str);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
FOREGROUND_GREEN | FOREGROUND_INTENSITY);
DWORD wr = 0;
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), str, (DWORD)strlen(str), &wr, NULL);
if (newline)
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), endstring, (DWORD)strlen(endstring), &wr, NULL);
}
if (Global::iWriteLogEnabled & 1) {
if( !output.is_open() ) {
void WriteLog(const char *str, double value) {
if (Global::iWriteLogEnabled) {
if (str) {
std::snprintf(logbuffer, sizeof(logbuffer), "%s %f", str, value);
WriteLog(logbuffer);
}
}
};
void WriteLog(const char *str, bool newline)
{
if (str)
{
if (Global::iWriteLogEnabled & 1)
{
if( !output.is_open() ) {
std::string const filename =
( Global::MultipleLogs ?
std::string const filename =
( Global::MultipleLogs ?
"logs/log (" + filename_scenery() + ") " + filename_date() + ".txt" :
"log.txt" );
output.open( filename, std::ios::trunc );
}
output << str;
if (newline)
output << "\n";
output.flush();
output.open( filename, std::ios::trunc );
}
// hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana
if (Global::iWriteLogEnabled & 2)
WriteConsoleOnly(str, newline);
output << str << "\n";
output.flush();
}
};
void ErrorLog(const char *str)
{ // Ra: bezwarunkowa rejestracja poważnych błędów
if( Global::iWriteLogEnabled & 2 ) {
// hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN | FOREGROUND_INTENSITY );
DWORD wr = 0;
WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), str, (DWORD)strlen( str ), &wr, NULL );
WriteConsole( GetStdHandle( STD_OUTPUT_HANDLE ), endstring, (DWORD)strlen( endstring ), &wr, NULL );
}
}
// Ra: bezwarunkowa rejestracja poważnych błędów
void ErrorLog( const char *str, logtype const Type ) {
if( str == nullptr ) { return; }
if( true == TestFlag( Global::DisabledLogTypes, Type ) ) { return; }
if (!errors.is_open()) {
std::string const filename =
( Global::MultipleLogs ?
"logs/errors (" + filename_scenery() + ") " + filename_date() + ".txt" :
"errors.txt" );
"logs/errors (" + filename_scenery() + ") " + filename_date() + ".txt" :
"errors.txt" );
errors.open( filename, std::ios::trunc );
errors << "EU07.EXE " + Global::asVersion << "\n";
}
if (str)
errors << str;
errors << "\n";
errors << str << "\n";
errors.flush();
};
@@ -134,15 +109,15 @@ void Error(const char *&asMessage, bool box)
WriteLog(asMessage);
}
void ErrorLog(const std::string &str, bool newline)
void ErrorLog(const std::string &str, logtype const Type )
{
ErrorLog(str.c_str());
WriteLog(str.c_str(), newline);
ErrorLog( str.c_str(), Type );
WriteLog( str.c_str(), Type );
}
void WriteLog(const std::string &str, bool newline)
void WriteLog(const std::string &str, logtype const Type )
{ // Ra: wersja z AnsiString jest zamienna z Error()
WriteLog(str.c_str(), newline);
WriteLog( str.c_str(), Type );
};
void CommLog(const char *str)

24
Logs.h
View File

@@ -10,13 +10,17 @@ http://mozilla.org/MPL/2.0/.
#pragma once
#include <string>
void WriteConsoleOnly(const char *str, double value);
void WriteConsoleOnly(const char *str, bool newline = true);
void WriteLog(const char *str, double value);
void WriteLog(const char *str, bool newline = true);
void Error(const std::string &asMessage, bool box = false);
void Error(const char* &asMessage, bool box = false);
void ErrorLog(const std::string &str, bool newline = true);
void WriteLog(const std::string &str, bool newline = true);
void CommLog(const char *str);
void CommLog(const std::string &str);
enum logtype : unsigned int {
generic = 0x1,
file = 0x2,
model = 0x4
};
void WriteLog( const char *str, logtype const Type = logtype::generic );
void Error( const std::string &asMessage, bool box = false );
void Error( const char* &asMessage, bool box = false );
void ErrorLog( const std::string &str, logtype const Type = logtype::generic );
void WriteLog( const std::string &str, logtype const Type = logtype::generic );
void CommLog( const char *str );
void CommLog( const std::string &str );

View File

@@ -606,11 +606,12 @@ void TMoverParameters::BrakeLevelSet(double b)
if (fBrakeCtrlPos == b)
return; // nie przeliczać, jak nie ma zmiany
fBrakeCtrlPos = b;
BrakeCtrlPosR = b;
if (fBrakeCtrlPos < Handle->GetPos(bh_MIN))
fBrakeCtrlPos = Handle->GetPos(bh_MIN); // odcięcie
else if (fBrakeCtrlPos > Handle->GetPos(bh_MAX))
fBrakeCtrlPos = Handle->GetPos(bh_MAX);
// TODO: verify whether BrakeCtrlPosR and fBrakeCtrlPos can be rolled into single variable
BrakeCtrlPosR = fBrakeCtrlPos;
int x = static_cast<int>(std::floor(fBrakeCtrlPos)); // jeśli odwołujemy się do BrakeCtrlPos w pośrednich, to musi być
// obcięte a nie zaokrągone
while ((x > BrakeCtrlPos) && (BrakeCtrlPos < BrakeCtrlPosNo)) // jeśli zwiększyło się o 1
@@ -4507,32 +4508,40 @@ double TMoverParameters::TractionForce(double dt)
Im = DElist[MainCtrlPos].Imax;
}
if (Im > 0) // jak pod obciazeniem
if (Flat) // ograniczenie napiecia w pradnicy - plaszczak u gory
Voltage = 1000.0 * tmp / abs(Im);
else // charakterystyka pradnicy obcowzbudnej (elipsa) - twierdzenie Pitagorasa
{
Voltage = sqrt(abs(square(DElist[MainCtrlPos].Umax) -
square(DElist[MainCtrlPos].Umax * Im /
DElist[MainCtrlPos].Imax))) *
(MainCtrlPos - 1) +
(1.0 - Im / DElist[MainCtrlPos].Imax) * DElist[MainCtrlPos].Umax *
(MainCtrlPosNo - MainCtrlPos);
Voltage = Voltage / (MainCtrlPosNo - 1);
Voltage = Min0R(Voltage, (1000.0 * tmp / abs(Im)));
if (Voltage < (Im * 0.05))
Voltage = Im * 0.05;
if( Im > 0 ) {
// jak pod obciazeniem
if( true == Flat ) {
// ograniczenie napiecia w pradnicy - plaszczak u gory
Voltage = 1000.0 * tmp / std::abs( Im );
}
if ((Voltage > DElist[MainCtrlPos].Umax) ||
(Im == 0)) // gdy wychodzi za duze napiecie
Voltage = DElist[MainCtrlPos].Umax *
int(ConverterFlag); // albo przy biegu jalowym (jest cos takiego?)
else {
// charakterystyka pradnicy obcowzbudnej (elipsa) - twierdzenie Pitagorasa
Voltage =
std::sqrt(
std::abs(
square( DElist[ MainCtrlPos ].Umax )
- square( DElist[ MainCtrlPos ].Umax * Im / DElist[ MainCtrlPos ].Imax ) ) )
* ( MainCtrlPos - 1 )
+ ( 1.0 - Im / DElist[ MainCtrlPos ].Imax ) * DElist[ MainCtrlPos ].Umax * ( MainCtrlPosNo - MainCtrlPos );
Voltage /= ( MainCtrlPosNo - 1 );
Voltage = clamp(
Voltage,
Im * 0.05, ( 1000.0 * tmp / std::abs( Im ) ) );
}
}
if( ( Voltage > DElist[ MainCtrlPos ].Umax )
|| ( Im == 0 ) ) {
// gdy wychodzi za duze napiecie albo przy biegu jalowym (jest cos takiego?)
Voltage = DElist[ MainCtrlPos ].Umax * ( ConverterFlag ? 1 : 0 );
}
EnginePower = Voltage * Im / 1000.0;
/*
// NOTE: this part is experimentally disabled, as it generated early traction force drop for undetermined purpose
if ((tmpV > 2) && (EnginePower < tmp))
Ft = Ft * EnginePower / tmp;
*/
}
if ((Imax > 1) && (Im > Imax))

View File

@@ -374,7 +374,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
if( ( std::abs( scale.x - 1.0f ) > 0.01 )
|| ( std::abs( scale.y - 1.0f ) > 0.01 )
|| ( std::abs( scale.z - 1.0f ) > 0.01 ) ) {
ErrorLog( "Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factors: " + to_string( scale ) + ")" );
ErrorLog( "Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factors: " + to_string( scale ) + ")", logtype::model );
m_normalizenormals = (
( ( std::abs( scale.x - scale.y ) < 0.01f ) && ( std::abs( scale.y - scale.z ) < 0.01f ) ) ?
rescale :
@@ -460,7 +460,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
--facecount; // o jeden trójkąt mniej
iNumVerts -= 3; // czyli o 3 wierzchołki
i -= 3; // wczytanie kolejnego w to miejsce
WriteLog("Bad model: degenerated triangle ignored in: \"" + pName + "\", vertices " + std::to_string(rawvertexcount-2) + "-" + std::to_string(rawvertexcount));
WriteLog("Bad model: degenerated triangle ignored in: \"" + pName + "\", vertices " + std::to_string(rawvertexcount-2) + "-" + std::to_string(rawvertexcount), logtype::model );
}
if (i > 0) {
// jeśli pierwszy trójkąt będzie zdegenerowany, to zostanie usunięty i nie ma co sprawdzać
@@ -472,7 +472,7 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
--facecount; // o jeden trójkąt mniej
iNumVerts -= 3; // czyli o 3 wierzchołki
i -= 3; // wczytanie kolejnego w to miejsce
WriteLog( "Bad model: too large triangle ignored in: \"" + pName + "\"" );
WriteLog( "Bad model: too large triangle ignored in: \"" + pName + "\"", logtype::model );
}
}
}
@@ -511,14 +511,14 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
vertexnormal += facenormals[ adjacenvertextidx / 3 ];
}
else {
ErrorLog( "Bad model: opposite normals in the same smoothing group, check sub-model \"" + pName + "\" for two-sided faces and/or scaling" );
ErrorLog( "Bad model: opposite normals in the same smoothing group, check sub-model \"" + pName + "\" for two-sided faces and/or scaling", logtype::model );
}
// i szukanie od kolejnego trójkąta
adjacenvertextidx = SeekFaceNormal(sg, adjacenvertextidx / 3 + 1, sg[faceidx], Vertices[vertexidx].position, Vertices);
}
// Ra 15-01: należało by jeszcze uwzględnić skalowanie wprowadzane przez transformy, aby normalne po przeskalowaniu były jednostkowe
if( glm::length2( vertexnormal ) == 0.0f ) {
WriteLog( "Bad model: zero lenght normal vector generated for sub-model \"" + pName + "\"" );
WriteLog( "Bad model: zero lenght normal vector generated for sub-model \"" + pName + "\"", logtype::model );
}
Vertices[ vertexidx ].normal = (
glm::length2( vertexnormal ) > 0.0f ?
@@ -1520,7 +1520,7 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
if( ( false == submodel.m_normalizenormals )
&& ( std::abs( normallength - 1.0f ) > 0.01f ) ) {
submodel.m_normalizenormals = TSubModel::normalize; // we don't know if uniform scaling would suffice
WriteLog( "Bad model: non-unit normal vector(s) encountered during sub-model geometry deserialization" );
WriteLog( "Bad model: non-unit normal vector(s) encountered during sub-model geometry deserialization", logtype::model );
}
}
}
@@ -1646,7 +1646,7 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
}
}
else {
ErrorLog( "Bad model: reference to nonexistent texture index in sub-model" + ( pName.empty() ? "" : " \"" + pName + "\"" ) );
ErrorLog( "Bad model: reference to nonexistent texture index in sub-model" + ( pName.empty() ? "" : " \"" + pName + "\"" ), logtype::model );
m_material = null_handle;
}
}
@@ -1686,7 +1686,7 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
if( ( std::abs( scale.x - 1.0f ) > 0.01 )
|| ( std::abs( scale.y - 1.0f ) > 0.01 )
|| ( std::abs( scale.z - 1.0f ) > 0.01 ) ) {
ErrorLog( "Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factors: " + to_string( scale ) + ")" );
ErrorLog( "Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factors: " + to_string( scale ) + ")", logtype::model );
m_normalizenormals = (
( ( std::abs( scale.x - scale.y ) < 0.01f ) && ( std::abs( scale.y - scale.z ) < 0.01f ) ) ?
rescale :

View File

@@ -604,14 +604,27 @@ opengl_texture::release( bool const Backup ) {
if( id == -1 ) { return; }
if( true == Backup ) {
// query texture details needed to perform the backup...
::glBindTexture( GL_TEXTURE_2D, id );
::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&data_format );
GLint datasize;
::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint *)&datasize );
data.resize( datasize );
// ...fetch the data...
::glGetCompressedTexImage( GL_TEXTURE_2D, 0, &data[ 0 ] );
GLint datasize {};
GLint iscompressed {};
::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED, &iscompressed );
if( iscompressed == GL_TRUE ) {
// texture is compressed on the gpu side
// query texture details needed to perform the backup...
::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &data_format );
::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &datasize );
data.resize( datasize );
// ...fetch the data...
::glGetCompressedTexImage( GL_TEXTURE_2D, 0, &data[ 0 ] );
}
else {
// for whatever reason texture didn't get compressed during upload
// fallback on plain rgba storage...
data_format = GL_RGBA;
data.resize( data_width * data_height * 4 );
// ...fetch the data...
::glGetTexImage( GL_TEXTURE_2D, 0, data_format, GL_UNSIGNED_BYTE, &data[ 0 ] );
}
// ...and update texture object state
data_mapcount = 1; // we keep copy of only top mipmap level
data_state = resource_state::good;

View File

@@ -62,7 +62,7 @@ private:
int data_width{ 0 },
data_height{ 0 },
data_mapcount{ 0 };
GLuint data_format{ 0 },
GLint data_format{ 0 },
data_components{ 0 };
/*
std::atomic<bool> is_loaded{ false }; // indicates the texture data was loaded and can be processed

View File

@@ -546,17 +546,17 @@ bool TTrain::is_eztoer() const {
}
// moves train brake lever to specified position, potentially emits switch sound if conditions are met
void TTrain::set_train_brake( int const Position ) {
void TTrain::set_train_brake( double const Position ) {
auto const originalbrakeposition { mvOccupied->BrakeCtrlPos };
auto const originalbrakeposition { static_cast<int>( 100.0 * mvOccupied->fBrakeCtrlPos ) };
mvOccupied->BrakeLevelSet( Position );
if( mvOccupied->BrakeCtrlPos == originalbrakeposition ) { return; }
if( static_cast<int>( 100.0 * mvOccupied->fBrakeCtrlPos ) == originalbrakeposition ) { return; }
if( ( true == is_eztoer() )
&& ( false == (
( ( originalbrakeposition == 0 ) || ( originalbrakeposition >= 5 ) )
( ( originalbrakeposition / 100 == 0 ) || ( originalbrakeposition / 100 >= 5 ) )
&& ( ( mvOccupied->BrakeCtrlPos == 0 ) || ( mvOccupied->BrakeCtrlPos >= 5 ) ) ) ) ) {
// sound feedback if the lever movement activates one of the switches
dsbPneumaticSwitch.play();

View File

@@ -115,7 +115,7 @@ class TTrain
// locates nearest vehicle belonging to the consist
TDynamicObject *find_nearest_consist_vehicle() const;
// moves train brake lever to specified position, potentially emits switch sound if conditions are met
void set_train_brake( int const Position );
void set_train_brake( double const Position );
// command handlers