mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
1181 lines
46 KiB
C++
1181 lines
46 KiB
C++
/*
|
|
This Source Code Form is subject to the
|
|
terms of the Mozilla Public License, v.
|
|
2.0. If a copy of the MPL was not
|
|
distributed with this file, You can
|
|
obtain one at
|
|
http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
/*
|
|
MaSzyna EU07 locomotive simulator
|
|
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
|
|
|
*/
|
|
#include "stdafx.h"
|
|
#include "globals.h"
|
|
|
|
#include "world.h"
|
|
#include "simulation.h"
|
|
#include "logs.h"
|
|
#include "Console.h"
|
|
#include "PyInt.h"
|
|
|
|
// namespace Global {
|
|
|
|
// parametry do użytku wewnętrznego
|
|
std::string Global::AppName{ "EU07" };
|
|
std::string Global::asCurrentSceneryPath = "scenery/";
|
|
std::string Global::asCurrentTexturePath = std::string(szTexturePath);
|
|
std::string Global::asCurrentDynamicPath = "";
|
|
int Global::iSlowMotion = 0; // info o malym FPS: 0-OK, 1-wyłączyć multisampling, 3-promień 1.5km, 7-1km
|
|
TDynamicObject *Global::changeDynObj = NULL; // info o zmianie pojazdu
|
|
double Global::ABuDebug = 0;
|
|
std::string Global::asSky = "1";
|
|
double Global::fLuminance = 1.0; // jasność światła do automatycznego zapalania
|
|
float Global::SunAngle = 0.0f;
|
|
int Global::ScreenWidth = 1;
|
|
int Global::ScreenHeight = 1;
|
|
float Global::ZoomFactor = 1.0f;
|
|
float Global::FieldOfView = 45.0f;
|
|
GLFWwindow *Global::window;
|
|
bool Global::shiftState;
|
|
bool Global::ctrlState;
|
|
int Global::iCameraLast = -1;
|
|
std::string Global::asVersion = "couldn't retrieve version string";
|
|
bool Global::ControlPicking = false; // indicates controls pick mode is enabled
|
|
bool Global::InputMouse = true; // whether control pick mode can be activated
|
|
int Global::iTextMode = 0; // tryb pracy wyświetlacza tekstowego
|
|
int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // numer ekranu wyświetlacza tekstowego
|
|
double Global::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::iPause = 0; // 0x10; // globalna pauza ruchu
|
|
bool Global::bActive = true; // czy jest aktywnym oknem
|
|
TWorld *Global::pWorld = NULL;
|
|
TCamera *Global::pCamera = NULL; // parametry kamery
|
|
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 );
|
|
|
|
vector3 Global::pCameraPosition;
|
|
vector3 Global::DebugCameraPosition;
|
|
std::vector<vector3> Global::FreeCameraInit;
|
|
std::vector<vector3> Global::FreeCameraInitAngle;
|
|
// parametry scenerii
|
|
GLfloat Global::FogColor[] = {0.6f, 0.7f, 0.8f};
|
|
double Global::fFogStart = 1700;
|
|
double Global::fFogEnd = 2000;
|
|
float Global::Overcast { 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
|
std::string Global::Season; // season of the year, based on simulation date
|
|
|
|
float Global::BaseDrawRange { 2500.f };
|
|
opengl_light Global::DayLight;
|
|
int Global::DynamicLightCount { 3 };
|
|
bool Global::ScaleSpecularValues { true };
|
|
bool Global::BasicRenderer { false };
|
|
bool Global::RenderShadows { true };
|
|
Global::shadowtune_t Global::shadowtune = { 2048, 250.f, 250.f, 500.f };
|
|
bool Global::bRollFix = true; // czy wykonać przeliczanie przechyłki
|
|
bool Global::bJoinEvents = false; // czy grupować eventy o tych samych nazwach
|
|
int Global::iHiddenEvents = 1; // czy łączyć eventy z torami poprzez nazwę toru
|
|
|
|
// parametry użytkowe (jak komu pasuje)
|
|
int Global::Keys[MaxKeys];
|
|
bool Global::RealisticControlMode{ false };
|
|
int Global::iWindowWidth = 800;
|
|
int Global::iWindowHeight = 600;
|
|
float Global::fDistanceFactor = Global::iWindowHeight / 768.0; // baza do przeliczania odległości dla LoD
|
|
int Global::iFeedbackMode = 1; // tryb pracy informacji zwrotnej
|
|
int Global::iFeedbackPort = 0; // dodatkowy adres dla informacji zwrotnych
|
|
bool Global::InputGamepad{ true };
|
|
bool Global::bFreeFly = false;
|
|
bool Global::bFullScreen = false;
|
|
bool Global::VSync{ false };
|
|
bool Global::bInactivePause = true; // automatyczna pauza, gdy okno nieaktywne
|
|
float Global::fMouseXScale = 1.5f;
|
|
float Global::fMouseYScale = 0.2f;
|
|
std::string Global::SceneryFile = "td.scn";
|
|
std::string Global::asHumanCtrlVehicle = "EU07-424";
|
|
int Global::iMultiplayer = 0; // blokada działania niektórych funkcji na rzecz komunikacji
|
|
double Global::fMoveLight = -1; // ruchome światło
|
|
bool Global::FakeLight{ false }; // toggle between fixed and dynamic daylight
|
|
double Global::fLatitudeDeg = 52.0; // szerokość geograficzna
|
|
float Global::fFriction = 1.0; // mnożnik tarcia - KURS90
|
|
double Global::fBrakeStep = 1.0; // krok zmiany hamulca dla klawiszy [Num3] i [Num9]
|
|
std::string Global::asLang = "pl"; // domyślny język - http://tools.ietf.org/html/bcp47
|
|
|
|
// parametry wydajnościowe (np. regulacja FPS, szybkość wczytywania)
|
|
bool Global::bAdjustScreenFreq = true;
|
|
bool Global::bEnableTraction = true;
|
|
bool Global::bLoadTraction = true;
|
|
bool Global::bLiveTraction = true;
|
|
float Global::AnisotropicFiltering = 8.0f; // requested level of anisotropic filtering. TODO: move it to renderer object
|
|
bool Global::bUseVBO = true; // czy jest VBO w karcie graficznej (czy użyć)
|
|
std::string Global::LastGLError;
|
|
GLint Global::iMaxTextureSize = 4096; // maksymalny rozmiar tekstury
|
|
bool Global::bSmoothTraction { true }; // wygładzanie drutów starym sposobem
|
|
float Global::SplineFidelity { 1.f }; // determines segment size during conversion of splines to geometry
|
|
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
|
|
int Global::iSlowMotionMask = -1; // maska wyłączanych właściwości dla zwiększenia FPS
|
|
// bool Global::bTerrainCompact=true; //czy zapisać teren w pliku
|
|
double Global::fFpsAverage = 20.0; // oczekiwana wartosć FPS
|
|
double Global::fFpsDeviation = 5.0; // odchylenie standardowe FPS
|
|
double Global::fFpsMin = 30.0; // dolna granica FPS, przy której promień scenerii będzie zmniejszany
|
|
double Global::fFpsMax = 65.0; // górna granica FPS, przy której promień scenerii będzie zwiększany
|
|
bool Global::FullPhysics { true }; // full calculations performed for each simulation step
|
|
|
|
// parametry testowe (do testowania scenerii i obiektów)
|
|
bool Global::bWireFrame = false;
|
|
|
|
// sound renderer
|
|
bool Global::bSoundEnabled = true;
|
|
float Global::AudioVolume = 1.0f;
|
|
std::string Global::AudioRenderer;
|
|
|
|
int Global::iWriteLogEnabled = 3; // maska bitowa: 1-zapis do pliku, 2-okienko, 4-nazwy torów
|
|
bool Global::MultipleLogs{ false };
|
|
|
|
// parametry do kalibracji
|
|
// kolejno współczynniki dla potęg 0, 1, 2, 3 wartości odczytanej z urządzenia
|
|
double Global::fCalibrateIn[6][6] = {{0, 1, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 0, 0}};
|
|
double Global::fCalibrateOut[7][6] = {{0, 1, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 0, 0},
|
|
{0, 1, 0, 0, 0, 0}};
|
|
double Global::fCalibrateOutMax[7] = {0, 0, 0, 0, 0, 0, 0};
|
|
int Global::iCalibrateOutDebugInfo = -1;
|
|
int Global::iPoKeysPWM[7] = {0, 1, 2, 3, 4, 5, 6};
|
|
// parametry przejściowe (do usunięcia)
|
|
// bool Global::bTimeChange=false; //Ra: ZiomalCl wyłączył starą wersję nocy
|
|
// bool Global::bRenderAlpha=true; //Ra: wywaliłam tę flagę
|
|
bool Global::bnewAirCouplers = true;
|
|
double Global::fTimeSpeed = 1.0; // przyspieszenie czasu, zmienna do testów
|
|
bool Global::bHideConsole = false; // hunter-271211: ukrywanie konsoli
|
|
//randomizacja
|
|
std::mt19937 Global::random_engine = std::mt19937(std::time(NULL));
|
|
// maciek001: konfiguracja wstępna portu COM
|
|
bool Global::bMWDmasterEnable = false; // główne włączenie portu!
|
|
bool Global::bMWDdebugEnable = false; // włącz dodawanie do logu
|
|
int Global::iMWDDebugMode = 0; // co ma wyświetlać w logu
|
|
std::string Global::sMWDPortId = "COM1"; // nazwa portu z którego korzystamy
|
|
unsigned long int Global::iMWDBaudrate = 9600; // prędkość transmisji danych
|
|
bool Global::bMWDInputEnable = false; // włącz wejścia
|
|
bool Global::bMWDBreakEnable = false; // włącz wejścia analogowe
|
|
double Global::fMWDAnalogInCalib[4][2] = { { 0, 1023 },{ 0, 1023 },{ 0, 1023 },{ 0, 1023 } }; // wartość max potencjometru, wartość min potencjometru, rozdzielczość (max. wartość jaka może być)
|
|
double Global::fMWDzg[2] = { 0.9, 1023 };
|
|
double Global::fMWDpg[2] = { 0.8, 1023 };
|
|
double Global::fMWDph[2] = { 0.6, 1023 };
|
|
double Global::fMWDvolt[2] = { 4000, 1023 };
|
|
double Global::fMWDamp[2] = { 800, 1023 };
|
|
double Global::fMWDlowVolt[2] = { 150, 1023 };
|
|
int Global::iMWDdivider = 5;
|
|
|
|
//---------------------------------------------------------------------------
|
|
//---------------------------------------------------------------------------
|
|
//---------------------------------------------------------------------------
|
|
|
|
void Global::LoadIniFile(std::string asFileName)
|
|
{
|
|
FreeCameraInit.resize( 10 );
|
|
FreeCameraInitAngle.resize( 10 );
|
|
cParser parser(asFileName, cParser::buffer_FILE);
|
|
ConfigParse(parser);
|
|
};
|
|
|
|
void Global::ConfigParse(cParser &Parser)
|
|
{
|
|
|
|
std::string token;
|
|
do
|
|
{
|
|
|
|
token = "";
|
|
Parser.getTokens();
|
|
Parser >> token;
|
|
|
|
if (token == "sceneryfile")
|
|
{
|
|
|
|
Parser.getTokens();
|
|
Parser >> Global::SceneryFile;
|
|
}
|
|
else if (token == "humanctrlvehicle")
|
|
{
|
|
|
|
Parser.getTokens();
|
|
Parser >> Global::asHumanCtrlVehicle;
|
|
}
|
|
else if( token == "fieldofview" ) {
|
|
|
|
Parser.getTokens( 1, false );
|
|
Parser >> Global::FieldOfView;
|
|
// guard against incorrect values
|
|
Global::FieldOfView = clamp( Global::FieldOfView, 15.0f, 75.0f );
|
|
}
|
|
else if (token == "width")
|
|
{
|
|
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::iWindowWidth;
|
|
}
|
|
else if (token == "height")
|
|
{
|
|
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::iWindowHeight;
|
|
}
|
|
else if (token == "heightbase")
|
|
{
|
|
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::fDistanceFactor;
|
|
}
|
|
else if (token == "fullscreen")
|
|
{
|
|
|
|
Parser.getTokens();
|
|
Parser >> Global::bFullScreen;
|
|
}
|
|
else if( token == "vsync" ) {
|
|
|
|
Parser.getTokens();
|
|
Parser >> Global::VSync;
|
|
}
|
|
else if (token == "freefly")
|
|
{ // Mczapkie-130302
|
|
|
|
Parser.getTokens();
|
|
Parser >> Global::bFreeFly;
|
|
Parser.getTokens(3, false);
|
|
Parser >>
|
|
Global::FreeCameraInit[0].x,
|
|
Global::FreeCameraInit[0].y,
|
|
Global::FreeCameraInit[0].z;
|
|
}
|
|
else if (token == "wireframe")
|
|
{
|
|
|
|
Parser.getTokens();
|
|
Parser >> Global::bWireFrame;
|
|
}
|
|
else if (token == "debugmode")
|
|
{ // McZapkie! - DebugModeFlag uzywana w mover.pas,
|
|
// warto tez blokowac cheaty gdy false
|
|
Parser.getTokens();
|
|
Parser >> DebugModeFlag;
|
|
}
|
|
else if (token == "soundenabled")
|
|
{ // McZapkie-040302 - blokada dzwieku - przyda
|
|
// sie do debugowania oraz na komp. bez karty
|
|
// dzw.
|
|
Parser.getTokens();
|
|
Parser >> Global::bSoundEnabled;
|
|
}
|
|
else if( token == "sound.openal.renderer" ) {
|
|
// selected device for audio renderer
|
|
Global::AudioRenderer = Parser.getToken<std::string>( false ); // case-sensitive
|
|
}
|
|
// else if (str==AnsiString("renderalpha")) //McZapkie-1312302 - dwuprzebiegowe renderowanie
|
|
// bRenderAlpha=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
|
else if (token == "physicslog")
|
|
{ // McZapkie-030402 - logowanie parametrow
|
|
// fizycznych dla kazdego pojazdu z maszynista
|
|
Parser.getTokens();
|
|
Parser >> WriteLogFlag;
|
|
}
|
|
else if (token == "fullphysics")
|
|
{ // McZapkie-291103 - usypianie fizyki
|
|
|
|
Parser.getTokens();
|
|
Parser >> Global::FullPhysics;
|
|
}
|
|
else if (token == "debuglog")
|
|
{
|
|
// McZapkie-300402 - wylaczanie log.txt
|
|
Parser.getTokens();
|
|
Parser >> token;
|
|
if (token == "yes")
|
|
{
|
|
Global::iWriteLogEnabled = 3;
|
|
}
|
|
else if (token == "no")
|
|
{
|
|
Global::iWriteLogEnabled = 0;
|
|
}
|
|
else
|
|
{
|
|
Global::iWriteLogEnabled = stol_def(token,3);
|
|
}
|
|
}
|
|
else if( token == "multiplelogs" ) {
|
|
Parser.getTokens();
|
|
Parser >> Global::MultipleLogs;
|
|
}
|
|
else if( token == "adjustscreenfreq" )
|
|
{
|
|
// McZapkie-240403 - czestotliwosc odswiezania ekranu
|
|
Parser.getTokens();
|
|
Parser >> Global::bAdjustScreenFreq;
|
|
}
|
|
else if (token == "mousescale")
|
|
{
|
|
// McZapkie-060503 - czulosc ruchu myszy (krecenia glowa)
|
|
Parser.getTokens(2, false);
|
|
Parser >> Global::fMouseXScale >> Global::fMouseYScale;
|
|
}
|
|
else if( token == "mousecontrol" ) {
|
|
// whether control pick mode can be activated
|
|
Parser.getTokens();
|
|
Parser >> Global::InputMouse;
|
|
}
|
|
else if (token == "enabletraction")
|
|
{
|
|
// Winger 040204 - 'zywe' patyki dostosowujace sie do trakcji; Ra 2014-03: teraz łamanie
|
|
Parser.getTokens();
|
|
Parser >> Global::bEnableTraction;
|
|
}
|
|
else if (token == "loadtraction")
|
|
{
|
|
// Winger 140404 - ladowanie sie trakcji
|
|
Parser.getTokens();
|
|
Parser >> Global::bLoadTraction;
|
|
}
|
|
else if (token == "friction")
|
|
{ // mnożnik tarcia - KURS90
|
|
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::fFriction;
|
|
}
|
|
else if (token == "livetraction")
|
|
{
|
|
// Winger 160404 - zaleznosc napiecia loka od trakcji;
|
|
// Ra 2014-03: teraz prąd przy braku sieci
|
|
Parser.getTokens();
|
|
Parser >> Global::bLiveTraction;
|
|
}
|
|
else if (token == "skyenabled")
|
|
{
|
|
// youBy - niebo
|
|
Parser.getTokens();
|
|
Parser >> token;
|
|
Global::asSky = (token == "yes" ? "1" : "0");
|
|
}
|
|
else if (token == "defaultext")
|
|
{
|
|
// ShaXbee - domyslne rozszerzenie tekstur
|
|
Parser.getTokens();
|
|
Parser >> token;
|
|
if (token == "tga")
|
|
{
|
|
// domyślnie od TGA
|
|
Global::szDefaultExt = Global::szTexturesTGA;
|
|
}
|
|
else {
|
|
Global::szDefaultExt =
|
|
( token[ 0 ] == '.' ?
|
|
token :
|
|
"." + token );
|
|
}
|
|
}
|
|
else if (token == "newaircouplers")
|
|
{
|
|
|
|
Parser.getTokens();
|
|
Parser >> Global::bnewAirCouplers;
|
|
}
|
|
else if( token == "anisotropicfiltering" ) {
|
|
|
|
Parser.getTokens( 1, false );
|
|
Parser >> Global::AnisotropicFiltering;
|
|
}
|
|
else if( token == "usevbo" )
|
|
{
|
|
|
|
Parser.getTokens();
|
|
Parser >> Global::bUseVBO;
|
|
}
|
|
else if (token == "feedbackmode")
|
|
{
|
|
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::iFeedbackMode;
|
|
}
|
|
else if (token == "feedbackport")
|
|
{
|
|
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::iFeedbackPort;
|
|
}
|
|
else if (token == "multiplayer")
|
|
{
|
|
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::iMultiplayer;
|
|
}
|
|
else if (token == "maxtexturesize")
|
|
{
|
|
// wymuszenie przeskalowania tekstur
|
|
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; }
|
|
}
|
|
else if (token == "movelight")
|
|
{
|
|
// numer dnia w roku albo -1
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::fMoveLight;
|
|
if (Global::fMoveLight == 0.f)
|
|
{ // pobranie daty z systemu
|
|
std::time_t timenow = std::time(0);
|
|
std::tm *localtime = std::localtime(&timenow);
|
|
Global::fMoveLight = localtime->tm_yday + 1; // numer bieżącego dnia w roku
|
|
}
|
|
Global::pWorld->compute_season( Global::fMoveLight );
|
|
}
|
|
else if( token == "dynamiclights" ) {
|
|
// number of dynamic lights in the scene
|
|
Parser.getTokens( 1, false );
|
|
Parser >> Global::DynamicLightCount;
|
|
// clamp the light number
|
|
// max 8 lights per opengl specs, minus one used for sun. at least one light for controlled vehicle
|
|
Global::DynamicLightCount = clamp( Global::DynamicLightCount, 1, 7 );
|
|
}
|
|
else if( token == "scalespeculars" ) {
|
|
// whether strength of specular highlights should be adjusted (generally needed for legacy 3d models)
|
|
Parser.getTokens();
|
|
Parser >> Global::ScaleSpecularValues;
|
|
}
|
|
else if( token == "gfxrenderer" ) {
|
|
// shadow render toggle
|
|
std::string gfxrenderer;
|
|
Parser.getTokens();
|
|
Parser >> gfxrenderer;
|
|
Global::BasicRenderer = ( gfxrenderer == "simple" );
|
|
}
|
|
else if( token == "shadows" ) {
|
|
// shadow render toggle
|
|
Parser.getTokens();
|
|
Parser >> Global::RenderShadows;
|
|
}
|
|
else if( token == "shadowtune" ) {
|
|
Parser.getTokens( 4, false );
|
|
Parser
|
|
>> Global::shadowtune.map_size
|
|
>> Global::shadowtune.width
|
|
>> Global::shadowtune.depth
|
|
>> Global::shadowtune.distance;
|
|
}
|
|
else if (token == "smoothtraction")
|
|
{
|
|
// podwójna jasność ambient
|
|
Parser.getTokens();
|
|
Parser >> Global::bSmoothTraction;
|
|
}
|
|
else if( token == "splinefidelity" ) {
|
|
// segment size during spline->geometry conversion
|
|
float splinefidelity;
|
|
Parser.getTokens();
|
|
Parser >> splinefidelity;
|
|
Global::SplineFidelity = clamp( splinefidelity, 1.f, 4.f );
|
|
}
|
|
else if (token == "timespeed")
|
|
{
|
|
// przyspieszenie czasu, zmienna do testów
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::fTimeSpeed;
|
|
}
|
|
else if (token == "multisampling")
|
|
{
|
|
// tryb antyaliasingu: 0=brak,1=2px,2=4px
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::iMultisampling;
|
|
}
|
|
else if (token == "glutfont")
|
|
{
|
|
// tekst generowany przez GLUT
|
|
Parser.getTokens();
|
|
Parser >> Global::bGlutFont;
|
|
}
|
|
else if (token == "latitude")
|
|
{
|
|
// szerokość geograficzna
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::fLatitudeDeg;
|
|
}
|
|
else if (token == "convertmodels")
|
|
{
|
|
// tworzenie plików binarnych
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::iConvertModels;
|
|
// temporary override, to prevent generation of .e3d not compatible with old exe
|
|
Global::iConvertModels =
|
|
( Global::iConvertModels > 128 ?
|
|
Global::iConvertModels - 128 :
|
|
0 );
|
|
}
|
|
else if (token == "inactivepause")
|
|
{
|
|
// automatyczna pauza, gdy okno nieaktywne
|
|
Parser.getTokens();
|
|
Parser >> Global::bInactivePause;
|
|
}
|
|
else if (token == "slowmotion")
|
|
{
|
|
// tworzenie plików binarnych
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::iSlowMotionMask;
|
|
}
|
|
else if (token == "hideconsole")
|
|
{
|
|
// hunter-271211: ukrywanie konsoli
|
|
Parser.getTokens();
|
|
Parser >> Global::bHideConsole;
|
|
}
|
|
else if (token == "rollfix")
|
|
{
|
|
// Ra: poprawianie przechyłki, aby wewnętrzna szyna była "pozioma"
|
|
Parser.getTokens();
|
|
Parser >> Global::bRollFix;
|
|
}
|
|
else if (token == "fpsaverage")
|
|
{
|
|
// oczekiwana wartość FPS
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::fFpsAverage;
|
|
}
|
|
else if (token == "fpsdeviation")
|
|
{
|
|
// odchylenie standardowe FPS
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::fFpsDeviation;
|
|
}
|
|
else if (token == "calibratein")
|
|
{
|
|
// parametry kalibracji wejść
|
|
Parser.getTokens(1, false);
|
|
int in;
|
|
Parser >> in;
|
|
if ((in < 0) || (in > 5))
|
|
{
|
|
in = 5; // na ostatni, bo i tak trzeba pominąć wartości
|
|
}
|
|
Parser.getTokens(4, false);
|
|
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
|
|
Global::fCalibrateIn[in][4] = 0.0; // mnożnik 4 potęgi
|
|
Global::fCalibrateIn[in][5] = 0.0; // mnożnik 5 potęgi
|
|
}
|
|
else if (token == "calibrate5din")
|
|
{
|
|
// parametry kalibracji wejść
|
|
Parser.getTokens(1, false);
|
|
int in;
|
|
Parser >> in;
|
|
if ((in < 0) || (in > 5))
|
|
{
|
|
in = 5; // na ostatni, bo i tak trzeba pominąć wartości
|
|
}
|
|
Parser.getTokens(6, false);
|
|
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
|
|
>> Global::fCalibrateIn[in][4] // mnożnik 4 potęgi
|
|
>> Global::fCalibrateIn[in][5]; // mnożnik 5 potęgi
|
|
}
|
|
else if (token == "calibrateout")
|
|
{
|
|
// parametry kalibracji wyjść
|
|
Parser.getTokens(1, false);
|
|
int out;
|
|
Parser >> out;
|
|
if ((out < 0) || (out > 6))
|
|
{
|
|
out = 6; // na ostatni, bo i tak trzeba pominąć wartości
|
|
}
|
|
Parser.getTokens(4, false);
|
|
Parser >> Global::fCalibrateOut[out][0] // wyraz wolny
|
|
>> Global::fCalibrateOut[out][1] // mnożnik liniowy
|
|
>> Global::fCalibrateOut[out][2] // mnożnik dla kwadratu
|
|
>> Global::fCalibrateOut[out][3]; // mnożnik dla sześcianu
|
|
Global::fCalibrateOut[out][4] = 0.0; // mnożnik dla 4 potęgi
|
|
Global::fCalibrateOut[out][5] = 0.0; // mnożnik dla 5 potęgi
|
|
}
|
|
else if (token == "calibrate5dout")
|
|
{
|
|
// parametry kalibracji wyjść
|
|
Parser.getTokens(1, false);
|
|
int out;
|
|
Parser >> out;
|
|
if ((out < 0) || (out > 6))
|
|
{
|
|
out = 6; // na ostatni, bo i tak trzeba pominąć wartości
|
|
}
|
|
Parser.getTokens(6, false);
|
|
Parser >> Global::fCalibrateOut[out][0] // wyraz wolny
|
|
>> Global::fCalibrateOut[out][1] // mnożnik liniowy
|
|
>> Global::fCalibrateOut[out][2] // mnożnik dla kwadratu
|
|
>> Global::fCalibrateOut[out][3] // mnożnik dla sześcianu
|
|
>> Global::fCalibrateOut[out][4] // mnożnik dla 4 potęgi
|
|
>> Global::fCalibrateOut[out][5]; // mnożnik dla 5 potęgi
|
|
}
|
|
else if (token == "calibrateoutmaxvalues")
|
|
{
|
|
// maksymalne wartości jakie można wyświetlić na mierniku
|
|
Parser.getTokens(7, false);
|
|
Parser >> Global::fCalibrateOutMax[0] >> Global::fCalibrateOutMax[1] >>
|
|
Global::fCalibrateOutMax[2] >> Global::fCalibrateOutMax[3] >>
|
|
Global::fCalibrateOutMax[4] >> Global::fCalibrateOutMax[5] >>
|
|
Global::fCalibrateOutMax[6];
|
|
}
|
|
else if (token == "calibrateoutdebuginfo")
|
|
{
|
|
// wyjście z info o przebiegu kalibracji
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::iCalibrateOutDebugInfo;
|
|
}
|
|
else if (token == "pwm")
|
|
{
|
|
// zmiana numerów wyjść PWM
|
|
Parser.getTokens(2, false);
|
|
int pwm_out, pwm_no;
|
|
Parser >> pwm_out >> pwm_no;
|
|
Global::iPoKeysPWM[pwm_out] = pwm_no;
|
|
}
|
|
else if (token == "brakestep")
|
|
{
|
|
// krok zmiany hamulca dla klawiszy [Num3] i [Num9]
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::fBrakeStep;
|
|
}
|
|
else if (token == "joinduplicatedevents")
|
|
{
|
|
// czy grupować eventy o tych samych nazwach
|
|
Parser.getTokens();
|
|
Parser >> Global::bJoinEvents;
|
|
}
|
|
else if (token == "hiddenevents")
|
|
{
|
|
// czy łączyć eventy z torami poprzez nazwę toru
|
|
Parser.getTokens(1, false);
|
|
Parser >> Global::iHiddenEvents;
|
|
}
|
|
else if (token == "pause")
|
|
{
|
|
// czy po wczytaniu ma być pauza?
|
|
Parser.getTokens();
|
|
Parser >> token;
|
|
iPause |= (token == "yes" ? 1 : 0);
|
|
}
|
|
else if (token == "lang")
|
|
{
|
|
// domyślny język - http://tools.ietf.org/html/bcp47
|
|
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
|
|
Parser.getTokens();
|
|
Parser >> token;
|
|
TPythonInterpreter::getInstance()->setScreenRendererPriority(token.c_str());
|
|
}
|
|
else if( token == "input.gamepad" ) {
|
|
// czy grupować eventy o tych samych nazwach
|
|
Parser.getTokens();
|
|
Parser >> Global::InputGamepad;
|
|
}
|
|
// maciek001: ustawienia MWD
|
|
else if (token == "mwdmasterenable") { // główne włączenie maszyny!
|
|
Parser.getTokens();
|
|
Parser >> bMWDmasterEnable;
|
|
if (bMWDdebugEnable) WriteLog("SerialPort Master Enable");
|
|
}
|
|
else if (token == "mwddebugenable") { // logowanie pracy
|
|
Parser.getTokens();
|
|
Parser >> bMWDdebugEnable;
|
|
if (bMWDdebugEnable) WriteLog("MWD Debug Mode On");
|
|
}
|
|
else if (token == "mwddebugmode") { // co ma być debugowane?
|
|
Parser.getTokens(1, false);
|
|
Parser >> iMWDDebugMode;
|
|
if (bMWDdebugEnable) WriteLog("Debug Mode = " + to_string(iMWDDebugMode));
|
|
}
|
|
else if (token == "mwdcomportname") { // nazwa portu COM
|
|
Parser.getTokens();
|
|
Parser >> sMWDPortId;
|
|
if (bMWDdebugEnable) WriteLog("PortName " + sMWDPortId);
|
|
}
|
|
else if (token == "mwdbaudrate") { // prędkość transmisji danych
|
|
Parser.getTokens(1, false);
|
|
Parser >> iMWDBaudrate;
|
|
if (bMWDdebugEnable) WriteLog("Baud rate = " + to_string((int)(iMWDBaudrate / 1000)) + (" kbps"));
|
|
}
|
|
else if (token == "mwdinputenable") { // włącz wejścia
|
|
Parser.getTokens();
|
|
Parser >> bMWDInputEnable;
|
|
if (bMWDdebugEnable && bMWDInputEnable) WriteLog("MWD Input Enable");
|
|
}
|
|
else if (token == "mwdbreakenable") { // włącz obsługę hamulców
|
|
Parser.getTokens();
|
|
Parser >> bMWDBreakEnable;
|
|
if (bMWDdebugEnable && bMWDBreakEnable) WriteLog("MWD Break Enable");
|
|
}
|
|
else if (token == "mwdmainbreakconfig") { // ustawienia hamulca zespolonego
|
|
Parser.getTokens(2, false);
|
|
Parser >> fMWDAnalogInCalib[0][0] >> fMWDAnalogInCalib[0][1];
|
|
if (bMWDdebugEnable) WriteLog("Main break settings: " + to_string(fMWDAnalogInCalib[0][0]) + (" ") + to_string(fMWDAnalogInCalib[0][1]));
|
|
}
|
|
else if (token == "mwdlocbreakconfig") { // ustawienia hamulca lokomotywy
|
|
Parser.getTokens(2, false);
|
|
Parser >> fMWDAnalogInCalib[1][0] >> fMWDAnalogInCalib[1][1];
|
|
if (bMWDdebugEnable) WriteLog("Locomotive break settings: " + to_string(fMWDAnalogInCalib[1][0]) + (" ") + to_string(fMWDAnalogInCalib[1][1]));
|
|
}
|
|
else if (token == "mwdanalogin1config") { // ustawienia hamulca zespolonego
|
|
Parser.getTokens(2, false);
|
|
Parser >> fMWDAnalogInCalib[2][0] >> fMWDAnalogInCalib[2][1];
|
|
if (bMWDdebugEnable) WriteLog("Analog input 1 settings: " + to_string(fMWDAnalogInCalib[2][0]) + (" ") + to_string(fMWDAnalogInCalib[2][1]));
|
|
}
|
|
else if (token == "mwdanalogin2config") { // ustawienia hamulca lokomotywy
|
|
Parser.getTokens(2, false);
|
|
Parser >> fMWDAnalogInCalib[3][0] >> fMWDAnalogInCalib[3][1];
|
|
if (bMWDdebugEnable) WriteLog("Analog input 2 settings: " + to_string(fMWDAnalogInCalib[3][0]) + (" ") + to_string(fMWDAnalogInCalib[3][1]));
|
|
}
|
|
else if (token == "mwdmaintankpress") { // max ciśnienie w zbiorniku głownym i rozdzielczość
|
|
Parser.getTokens(2, false);
|
|
Parser >> fMWDzg[0] >> fMWDzg[1];
|
|
if (bMWDdebugEnable) WriteLog("MainAirTank settings: " + to_string(fMWDzg[0]) + (" ") + to_string(fMWDzg[1]));
|
|
}
|
|
else if (token == "mwdmainpipepress") { // max ciśnienie w przewodzie głownym i rozdzielczość
|
|
Parser.getTokens(2, false);
|
|
Parser >> fMWDpg[0] >> fMWDpg[1];
|
|
if (bMWDdebugEnable) WriteLog("MainAirPipe settings: " + to_string(fMWDpg[0]) + (" ") + to_string(fMWDpg[1]));
|
|
}
|
|
else if (token == "mwdbreakpress") { // max ciśnienie w hamulcach i rozdzielczość
|
|
Parser.getTokens(2, false);
|
|
Parser >> fMWDph[0] >> fMWDph[1];
|
|
if (bMWDdebugEnable) WriteLog("AirPipe settings: " + to_string(fMWDph[0]) + (" ") + to_string(fMWDph[1]));
|
|
}
|
|
else if (token == "mwdhivoltmeter") { // max napięcie na woltomierzu WN
|
|
Parser.getTokens(2, false);
|
|
Parser >> fMWDvolt[0] >> fMWDvolt[1];
|
|
if (bMWDdebugEnable) WriteLog("VoltMeter settings: " + to_string(fMWDvolt[0]) + (" ") + to_string(fMWDvolt[1]));
|
|
}
|
|
else if (token == "mwdhiampmeter") {
|
|
Parser.getTokens(2, false);
|
|
Parser >> fMWDamp[0] >> fMWDamp[1];
|
|
if (bMWDdebugEnable) WriteLog("Amp settings: " + to_string(fMWDamp[0]) + (" ") + to_string(fMWDamp[1]));
|
|
}
|
|
else if (token == "mwdlowvoltmeter") {
|
|
Parser.getTokens(2, false);
|
|
Parser >> fMWDlowVolt[0] >> fMWDlowVolt[1];
|
|
if (bMWDdebugEnable) WriteLog("Low VoltMeter settings: " + to_string(fMWDlowVolt[0]) + (" ") + to_string(fMWDlowVolt[1]));
|
|
}
|
|
else if (token == "mwddivider") {
|
|
Parser.getTokens(1, false);
|
|
Parser >> iMWDdivider;
|
|
if (iMWDdivider == 0)
|
|
{
|
|
WriteLog("Dzielnik nie może być równy ZERO! Ustawiam na 1!");
|
|
iMWDdivider = 1;
|
|
}
|
|
if (bMWDdebugEnable) WriteLog("Divider = " + to_string(iMWDdivider));
|
|
}
|
|
} while ((token != "") && (token != "endconfig")); //(!Parser->EndOfFile)
|
|
// na koniec trochę zależności
|
|
if (!bLoadTraction) // wczytywanie drutów i słupów
|
|
{ // tutaj wyłączenie, bo mogą nie być zdefiniowane w INI
|
|
bEnableTraction = false; // false = pantograf się nie połamie
|
|
bLiveTraction = false; // false = pantografy zawsze zbierają 95% MaxVoltage
|
|
}
|
|
if (iMultisampling)
|
|
{ // antyaliasing całoekranowy wyłącza rozmywanie drutów
|
|
bSmoothTraction = false;
|
|
}
|
|
if (iMultiplayer > 0)
|
|
{
|
|
bInactivePause = false; // okno "w tle" nie może pauzować, jeśli włączona komunikacja
|
|
// pauzowanie jest zablokowane dla (iMultiplayer&2)>0, więc iMultiplayer=1 da się zapauzować
|
|
// (tryb instruktora)
|
|
}
|
|
/*
|
|
fFpsMin = fFpsAverage -
|
|
fFpsDeviation; // dolna granica FPS, przy której promień scenerii będzie zmniejszany
|
|
fFpsMax = fFpsAverage +
|
|
fFpsDeviation; // górna granica FPS, przy której promień scenerii będzie zwiększany
|
|
*/
|
|
if (iPause)
|
|
iTextMode = GLFW_KEY_F1; // jak pauza, to pokazać zegar
|
|
/* this won't execute anymore with the old parser removed
|
|
// TBD: remove, or launch depending on passed flag?
|
|
if (qp)
|
|
{ // to poniżej wykonywane tylko raz, jedynie po wczytaniu eu07.ini*/
|
|
Console::ModeSet(iFeedbackMode, iFeedbackPort); // tryb pracy konsoli sterowniczej
|
|
/*iFpsRadiusMax = 0.000025 * fFpsRadiusMax *
|
|
fFpsRadiusMax; // maksymalny promień renderowania 3000.0 -> 225
|
|
if (iFpsRadiusMax > 400)
|
|
iFpsRadiusMax = 400;
|
|
if (fDistanceFactor > 1.0)
|
|
{ // dla 1.0 specjalny tryb bez przeliczania
|
|
fDistanceFactor =
|
|
iWindowHeight /
|
|
fDistanceFactor; // fDistanceFactor>1.0 dla rozdzielczości większych niż bazowa
|
|
fDistanceFactor *=
|
|
(iMultisampling + 1.0) *
|
|
fDistanceFactor; // do kwadratu, bo większość odległości to ich kwadraty
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
void Global::InitKeys()
|
|
{
|
|
Keys[k_IncMainCtrl] = GLFW_KEY_KP_ADD;
|
|
Keys[k_IncMainCtrlFAST] = GLFW_KEY_KP_ADD;
|
|
Keys[k_DecMainCtrl] = GLFW_KEY_KP_SUBTRACT;
|
|
Keys[k_DecMainCtrlFAST] = GLFW_KEY_KP_SUBTRACT;
|
|
Keys[k_IncScndCtrl] = GLFW_KEY_KP_DIVIDE;
|
|
Keys[k_IncScndCtrlFAST] = GLFW_KEY_KP_DIVIDE;
|
|
Keys[k_DecScndCtrl] = GLFW_KEY_KP_MULTIPLY;
|
|
Keys[k_DecScndCtrlFAST] = GLFW_KEY_KP_MULTIPLY;
|
|
|
|
Keys[k_IncLocalBrakeLevel] = GLFW_KEY_KP_1;
|
|
Keys[k_DecLocalBrakeLevel] = GLFW_KEY_KP_7;
|
|
Keys[k_IncBrakeLevel] = GLFW_KEY_KP_3;
|
|
Keys[k_DecBrakeLevel] = GLFW_KEY_KP_9;
|
|
Keys[k_Releaser] = GLFW_KEY_KP_6;
|
|
Keys[k_EmergencyBrake] = GLFW_KEY_KP_0;
|
|
Keys[k_Brake3] = GLFW_KEY_KP_8;
|
|
Keys[k_Brake2] = GLFW_KEY_KP_5;
|
|
Keys[k_Brake1] = GLFW_KEY_KP_2;
|
|
Keys[k_Brake0] = GLFW_KEY_KP_4;
|
|
Keys[k_WaveBrake] = GLFW_KEY_KP_DECIMAL;
|
|
|
|
Keys[k_AntiSlipping] = GLFW_KEY_KP_ENTER;
|
|
Keys[k_Sand] = 'S';
|
|
Keys[k_Main] = 'M';
|
|
Keys[k_Active] = 'W';
|
|
Keys[k_Battery] = 'J';
|
|
Keys[k_DirectionForward] = 'D';
|
|
Keys[k_DirectionBackward] = 'R';
|
|
Keys[k_Fuse] = 'N';
|
|
Keys[k_Compressor] = 'C';
|
|
Keys[k_Converter] = 'X';
|
|
Keys[k_MaxCurrent] = 'F';
|
|
Keys[k_CurrentAutoRelay] = 'G';
|
|
Keys[k_BrakeProfile] = 'B';
|
|
Keys[k_CurrentNext] = 'Z';
|
|
|
|
Keys[k_Czuwak] = ' ';
|
|
Keys[k_Horn] = 'A';
|
|
Keys[k_Horn2] = 'A';
|
|
|
|
Keys[k_FailedEngineCutOff] = 'E';
|
|
|
|
Keys[k_MechUp] = GLFW_KEY_PAGE_UP;
|
|
Keys[k_MechDown] = GLFW_KEY_PAGE_DOWN;
|
|
Keys[k_MechLeft] = GLFW_KEY_LEFT;
|
|
Keys[k_MechRight] = GLFW_KEY_RIGHT;
|
|
Keys[k_MechForward] = GLFW_KEY_UP;
|
|
Keys[k_MechBackward] = GLFW_KEY_DOWN;
|
|
|
|
Keys[k_CabForward] = GLFW_KEY_HOME;
|
|
Keys[k_CabBackward] = GLFW_KEY_END;
|
|
|
|
Keys[k_Couple] = GLFW_KEY_INSERT;
|
|
Keys[k_DeCouple] = GLFW_KEY_DELETE;
|
|
|
|
Keys[k_ProgramQuit] = GLFW_KEY_F10;
|
|
Keys[k_ProgramHelp] = GLFW_KEY_F1;
|
|
Keys[k_WalkMode] = GLFW_KEY_F5;
|
|
|
|
Keys[k_OpenLeft] = ',';
|
|
Keys[k_OpenRight] = '.';
|
|
Keys[k_CloseLeft] = ',';
|
|
Keys[k_CloseRight] = '.';
|
|
Keys[k_DepartureSignal] = '/';
|
|
|
|
// Winger 160204 - obsluga pantografow
|
|
Keys[k_PantFrontUp] = 'P'; // Ra: zamieniony przedni z tylnym
|
|
Keys[k_PantFrontDown] = 'P';
|
|
Keys[k_PantRearUp] = 'O';
|
|
Keys[k_PantRearDown] = 'O';
|
|
// Winger 020304 - ogrzewanie
|
|
Keys[k_Heating] = 'H';
|
|
// headlights
|
|
Keys[k_LeftSign] = 'Y';
|
|
Keys[k_UpperSign] = 'U';
|
|
Keys[k_RightSign] = 'I';
|
|
Keys[k_DimHeadlights] = 'L';
|
|
// tail lights
|
|
Keys[k_EndSign] = 'T';
|
|
|
|
Keys[k_SmallCompressor] = 'V';
|
|
Keys[k_StLinOff] = 'L';
|
|
// ABu 090305 - przyciski uniwersalne, do roznych bajerow :)
|
|
Keys[k_Univ1] = '[';
|
|
Keys[k_Univ2] = ']';
|
|
Keys[k_Univ3] = ';';
|
|
Keys[k_Univ4] = '\'';
|
|
}
|
|
|
|
/*
|
|
vector3 Global::GetCameraPosition()
|
|
{
|
|
return pCameraPosition;
|
|
}
|
|
*/
|
|
void Global::SetCameraPosition(vector3 pNewCameraPosition)
|
|
{
|
|
pCameraPosition = pNewCameraPosition;
|
|
}
|
|
|
|
void Global::TrainDelete(TDynamicObject *d)
|
|
{ // usunięcie pojazdu prowadzonego przez użytkownika
|
|
if (pWorld)
|
|
pWorld->TrainDelete(d);
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TTranscripts::TTranscripts()
|
|
{
|
|
/*
|
|
iCount = 0; // brak linijek do wyświetlenia
|
|
iStart = 0; // wypełniać od linijki 0
|
|
for (int i = 0; i < MAX_TRANSCRIPTS; ++i)
|
|
{ // to do konstruktora można by dać
|
|
aLines[i].fHide = -1.0; // wolna pozycja (czas symulacji, 360.0 to doba)
|
|
aLines[i].iNext = -1; // nie ma kolejnej
|
|
}
|
|
*/
|
|
fRefreshTime = 360.0; // wartośc zaporowa
|
|
};
|
|
TTranscripts::~TTranscripts(){};
|
|
|
|
void TTranscripts::AddLine(std::string const &txt, float show, float hide, bool it)
|
|
{ // dodanie linii do tabeli, (show) i (hide) w [s] od aktualnego czasu
|
|
if (show == hide)
|
|
return; // komentarz jest ignorowany
|
|
show = Global::fTimeAngleDeg + show / 240.0; // jeśli doba to 360, to 1s będzie równe 1/240
|
|
hide = Global::fTimeAngleDeg + hide / 240.0;
|
|
|
|
TTranscript transcript;
|
|
transcript.asText = txt;
|
|
transcript.fShow = show;
|
|
transcript.fHide = hide;
|
|
transcript.bItalic = it;
|
|
aLines.emplace_back( transcript );
|
|
// set the next refresh time while at it
|
|
// TODO, TBD: sort the transcript lines? in theory, they should be coming arranged in the right order anyway
|
|
// short of cases with multiple sounds overleaping
|
|
fRefreshTime = aLines.front().fHide;
|
|
/*
|
|
int i = iStart, j, k; // od czegoś trzeba zacząć
|
|
while ((aLines[i].iNext >= 0) ? (aLines[aLines[i].iNext].fShow <= show) :
|
|
false) // póki nie koniec i wcześniej puszczane
|
|
i = aLines[i].iNext; // przejście do kolejnej linijki
|
|
*/
|
|
/*
|
|
//(i) wskazuje na linię, po której należy wstawić dany tekst, chyba że
|
|
while (txt ? *txt : false)
|
|
for (j = 0; j < MAX_TRANSCRIPTS; ++j)
|
|
if (aLines[j].fHide < 0.0)
|
|
{ // znaleziony pierwszy wolny
|
|
aLines[j].iNext = aLines[i].iNext; // dotychczasowy następny będzie za nowym
|
|
if (aLines[iStart].fHide < 0.0) // jeśli tablica jest pusta
|
|
iStart = j; // fHide trzeba sprawdzić przed ewentualnym nadpisaniem, gdy i=j=0
|
|
else
|
|
aLines[i].iNext = j; // a nowy będzie za tamtym wcześniejszym
|
|
aLines[j].fShow = show; // wyświetlać od
|
|
aLines[j].fHide = hide; // wyświetlać do
|
|
aLines[j].bItalic = it;
|
|
aLines[j].asText = std::string(txt); // bez sensu, wystarczyłby wskaźnik
|
|
if ((k = aLines[j].asText.find("|")) != std::string::npos)
|
|
{ // jak jest podział linijki na wiersze
|
|
aLines[j].asText = aLines[j].asText.substr(0, k - 1);
|
|
txt += k;
|
|
i = j; // kolejna linijka dopisywana będzie na koniec właśnie dodanej
|
|
}
|
|
else
|
|
txt = NULL; // koniec dodawania
|
|
if (fRefreshTime > show) // jeśli odświeżacz ustawiony jest na później
|
|
fRefreshTime = show; // to odświeżyć wcześniej
|
|
break; // więcej już nic
|
|
}
|
|
*/
|
|
};
|
|
void TTranscripts::Add(std::string const &txt, float len, bool backgorund)
|
|
{ // dodanie tekstów, długość dźwięku, czy istotne
|
|
if (true == txt.empty())
|
|
return; // pusty tekst
|
|
/*
|
|
int i = 0, j = int(0.5 + 10.0 * len); //[0.1s]
|
|
if (*txt == '[')
|
|
{ // powinny być dwa nawiasy
|
|
while (*++txt ? *txt != ']' : false)
|
|
if ((*txt >= '0') && (*txt <= '9'))
|
|
i = 10 * i + int(*txt - '0'); // pierwsza liczba aż do ]
|
|
if (*txt ? *++txt == '[' : false)
|
|
{
|
|
j = 0; // drugi nawias określa czas zakończenia wyświetlania
|
|
while (*++txt ? *txt != ']' : false)
|
|
if ((*txt >= '0') && (*txt <= '9'))
|
|
j = 10 * j + int(*txt - '0'); // druga liczba aż do ]
|
|
if (*txt)
|
|
++txt; // pominięcie drugiego ]
|
|
}
|
|
}
|
|
*/
|
|
std::string asciitext{ txt }; win1250_to_ascii( asciitext ); // TODO: launch relevant conversion table based on language
|
|
cParser parser( asciitext );
|
|
while( true == parser.getTokens( 3, false, "[]\n" ) ) {
|
|
|
|
float begin, end;
|
|
std::string transcript;
|
|
parser
|
|
>> begin
|
|
>> end
|
|
>> transcript;
|
|
AddLine( transcript, 0.10 * begin, 0.12 * end, false );
|
|
}
|
|
// try to handle malformed(?) cases with no show/hide times
|
|
std::string transcript; parser >> transcript;
|
|
while( false == transcript.empty() ) {
|
|
|
|
WriteLog( "Transcript text with no display/hide times: \"" + transcript + "\"" );
|
|
AddLine( transcript, 0.0, 0.12 * transcript.size(), false );
|
|
transcript = ""; parser >> transcript;
|
|
}
|
|
};
|
|
void TTranscripts::Update()
|
|
{ // usuwanie niepotrzebnych (nie częściej niż 10 razy na sekundę)
|
|
if( Global::fTimeAngleDeg < fRefreshTime )
|
|
return; // nie czas jeszcze na zmiany
|
|
// czas odświeżenia można ustalić wg tabelki, kiedy coś się w niej zmienia
|
|
// fRefreshTime = Global::fTimeAngleDeg + 360.0; // wartość zaporowa
|
|
|
|
while( ( false == aLines.empty() )
|
|
&& ( Global::fTimeAngleDeg >= aLines.front().fHide ) ) {
|
|
// remove expired lines
|
|
aLines.pop_front();
|
|
}
|
|
// update next refresh time
|
|
if( false == aLines.empty() ) { fRefreshTime = aLines.front().fHide; }
|
|
else { fRefreshTime = 360.0f; }
|
|
/*
|
|
int i = iStart, j = -1; // od czegoś trzeba zacząć
|
|
bool change = false; // czy zmieniać napisy?
|
|
do
|
|
{
|
|
if (aLines[i].fHide >= 0.0) // o ile aktywne
|
|
if (aLines[i].fHide < Global::fTimeAngleDeg)
|
|
{ // gdy czas wyświetlania upłynął
|
|
aLines[i].fHide = -1.0; // teraz będzie wolną pozycją
|
|
if (i == iStart)
|
|
iStart = aLines[i].iNext >= 0 ? aLines[i].iNext : 0; // przestawienie pierwszego
|
|
else if (j >= 0)
|
|
aLines[j].iNext = aLines[i].iNext; // usunięcie ze środka
|
|
change = true;
|
|
}
|
|
else
|
|
{ // gdy ma być pokazane
|
|
if (aLines[i].fShow > Global::fTimeAngleDeg) // będzie pokazane w przyszłości
|
|
if (fRefreshTime > aLines[i].fShow) // a nie ma nic wcześniej
|
|
fRefreshTime = aLines[i].fShow;
|
|
if (fRefreshTime > aLines[i].fHide)
|
|
fRefreshTime = aLines[i].fHide;
|
|
}
|
|
// można by jeszcze wykrywać, które nowe mają być pokazane
|
|
j = i;
|
|
i = aLines[i].iNext; // kolejna linijka
|
|
} while (i >= 0); // póki po tablicy
|
|
change = true; // bo na razie nie ma warunku, że coś się dodało
|
|
if (change)
|
|
{ // aktualizacja linijek ekranowych
|
|
i = iStart;
|
|
j = -1;
|
|
do
|
|
{
|
|
if (aLines[i].fHide > 0.0) // jeśli nie ukryte
|
|
if (aLines[i].fShow < Global::fTimeAngleDeg) // to dodanie linijki do wyświetlania
|
|
if (j < 5 - 1) // ograniczona liczba linijek
|
|
Global::asTranscript[++j] = aLines[i].asText; // skopiowanie tekstu
|
|
i = aLines[i].iNext; // kolejna linijka
|
|
} while (i >= 0); // póki po tablicy
|
|
for (++j; j < 5; ++j)
|
|
Global::asTranscript[j] = ""; // i czyszczenie nieużywanych linijek
|
|
}
|
|
*/
|
|
};
|
|
|
|
// Ra: tymczasowe rozwiązanie kwestii zagranicznych (czeskich) napisów
|
|
char bezogonkowo[] = "E?,?\"_++?%S<STZZ?`'\"\".--??s>stzz"
|
|
" ^^L$A|S^CS<--RZo±,l'uP.,as>L\"lz"
|
|
"RAAAALCCCEEEEIIDDNNOOOOxRUUUUYTB"
|
|
"raaaalccceeeeiiddnnoooo-ruuuuyt?";
|
|
|
|
std::string Global::Bezogonkow(std::string str, bool _)
|
|
{ // wycięcie liter z ogonkami, bo OpenGL nie umie wyświetlić
|
|
for (unsigned int i = 1; i < str.length(); ++i)
|
|
if (str[i] & 0x80)
|
|
str[i] = bezogonkowo[str[i] & 0x7F];
|
|
else if (str[i] < ' ') // znaki sterujące nie są obsługiwane
|
|
str[i] = ' ';
|
|
else if (_)
|
|
if (str[i] == '_') // nazwy stacji nie mogą zawierać spacji
|
|
str[i] = ' '; // więc trzeba wyświetlać inaczej
|
|
return str;
|
|
};
|
|
|
|
double Global::Min0RSpeed(double vel1, double vel2)
|
|
{ // rozszerzenie funkcji Min0R o wartości -1.0
|
|
if (vel1 == -1.0)
|
|
{
|
|
vel1 = std::numeric_limits<double>::max();
|
|
}
|
|
if (vel2 == -1.0)
|
|
{
|
|
vel2 = std::numeric_limits<double>::max();
|
|
}
|
|
return std::min(vel1, vel2);
|
|
};
|