more parameters exposed to python, reworked ui screens, ui text color setting

This commit is contained in:
tmj-fstate
2017-03-19 23:58:03 +01:00
parent a5d01ef059
commit f10494fd6a
9 changed files with 243 additions and 213 deletions

View File

@@ -399,4 +399,5 @@ class TController
int CrossRoute(TTrack *tr);
void RouteSwitch(int d);
std::string OwnerName();
TMoverParameters const *Controlling() const { return mvControlling; }
};

View File

@@ -157,8 +157,9 @@ void key_callback( GLFWwindow *window, int key, int scancode, int action, int mo
else if( !( Global::iMultiplayer & 2 ) ) // w multiplayerze pauza nie ma sensu
if( !Global::ctrlState ) // z [Ctrl] to radiostop jest
Global::iPause ^= 2; // zmiana stanu zapauzowania
if( Global::iPause ) // jak pauza
if( Global::iPause ) {// jak pauza
Global::iTextMode = GLFW_KEY_F1; // to wyświetlić zegar i informację
}
break;
}
case GLFW_KEY_F7:

View File

@@ -48,20 +48,18 @@ GLFWwindow *Global::window;
bool Global::shiftState;
bool Global::ctrlState;
int Global::iCameraLast = -1;
std::string Global::asRelease = "16.0.1172.482";
std::string Global::asRelease = "16.0.1172.482++";
std::string Global::asVersion =
"Compilation 2017-01-10, release " + Global::asRelease + "."; // tutaj, bo wysyłany
"Compilation 2017-03-19, release " + Global::asRelease + "."; // tutaj, bo wysyłany
int Global::iTextMode = 0; // tryb pracy wyświetlacza tekstowego
int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0}; // numer ekranu wyświetlacza tekstowego
int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // numer ekranu wyświetlacza tekstowego
double Global::fSunDeclination = 0.0; // deklinacja Słońca
double Global::fTimeAngleDeg = 0.0; // godzina w postaci kąta
float Global::fClockAngleDeg[6]; // kąty obrotu cylindrów dla zegara cyfrowego
std::string Global::szTexturesTGA = ".tga"; // lista tekstur od TGA
std::string Global::szTexturesDDS = ".dds"; // lista tekstur od DDS
int Global::iKeyLast = 0; // ostatnio naciśnięty klawisz w celu logowania
GLuint Global::iTextureId = 0; // ostatnio użyta tekstura 2D
int Global::iPause = 0x10; // globalna pauza ruchu
int Global::iPause = 0; // 0x10; // globalna pauza ruchu
bool Global::bActive = true; // czy jest aktywnym oknem
int Global::iErorrCounter = 0; // licznik sprawdzań do śledzenia błędów OpenGL
int Global::iTextures = 0; // licznik użytych tekstur
@@ -74,6 +72,7 @@ TDynamicObject *Global::pUserDynamic = NULL; // pojazd użytkownika, renderowany
std::string Global::asTranscript[5]; // napisy na ekranie (widoczne)
*/
TTranscripts Global::tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
float4 Global::UITextColor = float4( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f );
// parametry scenerii
vector3 Global::pCameraPosition;
@@ -140,10 +139,11 @@ int Global::iRailProFiltering = 5; // domyślne rozmywanie tekstur szyn
int Global::iDynamicFiltering = 5; // domyślne rozmywanie tekstur pojazdów
bool Global::bUseVBO = false; // czy jest VBO w karcie graficznej (czy użyć)
std::string Global::LastGLError;
GLint Global::iMaxTextureSize = 16384; // maksymalny rozmiar tekstury
GLint Global::iMaxTextureSize = 4096; // maksymalny rozmiar tekstury
bool Global::bSmoothTraction = false; // wygładzanie drutów starym sposobem
std::string Global::szDefaultExt = Global::szTexturesDDS; // domyślnie od DDS
int Global::iMultisampling = 2; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px
bool Global::DLFont{ false }; // switch indicating presence of basic font
bool Global::bGlutFont = false; // czy tekst generowany przez GLUT32.DLL
//int Global::iConvertModels = 7; // tworzenie plików binarnych, +2-optymalizacja transformów
int Global::iConvertModels{ 0 }; // temporary override, to prevent generation of .e3d not compatible with old exe
@@ -513,42 +513,15 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens(1, false);
int size;
Parser >> size;
if (size <= 64)
{
Global::iMaxTextureSize = 64;
}
else if (size <= 128)
{
Global::iMaxTextureSize = 128;
}
else if (size <= 256)
{
Global::iMaxTextureSize = 256;
}
else if (size <= 512)
{
Global::iMaxTextureSize = 512;
}
else if (size <= 1024)
{
Global::iMaxTextureSize = 1024;
}
else if (size <= 2048)
{
Global::iMaxTextureSize = 2048;
}
else if (size <= 4096)
{
Global::iMaxTextureSize = 4096;
}
else if (size <= 8192)
{
Global::iMaxTextureSize = 8192;
}
else
{
Global::iMaxTextureSize = 16384;
}
if (size <= 64) { Global::iMaxTextureSize = 64; }
else if (size <= 128) { Global::iMaxTextureSize = 128; }
else if (size <= 256) { Global::iMaxTextureSize = 256; }
else if (size <= 512) { Global::iMaxTextureSize = 512; }
else if (size <= 1024) { Global::iMaxTextureSize = 1024; }
else if (size <= 2048) { Global::iMaxTextureSize = 2048; }
else if (size <= 4096) { Global::iMaxTextureSize = 4096; }
else if (size <= 8192) { Global::iMaxTextureSize = 8192; }
else { Global::iMaxTextureSize = 16384; }
}
else if (token == "doubleambient")
{
@@ -682,7 +655,8 @@ void Global::ConfigParse(cParser &Parser)
in = 5; // na ostatni, bo i tak trzeba pominąć wartości
}
Parser.getTokens(4, false);
Parser >> Global::fCalibrateIn[in][0] // wyraz wolny
Parser
>> Global::fCalibrateIn[in][0] // wyraz wolny
>> Global::fCalibrateIn[in][1] // mnożnik
>> Global::fCalibrateIn[in][2] // mnożnik dla kwadratu
>> Global::fCalibrateIn[in][3]; // mnożnik dla sześcianu
@@ -797,6 +771,19 @@ void Global::ConfigParse(cParser &Parser)
Parser.getTokens(1, false);
Parser >> Global::asLang;
}
else if( token == "uitextcolor" ) {
// color of the ui text. NOTE: will be obsolete once the real ui is in place
Parser.getTokens( 3, false );
Parser
>> Global::UITextColor.x
>> Global::UITextColor.y
>> Global::UITextColor.z;
Global::UITextColor.x = clamp( Global::UITextColor.x, 0.0f, 255.0f );
Global::UITextColor.y = clamp( Global::UITextColor.y, 0.0f, 255.0f );
Global::UITextColor.z = clamp( Global::UITextColor.z, 0.0f, 255.0f );
Global::UITextColor = Global::UITextColor / 255.0f;
Global::UITextColor.w = 1.0f;
}
else if (token == "pyscreenrendererpriority")
{
// priority of python screen renderer
@@ -1067,14 +1054,6 @@ void Global::SetCameraRotation(double Yaw)
pCameraRotationDeg = pCameraRotation * 180.0 / M_PI;
}
void Global::BindTexture(GLuint t)
{ // ustawienie aktualnej tekstury, tylko gdy się zmienia
if (t != iTextureId)
{
iTextureId = t;
}
};
void Global::TrainDelete(TDynamicObject *d)
{ // usunięcie pojazdu prowadzonego przez użytkownika
if (pWorld)

View File

@@ -163,7 +163,6 @@ private:
class Global
{
private:
static GLuint iTextureId; // ostatnio użyta tekstura 2D
public:
// double Global::tSinceStart;
static int Keys[MaxKeys];
@@ -282,6 +281,7 @@ class Global
static std::string szTexturesTGA; // lista tekstur od TGA
static std::string szTexturesDDS; // lista tekstur od DDS
static int iMultisampling; // tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px
static bool DLFont; // switch indicating presence of basic font
static bool bGlutFont; // tekst generowany przez GLUT
static int iKeyLast; // ostatnio naciśnięty klawisz w celu logowania
static int iPause; // globalna pauza ruchu: b0=start,b1=klawisz,b2=tło,b3=lagi,b4=wczytywanie
@@ -322,6 +322,7 @@ class Global
static std::string asTranscript[5]; // napisy na ekranie (widoczne)
*/
static TTranscripts tranTexts; // obiekt obsługujący stenogramy dźwięków na ekranie
static float4 UITextColor; // base color of UI text
static std::string asLang; // domyślny język - http://tools.ietf.org/html/bcp47
static int iHiddenEvents; // czy łączyć eventy z torami poprzez nazwę toru
static TTextSound *tsRadioBusy[10]; // zajętość kanałów radiowych (wskaźnik na odgrywany dźwięk)

127
Train.cpp
View File

@@ -295,35 +295,58 @@ PyObject *TTrain::GetTrainState() {
return NULL;
}
PyDict_SetItemString( dict, "direction", PyGetInt( DynamicObject->MoverParameters->ActiveDir ) );
PyDict_SetItemString( dict, "cab", PyGetInt( DynamicObject->MoverParameters->ActiveCab ) );
PyDict_SetItemString( dict, "slipping_wheels",
PyGetBool( DynamicObject->MoverParameters->SlippingWheels ) );
PyDict_SetItemString( dict, "converter",
PyGetBool( DynamicObject->MoverParameters->ConverterFlag ) );
PyDict_SetItemString( dict, "main_ctrl_actual_pos",
PyGetInt( DynamicObject->MoverParameters->MainCtrlActualPos ) );
PyDict_SetItemString( dict, "scnd_ctrl_actual_pos",
PyGetInt( DynamicObject->MoverParameters->ScndCtrlActualPos ) );
PyDict_SetItemString( dict, "fuse", PyGetBool( DynamicObject->MoverParameters->FuseFlag ) );
PyDict_SetItemString( dict, "converter_overload",
PyGetBool( DynamicObject->MoverParameters->ConvOvldFlag ) );
PyDict_SetItemString( dict, "voltage", PyGetFloat( DynamicObject->MoverParameters->Voltage ) );
PyDict_SetItemString( dict, "velocity", PyGetFloat( DynamicObject->MoverParameters->Vel ) );
PyDict_SetItemString( dict, "im", PyGetFloat( DynamicObject->MoverParameters->Im ) );
PyDict_SetItemString( dict, "compress",
PyGetBool( DynamicObject->MoverParameters->CompressorFlag ) );
PyDict_SetItemString( dict, "hours", PyGetInt( GlobalTime->hh ) );
PyDict_SetItemString( dict, "minutes", PyGetInt( GlobalTime->mm ) );
PyDict_SetItemString( dict, "seconds", PyGetInt( GlobalTime->mr ) );
PyDict_SetItemString( dict, "velocity_desired", PyGetFloat( DynamicObject->Mechanik->VelDesired ) );
auto const &mover = DynamicObject->MoverParameters;
PyDict_SetItemString( dict, "cab", PyGetInt( mover->ActiveCab ) );
// basic systems state data
PyDict_SetItemString( dict, "battery", PyGetBool( mvControlled->Battery ) );
PyDict_SetItemString( dict, "linebreaker", PyGetBool( mvControlled->Mains ) );
PyDict_SetItemString( dict, "converter", PyGetBool( mover->ConverterFlag ) );
PyDict_SetItemString( dict, "converter_overload", PyGetBool( mover->ConvOvldFlag ) );
PyDict_SetItemString( dict, "compress", PyGetBool( mover->CompressorFlag ) );
// reverser
PyDict_SetItemString( dict, "direction", PyGetInt( mover->ActiveDir ) );
// throttle
PyDict_SetItemString( dict, "mainctrl_pos", PyGetInt( mover->MainCtrlPos ) );
PyDict_SetItemString( dict, "main_ctrl_actual_pos", PyGetInt( mover->MainCtrlActualPos ) );
PyDict_SetItemString( dict, "scndctrl_pos", PyGetInt( mover->ScndCtrlPos ) );
PyDict_SetItemString( dict, "scnd_ctrl_actual_pos", PyGetInt( mover->ScndCtrlActualPos ) );
// brakes
PyDict_SetItemString( dict, "manual_brake", PyGetBool( mvOccupied->ManualBrakePos > 0 ) );
bool const bEP = ( mvControlled->LocHandle->GetCP()>0.2 ) || ( fEIMParams[ 0 ][ 2 ]>0.01 );
PyDict_SetItemString( dict, "dir_brake", PyGetBool( bEP ) );
bool bPN;
if( ( typeid( *mvControlled->Hamulec ) == typeid( TLSt ) )
|| ( typeid( *mvControlled->Hamulec ) == typeid( TEStED ) ) ) {
TBrake* temp_ham = mvControlled->Hamulec.get();
bPN = ( static_cast<TLSt*>( temp_ham )->GetEDBCP()>0.2 );
}
else
bPN = false;
PyDict_SetItemString( dict, "indir_brake", PyGetBool( bPN ) );
// other controls
PyDict_SetItemString( dict, "ca", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ) );
PyDict_SetItemString( dict, "shp", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ) );
PyDict_SetItemString( dict, "pantpress", PyGetFloat( mvControlled->PantPress ) );
PyDict_SetItemString( dict, "universal3", PyGetBool( LampkaUniversal3_st ) );
// movement data
PyDict_SetItemString( dict, "velocity", PyGetFloat( mover->Vel ) );
PyDict_SetItemString( dict, "tractionforce", PyGetFloat( mover->Ft ) );
PyDict_SetItemString( dict, "slipping_wheels", PyGetBool( mover->SlippingWheels ) );
// electric current data
PyDict_SetItemString( dict, "traction_voltage", PyGetFloat( mover->RunningTraction.TractionVoltage ) );
PyDict_SetItemString( dict, "voltage", PyGetFloat( mover->Voltage ) );
PyDict_SetItemString( dict, "im", PyGetFloat( mover->Im ) );
PyDict_SetItemString( dict, "fuse", PyGetBool( mover->FuseFlag ) );
// induction motor state data
char* TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" };
char* TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" };
char* TXTP[ 3 ] = { "bc", "bp", "sp" };
for( int j = 0; j<10; j++ )
for( int j = 0; j < 10; ++j )
PyDict_SetItemString( dict, ( std::string( "eimp_t_" ) + std::string( TXTT[ j ] ) ).c_str(), PyGetFloatS( fEIMParams[ 0 ][ j ] ) );
for( int i = 0; i<8; i++ ) {
for( int j = 0; j<10; j++ )
for( int i = 0; i < 8; ++i ) {
for( int j = 0; j < 10; ++j )
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_" ) + std::string( TXTC[ j ] ) ).c_str(), PyGetFloatS( fEIMParams[ i + 1 ][ j ] ) );
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_ms" ) ).c_str(), PyGetBool( bMains[ i ] ) );
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_cv" ) ).c_str(), PyGetFloatS( fCntVol[ i ] ) );
@@ -337,25 +360,17 @@ PyObject *TTrain::GetTrainState() {
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_heat" ) ).c_str(), PyGetBool( bHeat[ i ] ) );
}
for( int i = 0; i<20; i++ ) {
for( int j = 0; j<3; j++ )
for( int i = 0; i < 20; ++i ) {
for( int j = 0; j < 3; ++j )
PyDict_SetItemString( dict, ( std::string( "eimp_pn" ) + std::to_string( i + 1 ) + std::string( "_" ) + std::string( TXTP[ j ] ) ).c_str(),
PyGetFloatS( fPress[ i ][ j ] ) );
}
bool bEP, bPN;
bEP = ( mvControlled->LocHandle->GetCP()>0.2 ) || ( fEIMParams[ 0 ][ 2 ]>0.01 );
PyDict_SetItemString( dict, "dir_brake", PyGetBool( bEP ) );
if( ( typeid( *mvControlled->Hamulec ) == typeid( TLSt ) )
|| ( typeid( *mvControlled->Hamulec ) == typeid( TEStED ) ) ) {
// multi-unit state data
PyDict_SetItemString( dict, "car_no", PyGetInt( iCarNo ) );
PyDict_SetItemString( dict, "power_no", PyGetInt( iPowerNo ) );
PyDict_SetItemString( dict, "unit_no", PyGetInt( iUnitNo ) );
TBrake* temp_ham = mvControlled->Hamulec.get();
// TLSt* temp_ham2 = temp_ham;
bPN = ( static_cast<TLSt*>( temp_ham )->GetEDBCP()>0.2 );
}
else
bPN = false;
PyDict_SetItemString( dict, "indir_brake", PyGetBool( bPN ) );
for( int i = 0; i<20; i++ ) {
for( int i = 0; i < 20; i++ ) {
PyDict_SetItemString( dict, ( std::string( "doors_" ) + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 0 ] ) );
PyDict_SetItemString( dict, ( std::string( "doors_r_" ) + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 1 ] ) );
PyDict_SetItemString( dict, ( std::string( "doors_l_" ) + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 2 ] ) );
@@ -364,23 +379,21 @@ PyObject *TTrain::GetTrainState() {
cCode[ i ] ).c_str() ) );
PyDict_SetItemString( dict, ( std::string( "car_name" ) + std::to_string( i + 1 ) ).c_str(), PyGetString( asCarName[ i ].c_str() ) );
}
PyDict_SetItemString( dict, "car_no", PyGetInt( iCarNo ) );
PyDict_SetItemString( dict, "power_no", PyGetInt( iPowerNo ) );
PyDict_SetItemString( dict, "unit_no", PyGetInt( iUnitNo ) );
PyDict_SetItemString( dict, "universal3", PyGetBool( LampkaUniversal3_st ) );
PyDict_SetItemString( dict, "ca", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ) );
PyDict_SetItemString( dict, "shp", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ) );
PyDict_SetItemString( dict, "manual_brake", PyGetBool( mvOccupied->ManualBrakePos > 0 ) );
PyDict_SetItemString( dict, "pantpress", PyGetFloat( mvControlled->PantPress ) );
PyDict_SetItemString( dict, "trainnumber", PyGetString( DynamicObject->Mechanik->TrainName().c_str() ) );
PyDict_SetItemString( dict, "velnext", PyGetFloat( DynamicObject->Mechanik->VelNext ) );
PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( DynamicObject->Mechanik->ActualProximityDist ) );
PyDict_SetItemString( dict, "velsignallast", PyGetFloat( DynamicObject->Mechanik->VelSignalLast ) );
PyDict_SetItemString( dict, "vellimitlast", PyGetFloat( DynamicObject->Mechanik->VelLimitLast ) );
PyDict_SetItemString( dict, "velroad", PyGetFloat( DynamicObject->Mechanik->VelRoad ) );
PyDict_SetItemString( dict, "velsignalnext", PyGetFloat( DynamicObject->Mechanik->VelSignalNext ) );
PyDict_SetItemString( dict, "battery", PyGetBool( mvControlled->Battery ) );
PyDict_SetItemString( dict, "tractionforce", PyGetFloat( DynamicObject->MoverParameters->Ft ) );
// ai state data
auto const &driver = DynamicObject->Mechanik;
PyDict_SetItemString( dict, "velocity_desired", PyGetFloat( driver->VelDesired ) );
PyDict_SetItemString( dict, "velroad", PyGetFloat( driver->VelRoad ) );
PyDict_SetItemString( dict, "vellimitlast", PyGetFloat( driver->VelLimitLast ) );
PyDict_SetItemString( dict, "velsignallast", PyGetFloat( driver->VelSignalLast ) );
PyDict_SetItemString( dict, "velsignalnext", PyGetFloat( driver->VelSignalNext ) );
PyDict_SetItemString( dict, "velnext", PyGetFloat( driver->VelNext ) );
PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( driver->ActualProximityDist ) );
PyDict_SetItemString( dict, "trainnumber", PyGetString( driver->TrainName().c_str() ) );
// world state data
PyDict_SetItemString( dict, "hours", PyGetInt( GlobalTime->hh ) );
PyDict_SetItemString( dict, "minutes", PyGetInt( GlobalTime->mm ) );
PyDict_SetItemString( dict, "seconds", PyGetInt( GlobalTime->mr ) );
return dict;
}

View File

@@ -252,8 +252,7 @@ class TTrain
TButton btLampkaOpory;
TButton btLampkaWysRozr;
TButton btLampkaUniversal3;
int LampkaUniversal3_typ; // ABu 030405 - swiecenie uzaleznione od: 0-nic,
// 1-obw.gl, 2-przetw.
int LampkaUniversal3_typ; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw.
bool LampkaUniversal3_st;
TButton btLampkaWentZaluzje; // ET22
TButton btLampkaOgrzewanieSkladu;

223
World.cpp
View File

@@ -253,10 +253,10 @@ bool TWorld::Init( GLFWwindow *Window ) {
Timer::ResetTimers();
// make 4 empty lines for the ui header, to cut down on work down the road
UIHeader->text_lines.emplace_back( "", float4( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f ) );
UIHeader->text_lines.emplace_back( "", float4( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f ) );
UIHeader->text_lines.emplace_back( "", float4( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f ) );
UIHeader->text_lines.emplace_back( "", float4( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f ) );
UIHeader->text_lines.emplace_back( "", Global::UITextColor );
UIHeader->text_lines.emplace_back( "", Global::UITextColor );
UIHeader->text_lines.emplace_back( "", Global::UITextColor );
UIHeader->text_lines.emplace_back( "", Global::UITextColor );
// bind the panels with ui object. maybe not the best place for this but, eh
UILayer.push_back( UIHeader );
UILayer.push_back( UITable );
@@ -334,33 +334,42 @@ void TWorld::OnKeyDown(int cKey)
if( ( false == Global::ctrlState )
&& ( false == Global::shiftState ) ) {
// czas i relacja
if( Global::iTextMode == cKey ) {
// wyłączenie napisów, chyba że pauza
Global::iTextMode =
( Global::iPause && ( cKey != GLFW_KEY_F1 ) ?
GLFW_KEY_F1 :
0 );
if( Global::iTextMode == cKey ) { ++Global::iScreenMode[ cKey - GLFW_KEY_F1 ]; }
if( Global::iScreenMode[ cKey - GLFW_KEY_F1 ] > 1 ) {
// wyłączenie napisów
Global::iTextMode = 0;
Global::iScreenMode[ cKey - GLFW_KEY_F1 ] = 0;
}
else
else {
Global::iTextMode = cKey;
}
}
break;
}
case GLFW_KEY_F2: {
// parametry pojazdu
if( Global::iTextMode == cKey ) {
// jeśli kolejne naciśnięcie
++Global::iScreenMode[ cKey - GLFW_KEY_F1 ]; // kolejny ekran
if( Global::iTextMode == cKey ) { ++Global::iScreenMode[ cKey - GLFW_KEY_F1 ]; }
if( Global::iScreenMode[ cKey - GLFW_KEY_F1 ] > 1 ) {
// wyłączenie napisów
Global::iTextMode = 0;
Global::iScreenMode[ cKey - GLFW_KEY_F1 ] = 0;
}
else {
// pierwsze naciśnięcie daje pierwszy (tzn. zerowy) ekran
Global::iTextMode = cKey;
Global::iScreenMode[ cKey - GLFW_KEY_F1 ] = 0;
}
break;
}
case GLFW_KEY_F3: {
Global::iTextMode = cKey;
// timetable
if( Global::iTextMode == cKey ) { ++Global::iScreenMode[ cKey - GLFW_KEY_F1 ]; }
if( Global::iScreenMode[ cKey - GLFW_KEY_F1 ] > 1 ) {
// wyłączenie napisów
Global::iTextMode = 0;
Global::iScreenMode[ cKey - GLFW_KEY_F1 ] = 0;
}
else {
Global::iTextMode = cKey;
}
break;
}
case GLFW_KEY_F4: {
@@ -408,7 +417,7 @@ void TWorld::OnKeyDown(int cKey)
break;
}
case GLFW_KEY_F6: {
Global::iTextMode = cKey;
// Global::iTextMode = cKey;
// przyspieszenie symulacji do testowania scenerii... uwaga na FPS!
if( DebugModeFlag ) {
@@ -851,7 +860,7 @@ bool TWorld::Update()
if( (Train != nullptr)
&& (Camera.Type == tp_Follow )) {
// jeśli jazda w kabinie, przeliczyć trzeba parametry kamery
Train->UpdateMechPosition( m_secondaryupdaterate / Global::fTimeSpeed ); // ograniczyć telepanie po przyspieszeniu
Train->UpdateMechPosition( m_secondaryupdaterate );
}
m_secondaryupdateaccumulator -= m_secondaryupdaterate; // these should be inexpensive enough we have no cap
@@ -1433,19 +1442,112 @@ TWorld::Update_UI() {
if( Global::iPause ) {
OutText1 += " (paused)";
}
if( Controlled && ( Controlled->Mechanik != nullptr ) ) {
auto const &mover = Controlled->MoverParameters;
auto const &driver = Controlled->Mechanik;
OutText2 = "Throttle: " + to_string( driver->Controlling()->MainCtrlPos, 0, 2 ) + "+" + std::to_string( driver->Controlling()->ScndCtrlPos );
if( mover->ActiveDir > 0 ) { OutText2 += " D"; }
else if( mover->ActiveDir < 0 ) { OutText2 += " R"; }
else { OutText2 += " N"; }
OutText3 = "Brakes:" + to_string( mover->fBrakeCtrlPos, 1, 5 ) + "+" + std::to_string( mover->LocalBrakePos );
if( Global::iScreenMode[ Global::iTextMode - GLFW_KEY_F1 ] == 1 ) {
// detail mode on second key press
OutText2 +=
" Speed: " + std::to_string( static_cast<int>( std::floor( mover->Vel ) ) ) + " km/h"
+ " (limit: " + std::to_string( static_cast<int>( std::floor( driver->VelDesired ) ) ) + " km/h"
+ ", next limit: " + std::to_string( static_cast<int>( std::floor( Controlled->Mechanik->VelNext ) ) ) + " km/h"
+ " in " + to_string( Controlled->Mechanik->ActualProximityDist * 0.001, 1 ) + " km)";
OutText3 +=
" Pressure: " + to_string( mover->BrakePress * 100.0, 2 ) + " kPa"
+ " (train pipe: " + to_string( mover->PipePress * 100.0, 2 ) + " kPa)";
}
}
break;
}
case( GLFW_KEY_F2 ) : {
// timetable
TDynamicObject *tmp =
( FreeFlyModeFlag ?
Ground.DynamicNearest( Camera.Pos ) :
Controlled ); // w trybie latania lokalizujemy wg mapy
if( tmp == nullptr ) { break; }
if( tmp->Mechanik == nullptr ) { break; }
auto const table = tmp->Mechanik->Timetable();
if( table == nullptr ) { break; }
OutText1 =
"Time: "
+ to_string( (int)GlobalTime->hh ) + ":"
+ ( GlobalTime->mm < 10 ? "0" : "" ) + to_string( GlobalTime->mm ) + ":"
+ ( GlobalTime->mr < 10 ? "0" : "" ) + to_string( std::floor( GlobalTime->mr ) );
if( Global::iPause ) {
OutText1 += " (paused)";
}
if( Controlled
&& Controlled->Mechanik ) {
OutText2 = Global::Bezogonkow( Controlled->Mechanik->Relation(), true );
OutText2 = Global::Bezogonkow( Controlled->Mechanik->Relation(), true ) + " (" + tmp->Mechanik->Timetable()->TrainName + ")";
if( !OutText2.empty() ) {
// jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania
OutText3 = " -> " + Global::Bezogonkow( Controlled->Mechanik->NextStop(), true );
}
}
if( Global::iScreenMode[ Global::iTextMode - GLFW_KEY_F1 ] == 1 ) {
if( 0 == table->StationCount ) {
// only bother if there's stations to list
UITable->text_lines.emplace_back( "(no timetable)", Global::UITextColor );
}
else {
// header
UITable->text_lines.emplace_back( "+----------------------------+-------+-------+-----+", Global::UITextColor );
TMTableLine *tableline;
for( int i = tmp->Mechanik->iStationStart; i <= std::min( tmp->Mechanik->iStationStart + 15, table->StationCount ); ++i ) {
// wyświetlenie pozycji z rozkładu
tableline = table->TimeTable + i; // linijka rozkładu
std::string station =
( tableline->StationName + " " ).substr( 0, 26 );
std::string arrival =
( tableline->Ah >= 0 ?
to_string( int( 100 + tableline->Ah ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Am ) ).substr( 1, 2 ) :
" " );
std::string departure =
( tableline->Dh >= 0 ?
to_string( int( 100 + tableline->Dh ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Dm ) ).substr( 1, 2 ) :
" " );
std::string vmax =
" "
+ to_string( tableline->vmax, 0 );
vmax = vmax.substr( vmax.length() - 3, 3 ); // z wyrównaniem do prawej
UITable->text_lines.emplace_back(
Global::Bezogonkow( "| " + station + " | " + arrival + " | " + departure + " | " + vmax + " | " + tableline->StationWare, true ),
( ( tmp->Mechanik->iStationStart < table->StationIndex ) && ( i < table->StationIndex ) ?
float4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono
Global::UITextColor )
);
// divider/footer
UITable->text_lines.emplace_back( "+----------------------------+-------+-------+-----+", Global::UITextColor );
}
}
}
break;
}
case( GLFW_KEY_F2 ) : {
case( GLFW_KEY_F3 ) : {
TDynamicObject *tmp =
( FreeFlyModeFlag ?
@@ -1574,19 +1676,18 @@ TWorld::Update_UI() {
OutText4 += ", command: " + tmp->Mechanik->OrderCurrent();
}
if( Global::iScreenMode[ Global::iTextMode - GLFW_KEY_F1 ] != 0 ) {
if( Global::iScreenMode[ Global::iTextMode - GLFW_KEY_F1 ] == 1 ) {
// f2 screen, track scan mode
if( tmp->Mechanik == nullptr ) {
//żeby była tabelka, musi być AI
break;
}
float4 linecolor( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f );
int i = 0;
do {
std::string scanline = tmp->Mechanik->TableText( i );
if( scanline.empty() ) { break; }
UITable->text_lines.emplace_back( Global::Bezogonkow( scanline ), linecolor );
UITable->text_lines.emplace_back( Global::Bezogonkow( scanline ), Global::UITextColor );
++i;
} while( i < 16 ); // TController:iSpeedTableSize TODO: change when the table gets recoded
}
@@ -1611,74 +1712,6 @@ TWorld::Update_UI() {
break;
}
case( GLFW_KEY_F3 ) : {
// timetable
TDynamicObject *tmp =
( FreeFlyModeFlag ?
Ground.DynamicNearest( Camera.Pos ) :
Controlled ); // w trybie latania lokalizujemy wg mapy
if( tmp == nullptr ) { break; }
if( tmp->Mechanik == nullptr ) { break; }
auto const table = tmp->Mechanik->Timetable();
if( table == nullptr ) { break; }
OutText1 =
"Time: "
+ to_string( (int)GlobalTime->hh ) + ":"
+ ( GlobalTime->mm < 10 ? "0" : "" ) + to_string( GlobalTime->mm ) + ":"
+ ( GlobalTime->mr < 10 ? "0" : "" ) + to_string( std::floor( GlobalTime->mr ) );
if( Global::iPause ) {
OutText1 += " (paused)";
}
OutText2 = tmp->Mechanik->Relation() + " (" + tmp->Mechanik->Timetable()->TrainName + ")";
float4 linecolor( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f );
if( 0 == table->StationCount ) {
// only bother if there's stations to list
UITable->text_lines.emplace_back( "(no timetable)", linecolor );
}
else {
// header
UITable->text_lines.emplace_back( "+----------------------------+-------+-------+-----+", linecolor );
TMTableLine *tableline;
for( int i = tmp->Mechanik->iStationStart; i <= std::min( tmp->Mechanik->iStationStart + 15, table->StationCount ); ++i ) {
// wyświetlenie pozycji z rozkładu
tableline = table->TimeTable + i; // linijka rozkładu
std::string station =
( tableline->StationName + " " ).substr( 0, 26 );
std::string arrival =
( tableline->Ah >= 0 ?
to_string( int( 100 + tableline->Ah ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Am ) ).substr( 1, 2 ) :
" " );
std::string departure =
( tableline->Dh >= 0 ?
to_string( int( 100 + tableline->Dh ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Dm ) ).substr( 1, 2 ) :
" " );
std::string vmax =
" "
+ to_string( tableline->vmax, 0 );
vmax = vmax.substr( vmax.length() - 3, 3 ); // z wyrównaniem do prawej
UITable->text_lines.emplace_back(
Global::Bezogonkow( "| " + station + " | " + arrival + " | " + departure + " | " + vmax + " | " + tableline->StationWare, true ),
( ( tmp->Mechanik->iStationStart < table->StationIndex ) && ( i < table->StationIndex ) ?
float4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono
linecolor )
);
// divider/footer
UITable->text_lines.emplace_back( "+----------------------------+-------+-------+-----+", linecolor );
}
}
break;
}
case( GLFW_KEY_F8 ) : {
OutText1 =
@@ -1846,9 +1879,7 @@ TWorld::Update_UI() {
// induction motor data
if( tmp->MoverParameters->EngineType == ElectricInductionMotor ) {
float4 linecolor( 225.0 / 255.0f, 225.0f / 255.0f, 225.0f / 255.0f, 1.0f );
UITable->text_lines.emplace_back( " eimc: eimv: press:", linecolor );
UITable->text_lines.emplace_back( " eimc: eimv: press:", Global::UITextColor );
for( int i = 0; i <= 20; ++i ) {
std::string parameters =
@@ -1865,7 +1896,7 @@ TWorld::Update_UI() {
parameters += " " + to_string( tmp->MED[ 0 ][ i - 13 ], 2, 9 );
}
UITable->text_lines.emplace_back( parameters, linecolor );
UITable->text_lines.emplace_back( parameters, Global::UITextColor );
}
}

View File

@@ -46,12 +46,12 @@ light_array::update() {
// update light parameters to match current data of the owner
if( light.index == 0 ) {
// front light set
light.position = light.owner->GetPosition() + ( light.owner->VectorFront() * light.owner->GetLength() * 0.45 );
light.position = light.owner->GetPosition() + ( light.owner->VectorFront() * light.owner->GetLength() * 0.4 );
light.direction = light.owner->VectorFront();
}
else {
// rear light set
light.position = light.owner->GetPosition() - ( light.owner->VectorFront() * light.owner->GetLength() * 0.45 );
light.position = light.owner->GetPosition() - ( light.owner->VectorFront() * light.owner->GetLength() * 0.4 );
light.direction = light.owner->VectorFront();
light.direction.x = -light.direction.x;
light.direction.z = -light.direction.z;

View File

@@ -47,11 +47,15 @@ ui_layer::init( GLFWwindow *Window ) {
// builds 96 characters starting at character 32
WriteLog( "Display Lists font used" ); //+AnsiString(glGetError())
WriteLog( "Font init OK" ); //+AnsiString(glGetError())
Global::DLFont = true;
return true;
}
else {
ErrorLog( "Font init failed" );
return false;
// return false;
// NOTE: we report success anyway, given some cards can't produce fonts in this manner
Global::DLFont = false;
return true;
}
}
@@ -171,7 +175,8 @@ ui_layer::render_background() {
void
ui_layer::print( std::string const &Text )
{
if( true == Text.empty() )
if( (false == Global::DLFont)
|| (true == Text.empty()) )
return;
::glPushAttrib( GL_LIST_BIT );