mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 08:39:18 +02:00
Merge branch 'gfx-work' into sim
This commit is contained in:
@@ -30,6 +30,13 @@ file(GLOB HEADERS "*.h"
|
||||
"network/backend/*.h"
|
||||
"widgets/*.h")
|
||||
|
||||
if (APPLE)
|
||||
set (CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000")
|
||||
endif()
|
||||
|
||||
option(USE_IMGUI_GL3 "Use OpenGL3+ imgui implementation" ON)
|
||||
option(WITH_UART "Compile with libserialport" ON)
|
||||
|
||||
set(SOURCES
|
||||
"Texture.cpp"
|
||||
"Timer.cpp"
|
||||
@@ -86,7 +93,6 @@ set(SOURCES
|
||||
"material.cpp"
|
||||
"lua.cpp"
|
||||
"stdafx.cpp"
|
||||
"uart.cpp"
|
||||
"messaging.cpp"
|
||||
"scene.cpp"
|
||||
"scenenode.cpp"
|
||||
@@ -117,6 +123,7 @@ set(SOURCES
|
||||
"simulationstateserializer.cpp"
|
||||
"precipitation.cpp"
|
||||
"pythonscreenviewer.cpp"
|
||||
"dictionary.cpp"
|
||||
|
||||
"network/network.cpp"
|
||||
"network/message.cpp"
|
||||
@@ -157,8 +164,6 @@ set(SOURCES
|
||||
"extras/VS_Dev.cpp"
|
||||
)
|
||||
|
||||
option(USE_IMGUI_GL3 "Use OpenGL3+ imgui implementation" ON)
|
||||
|
||||
if (USE_IMGUI_GL3)
|
||||
set(SOURCES ${SOURCES} "imgui/imgui_impl_opengl3.cpp")
|
||||
else()
|
||||
@@ -166,15 +171,20 @@ else()
|
||||
set(SOURCES ${SOURCES} "imgui/imgui_impl_opengl2.cpp")
|
||||
endif()
|
||||
|
||||
if (WITH_UART)
|
||||
add_definitions(-DWITH_UART)
|
||||
set(SOURCES ${SOURCES} "uart.cpp")
|
||||
endif()
|
||||
|
||||
set (PREFIX "")
|
||||
|
||||
if (WIN32)
|
||||
add_definitions(-DHAVE_ROUND) # to make pymath to not redefine round
|
||||
add_definitions(-DEU07_BUILD_STATIC) # to make pymath to not redefine round
|
||||
add_definitions(-DGLFW_DLL)
|
||||
|
||||
set(SOURCES ${SOURCES} "windows.cpp" "Console.cpp" "Console/LPT.cpp" "Console/PoKeys55.cpp")
|
||||
set(GLFW3_INCLUDE_DIR ${GLFW3_INCLUDE_DIR} "${DEPS_DIR}/glfw/include/")
|
||||
set(PNG_PNG_INCLUDE_DIR ${PNG_PNG_INCLUDE_DIR} "${DEPS_DIR}/libpng/include/")
|
||||
set(PNG_INCLUDE_DIRS ${PNG_INCLUDE_DIRS} "${DEPS_DIR}/libpng/include/")
|
||||
set(ZLIB_INCLUDE_DIR ${ZLIB_INCLUDE_DIR} "${DEPS_DIR}/zlib/")
|
||||
set(OPENAL_INCLUDE_DIR ${OPENAL_INCLUDE_DIR} "${DEPS_DIR}/openal/include")
|
||||
set(LIBSNDFILE_INCLUDE_DIR ${LIBSNDFILE_INCLUDE_DIR} "${DEPS_DIR}/libsndfile/include")
|
||||
@@ -190,8 +200,8 @@ if (WIN32)
|
||||
|
||||
set (PREFIX "-${ARCH}")
|
||||
|
||||
set(GLFW3_LIBRARIES ${GLFW3_LIBRARIES} "${DEPS_DIR}/glfw/lib/${ARCH}/glfw3.lib")
|
||||
set(PNG_LIBRARY ${PNG_LIBRARY} "${DEPS_DIR}/libpng/lib/${ARCH}/libpng16.lib")
|
||||
set(GLFW3_LIBRARIES ${GLFW3_LIBRARIES} "${DEPS_DIR}/glfw/lib/${ARCH}/glfw3dll.lib")
|
||||
set(PNG_LIBRARIES ${PNG_LIBRARIES} "${DEPS_DIR}/libpng/lib/${ARCH}/libpng16.lib")
|
||||
set(OPENAL_LIBRARY ${OPENAL_LIBRARY} "${DEPS_DIR}/openal/lib/${ARCH}/OpenAL32.lib")
|
||||
set(LIBSNDFILE_LIBRARY ${LIBSNDFILE_LIBRARY} "${DEPS_DIR}/libsndfile/lib/${ARCH}/libsndfile-1.lib")
|
||||
set(LUAJIT_LIBRARIES ${LUAJIT_LIBRARIES} "${DEPS_DIR}/luajit/lib/${ARCH}/lua51.lib")
|
||||
@@ -236,10 +246,12 @@ find_package(PythonLibs 2 REQUIRED)
|
||||
include_directories(${PYTHON_INCLUDE_DIRS})
|
||||
target_link_libraries(${PROJECT_NAME} ${PYTHON_LIBRARIES})
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
include_directories(${PNG_INCLUDE_DIRS} ${PNG_PNG_INCLUDE_DIR})
|
||||
if (NOT WIN32)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(PNG libpng16 REQUIRED)
|
||||
endif()
|
||||
include_directories(${PNG_INCLUDE_DIRS})
|
||||
target_link_libraries(${PROJECT_NAME} ${PNG_LIBRARIES})
|
||||
target_link_libraries(${PROJECT_NAME} ${PNG_LIBRARY})
|
||||
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} Threads::Threads)
|
||||
@@ -259,9 +271,11 @@ find_package(LuaJIT REQUIRED)
|
||||
include_directories(${LUAJIT_INCLUDE_DIR})
|
||||
target_link_libraries(${PROJECT_NAME} ${LUAJIT_LIBRARIES})
|
||||
|
||||
if (WITH_UART)
|
||||
find_package(libserialport REQUIRED)
|
||||
include_directories(${libserialport_INCLUDE_DIR})
|
||||
target_link_libraries(${PROJECT_NAME} ${libserialport_LIBRARY})
|
||||
endif()
|
||||
|
||||
find_package(ASIO REQUIRED)
|
||||
target_link_libraries(${PROJECT_NAME} ASIO::ASIO)
|
||||
|
||||
@@ -40,6 +40,7 @@ class powergridsource_table;
|
||||
class instance_table;
|
||||
class vehicle_table;
|
||||
struct light_array;
|
||||
struct dictionary_source;
|
||||
|
||||
namespace scene {
|
||||
struct node_data;
|
||||
|
||||
47
Driver.cpp
47
Driver.cpp
@@ -1373,7 +1373,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
if( ( mvOccupied->Vel < v )
|
||||
|| ( v == 0.0 ) ) {
|
||||
// if we're going slower than the target velocity and there's enough room for safe stop, speed up
|
||||
auto const brakingdistance = fBrakeDist * braking_distance_multiplier( v );
|
||||
auto const brakingdistance { 1.2 * fBrakeDist * braking_distance_multiplier( v ) };
|
||||
if( brakingdistance > 0.0 ) {
|
||||
// maintain desired acc while we have enough room to brake safely, when close enough start paying attention
|
||||
// try to make a smooth transition instead of sharp change
|
||||
@@ -1638,7 +1638,7 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche,
|
||||
if( WriteLogFlag ) {
|
||||
#ifdef _WIN32
|
||||
CreateDirectory( "physicslog", NULL );
|
||||
#elif __linux__
|
||||
#elif __unix__
|
||||
mkdir( "physicslog", 0644 );
|
||||
#endif
|
||||
LogFile.open( std::string( "physicslog/" + VehicleName + ".dat" ),
|
||||
@@ -2125,6 +2125,11 @@ bool TController::CheckVehicles(TOrders user)
|
||||
&& ( ( p->MoverParameters->Couplers[ end::rear ].CouplingFlag & ( coupling::control ) ) == 0 ) ) {
|
||||
// NOTE: don't set battery in the occupied vehicle, let the user/ai do it explicitly
|
||||
p->MoverParameters->BatterySwitch( true );
|
||||
// enable heating and converter in carriages with can be heated
|
||||
if( p->MoverParameters->HeatingPower > 0 ) {
|
||||
p->MoverParameters->HeatingAllow = true;
|
||||
p->MoverParameters->ConverterSwitch( true, range_t::local );
|
||||
}
|
||||
}
|
||||
|
||||
if (p->asDestination == "none")
|
||||
@@ -2356,6 +2361,7 @@ double TController::BrakeAccFactor() const
|
||||
double Factor = 1.0;
|
||||
|
||||
if( ( fAccThreshold != 0.0 )
|
||||
&& ( AccDesired < 0.0 )
|
||||
&& ( ( ActualProximityDist > fMinProximityDist )
|
||||
|| ( mvOccupied->Vel > VelDesired + fVelPlus ) ) ) {
|
||||
Factor += ( fBrakeReaction * ( /*mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.5 ? 1.5 : 1 ) ) * mvOccupied->Vel / ( std::max( 0.0, ActualProximityDist ) + 1 ) * ( ( AccDesired - AbsAccS_pub ) / fAccThreshold );
|
||||
@@ -2525,9 +2531,9 @@ bool TController::PrepareEngine()
|
||||
}
|
||||
// sync virtual brake state with the 'real' one
|
||||
std::unordered_map<int, int> const brakepositions {
|
||||
{ mvOccupied->Handle->GetPos( bh_RP ), gbh_RP },
|
||||
{ mvOccupied->Handle->GetPos( bh_NP ), gbh_NP },
|
||||
{ mvOccupied->Handle->GetPos( bh_FS ), gbh_FS } };
|
||||
{ static_cast<int>( mvOccupied->Handle->GetPos( bh_RP ) ), gbh_RP },
|
||||
{ static_cast<int>( mvOccupied->Handle->GetPos( bh_NP ) ), gbh_NP },
|
||||
{ static_cast<int>( mvOccupied->Handle->GetPos( bh_FS ) ), gbh_FS } };
|
||||
auto const lookup { brakepositions.find( static_cast<int>( mvOccupied->fBrakeCtrlPos ) ) };
|
||||
if( lookup != brakepositions.end() ) {
|
||||
BrakeLevelSet( lookup->second ); // GBH
|
||||
@@ -3545,7 +3551,7 @@ void TController::Doors( bool const Open, int const Side ) {
|
||||
}
|
||||
|
||||
if( AIControllFlag ) {
|
||||
if( ( true == mvOccupied->Doors.has_autowarning )
|
||||
if( ( true == mvOccupied->Doors.has_warning )
|
||||
&& ( false == mvOccupied->DepartureSignal )
|
||||
&& ( true == TestFlag( iDrivigFlags, moveDoorOpened ) ) ) {
|
||||
mvOccupied->signal_departure( true ); // załącenie bzyczka
|
||||
@@ -4046,7 +4052,7 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
||||
}
|
||||
|
||||
if (NewCommand == "SetSignal") {
|
||||
TSignals signal = (TSignals)std::round(NewValue1);
|
||||
TSignals signal = (TSignals)std::lrint(NewValue1);
|
||||
|
||||
mvOccupied->iLights[0] = 0;
|
||||
mvOccupied->iLights[1] = 0;
|
||||
@@ -4714,11 +4720,11 @@ TController::UpdateSituation(double dt) {
|
||||
// TODO: test if we can use the distances calculation from obey_train
|
||||
fMinProximityDist = std::min( 5 + iVehicles, 25 );
|
||||
fMaxProximityDist = std::min( 10 + iVehicles, 50 );
|
||||
/*
|
||||
if( IsHeavyCargoTrain ) {
|
||||
fMaxProximityDist *= 1.5;
|
||||
// HACK: modern vehicles might brake slower at low speeds, increase safety margin as crude counter
|
||||
if( mvControlling->EIMCtrlType > 0 ) {
|
||||
fMinProximityDist += 5.0;
|
||||
fMaxProximityDist += 5.0;
|
||||
}
|
||||
*/
|
||||
fVelPlus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
|
||||
// margines prędkości powodujący załączenie napędu
|
||||
// były problemy z jazdą np. 3km/h podczas ładowania wagonów
|
||||
@@ -5198,7 +5204,11 @@ TController::UpdateSituation(double dt) {
|
||||
20.0 ) ); // others
|
||||
if( vel > VelDesired + fVelPlus ) {
|
||||
// if going too fast force some prompt braking
|
||||
AccPreferred = std::min( -0.65, AccPreferred );
|
||||
AccPreferred = std::min(
|
||||
( ( mvOccupied->CategoryFlag & 2 ) ?
|
||||
-0.65 : // cars
|
||||
-0.30 ), // others
|
||||
AccPreferred );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5710,11 +5720,11 @@ TController::UpdateSituation(double dt) {
|
||||
|| ( VelNext > vel - 40.0 ) ) ?
|
||||
fBrake_a0[ 0 ] * 0.8 :
|
||||
-fAccThreshold )
|
||||
/ braking_distance_multiplier( VelNext ) ) {
|
||||
/ ( 1.2 * braking_distance_multiplier( VelNext ) ) ) {
|
||||
AccDesired = std::max( -0.06, AccDesired );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( AccDesired < -0.1 ) {
|
||||
// i orientuj się szybciej, jeśli hamujesz
|
||||
ReactionTime = 0.25;
|
||||
}
|
||||
@@ -5813,11 +5823,11 @@ TController::UpdateSituation(double dt) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// yB: usunięte różne dziwne warunki, oddzielamy część zadającą od wykonawczej
|
||||
// zwiekszanie predkosci
|
||||
// yB: usunięte różne dziwne warunki, oddzielamy część zadającą od wykonawczej zwiekszanie predkosci
|
||||
// Ra 2F1H: jest konflikt histerezy pomiędzy nastawioną pozycją a uzyskiwanym
|
||||
// przyspieszeniem - utrzymanie pozycji powoduje przekroczenie przyspieszenia
|
||||
if( ( AccDesired - AbsAccS > 0.01 ) ) {
|
||||
if( ( AccDesired > -0.06 ) // don't add power if not asked for actual speed-up
|
||||
&& ( AccDesired - AbsAccS > 0.05 ) ) {
|
||||
// jeśli przyspieszenie pojazdu jest mniejsze niż żądane oraz...
|
||||
if( vel < (
|
||||
VelDesired == 1.0 ? // work around for trains getting stuck on tracks with speed limit = 1
|
||||
@@ -5909,7 +5919,8 @@ TController::UpdateSituation(double dt) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((AccDesired < fAccGravity - 0.05) && (AbsAccS < AccDesired - fBrake_a1[0]*0.51)) {
|
||||
if ( ( AccDesired < fAccGravity - 0.05 )
|
||||
&& ( ( AccDesired - fBrake_a1[0]*0.51 ) ) - AbsAccS > 0.05 ) {
|
||||
// jak hamuje, to nie tykaj kranu za często
|
||||
// yB: luzuje hamulec dopiero przy różnicy opóźnień rzędu 0.2
|
||||
if( OrderCurrentGet() != Disconnect ) {
|
||||
|
||||
2
Driver.h
2
Driver.h
@@ -416,9 +416,9 @@ private:
|
||||
// methods
|
||||
public:
|
||||
const std::string &TrainName() const;
|
||||
Mtable::TTrainParameters const * TrainTimetable() const;
|
||||
private:
|
||||
std::string Relation() const;
|
||||
Mtable::TTrainParameters const * TrainTimetable() const;
|
||||
int StationIndex() const;
|
||||
int StationCount() const;
|
||||
bool IsStop() const;
|
||||
|
||||
183
DynObj.cpp
183
DynObj.cpp
@@ -162,6 +162,39 @@ void TAnim::Parovoz(){
|
||||
// animowanie tłoka i rozrządu parowozu
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
void TDynamicObject::destination_data::deserialize( cParser &Input ) {
|
||||
|
||||
while( true == deserialize_mapping( Input ) ) {
|
||||
; // all work done by while()
|
||||
}
|
||||
}
|
||||
|
||||
bool TDynamicObject::destination_data::deserialize_mapping( cParser &Input ) {
|
||||
// token can be a key or block end
|
||||
auto const key { Input.getToken<std::string>( true, "\n\r\t ,;[]" ) };
|
||||
|
||||
if( ( true == key.empty() ) || ( key == "}" ) ) { return false; }
|
||||
|
||||
if( key == "{" ) {
|
||||
script = Input.getToken<std::string>();
|
||||
}
|
||||
else if( key == "update:" ) {
|
||||
auto const value { Input.getToken<std::string>() };
|
||||
// TODO: implement
|
||||
}
|
||||
else if( key == "instance:" ) {
|
||||
instancing = Input.getToken<std::string>();
|
||||
}
|
||||
else if( key == "parameters:" ) {
|
||||
parameters = Input.getToken<std::string>();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
TDynamicObject * TDynamicObject::FirstFind(int &coupler_nr, int cf)
|
||||
{ // szukanie skrajnego połączonego pojazdu w pociagu
|
||||
@@ -918,6 +951,8 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
btEndSignalsTab2.Turn( true );
|
||||
btnOn = true;
|
||||
}
|
||||
// destination signs
|
||||
update_destinations();
|
||||
// else btEndSignalsTab2.TurnOff();
|
||||
// McZapkie-181002: krecenie wahaczem (korzysta z kata obrotu silnika)
|
||||
if (iAnimType[ANIM_LEVERS])
|
||||
@@ -1535,20 +1570,12 @@ void TDynamicObject::place_on_track(TTrack *Track, double fDist, bool Reversed)
|
||||
// Ra: pojazdy wstawiane są na tor początkowy, a potem przesuwane
|
||||
case 2: // ustawianie osi na torze
|
||||
Axle0.Init(Track, this, iDirection ? 1 : -1);
|
||||
Axle0.Reset();
|
||||
Axle0.Move((iDirection ? fDist : -fDist) + fAxleDistHalf, false);
|
||||
Axle1.Init(Track, this, iDirection ? 1 : -1);
|
||||
Axle1.Reset();
|
||||
Axle1.Move((iDirection ? fDist : -fDist) - fAxleDistHalf, false); // false, żeby nie generować eventów
|
||||
break;
|
||||
case 4:
|
||||
Axle0.Init(Track, this, iDirection ? 1 : -1);
|
||||
Axle0.Move((iDirection ? fDist : -fDist) + (fAxleDistHalf + MoverParameters->ADist * 0.5), false);
|
||||
Axle1.Init(Track, this, iDirection ? 1 : -1);
|
||||
Axle1.Move((iDirection ? fDist : -fDist) - (fAxleDistHalf + MoverParameters->ADist * 0.5), false);
|
||||
// Axle2.Init(Track,this,iDirection?1:-1);
|
||||
// Axle2.Move((iDirection?fDist:-fDist)-(fAxleDistHalf-MoverParameters->ADist*0.5),false);
|
||||
// Axle3.Init(Track,this,iDirection?1:-1);
|
||||
// Axle3.Move((iDirection?fDist:-fDist)+(fAxleDistHalf-MoverParameters->ADist*0.5),false);
|
||||
break;
|
||||
}
|
||||
// potrzebne do wyliczenia aktualnej pozycji; nie może być zero, bo nie przeliczy pozycji
|
||||
// teraz jeszcze trzeba przypisać pojazdy do nowego toru, bo przesuwanie początkowe osi nie
|
||||
@@ -1982,6 +2009,10 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
init_sections( mdLowPolyInt, nameprefix );
|
||||
}
|
||||
}
|
||||
// destination sign
|
||||
if( mdModel ) {
|
||||
init_destination( mdModel );
|
||||
}
|
||||
// 'external_load' is an optional special section in the main model, pointing to submodel of external load
|
||||
if( mdModel ) {
|
||||
init_sections( mdModel, "external_load" );
|
||||
@@ -2106,6 +2137,16 @@ TDynamicObject::init_sections( TModel3d const *Model, std::string const &Namepre
|
||||
return sectioncount;
|
||||
}
|
||||
|
||||
bool
|
||||
TDynamicObject::init_destination( TModel3d *Model ) {
|
||||
|
||||
if( Model->GetSMRoot() == nullptr ) { return false; }
|
||||
|
||||
std::tie( DestinationSign.sign, DestinationSign.has_light ) = Model->GetSMRoot()->find_replacable4();
|
||||
|
||||
return DestinationSign.sign != nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
TDynamicObject::create_controller( std::string const Type, bool const Trainset ) {
|
||||
|
||||
@@ -2579,6 +2620,27 @@ na sprzęgach, opóźnienie działania hamulca itp. Oczywiście musi mieć to pe
|
||||
histerezę czasową, aby te tryby pracy nie przełączały się zbyt szybko.
|
||||
*/
|
||||
|
||||
void TDynamicObject::update_destinations() {
|
||||
|
||||
if( DestinationSign.sign == nullptr ) { return; }
|
||||
|
||||
DestinationSign.sign->fLight = (
|
||||
( ( DestinationSign.has_light ) && ( MoverParameters->Battery ) ) ?
|
||||
2.0 :
|
||||
-1.0 );
|
||||
|
||||
// jak są 4 tekstury wymienne, to nie zmieniać rozkładem
|
||||
if( std::abs( m_materialdata.multi_textures ) >= 4 ) { return; }
|
||||
// TODO: dedicated setting to discern electronic signs, instead of fallback on light presence
|
||||
m_materialdata.replacable_skins[ 4 ] = (
|
||||
( ( DestinationSign.destination != null_handle )
|
||||
&& ( ( false == DestinationSign.has_light ) // physical destination signs remain up until manually changed
|
||||
|| ( ( true == MoverParameters->Battery ) // lcd signs are off without power
|
||||
&& ( ctOwner != nullptr ) ) ) ) ? // lcd signs are off for carriages without engine, potentially left on a siding
|
||||
DestinationSign.destination :
|
||||
DestinationSign.destination_off );
|
||||
}
|
||||
|
||||
bool TDynamicObject::Update(double dt, double dt1)
|
||||
{
|
||||
if (dt1 == 0.0)
|
||||
@@ -4073,6 +4135,10 @@ void TDynamicObject::RenderSounds() {
|
||||
}
|
||||
if( volume > 0.05 ) {
|
||||
rscurve
|
||||
.pitch(
|
||||
true == rscurve.is_combined() ?
|
||||
MoverParameters->Vel * 0.01f :
|
||||
rscurve.m_frequencyoffset + rscurve.m_frequencyfactor * 1.f )
|
||||
.gain( 2.5 * volume )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
@@ -4298,7 +4364,8 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
}
|
||||
|
||||
// potentially set blank destination texture
|
||||
DestinationSet( {}, {} );
|
||||
DestinationSign.destination_off = DestinationFind( "nowhere" );
|
||||
// DestinationSet( {}, {} );
|
||||
|
||||
if( GfxRenderer.Material( m_materialdata.replacable_skins[ 1 ] ).get_or_guess_opacity() == 0.0f ) {
|
||||
// tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
@@ -5595,6 +5662,15 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
parser >> JointCabs;
|
||||
}
|
||||
|
||||
else if( token == "pydestinationsign:" ) {
|
||||
DestinationSign.deserialize( parser );
|
||||
// supply vehicle folder as script path if none is provided
|
||||
if( ( false == DestinationSign.script.empty() )
|
||||
&& ( substr_path( DestinationSign.script ).empty() ) ) {
|
||||
DestinationSign.script = asBaseDir + DestinationSign.script;
|
||||
}
|
||||
}
|
||||
|
||||
} while( token != "" );
|
||||
|
||||
} // internaldata:
|
||||
@@ -6142,45 +6218,92 @@ int TDynamicObject::RouteWish(TTrack *tr)
|
||||
return Mechanik ? Mechanik->CrossRoute(tr) : 0; // wg AI albo prosto
|
||||
};
|
||||
|
||||
void TDynamicObject::DestinationSet(std::string to, std::string numer)
|
||||
{ // ustawienie stacji docelowej oraz wymiennej tekstury 4, jeśli istnieje plik
|
||||
void TDynamicObject::DestinationSet(std::string to, std::string numer) {
|
||||
// ustawienie stacji docelowej oraz wymiennej tekstury 4, jeśli istnieje plik
|
||||
// w zasadzie, to każdy wagon mógłby mieć inną stację docelową
|
||||
// zwłaszcza w towarowych, pod kątem zautomatyzowania maewrów albo pracy górki
|
||||
// ale to jeszcze potrwa, zanim będzie możliwe, na razie można wpisać stację z
|
||||
// rozkładu
|
||||
if( std::abs( m_materialdata.multi_textures ) >= 4 ) {
|
||||
// jak są 4 tekstury wymienne, to nie zmieniać rozkładem
|
||||
|
||||
asDestination = to;
|
||||
|
||||
if( std::abs( m_materialdata.multi_textures ) >= 4 ) { return; } // jak są 4 tekstury wymienne, to nie zmieniać rozkładem
|
||||
if( DestinationSign.sign == nullptr ) { return; } // no sign submodel, no problem
|
||||
|
||||
// now see if we can find any version of the destination texture
|
||||
std::vector<std::string> const destinations = {
|
||||
numer, // try dedicated timetable sign first...
|
||||
to }; // ...then generic destination sign
|
||||
|
||||
for( auto const &destination : destinations ) {
|
||||
|
||||
DestinationSign.destination = DestinationFind( destination );
|
||||
if( DestinationSign.destination != null_handle ) {
|
||||
// got what we wanted, we're done here
|
||||
return;
|
||||
}
|
||||
numer = Bezogonkow(numer);
|
||||
asDestination = to;
|
||||
to = Bezogonkow(to); // do szukania pliku obcinamy ogonki
|
||||
if( true == to.empty() ) {
|
||||
to = "nowhere";
|
||||
}
|
||||
// if we didn't get static texture we might be able to make one
|
||||
if( DestinationSign.script.empty() ) { return; } // no script so no way to make the texture
|
||||
if( numer == "none" ) { return; } // blank or incomplete/malformed timetable, don't bother
|
||||
|
||||
std::string signrequest {
|
||||
"make:"
|
||||
+ DestinationSign.script + "?"
|
||||
// timetable include
|
||||
+ "$timetable=" + (
|
||||
ctOwner == nullptr ?
|
||||
MoverParameters->Name : // leading vehicle, can point to it directly
|
||||
ctOwner->Vehicle()->MoverParameters->Name ) + "&" // owned vehicle, safer to point to owner as carriages can have identical names
|
||||
// basic instancing string
|
||||
// NOTE: underscore doesn't have any magic meaning for the time being, it's just less likely to conflict with regular dictionary keys
|
||||
+ "_id1=" + (
|
||||
ctOwner != nullptr ? ctOwner->TrainName() :
|
||||
Mechanik != nullptr ? Mechanik->TrainName() :
|
||||
"none" ) }; // shouldn't get here but, eh
|
||||
// TBD, TODO: replace instancing with support for variables in extra parameters string?
|
||||
if( false == DestinationSign.instancing.empty() ) {
|
||||
signrequest +=
|
||||
"&_id2=" + (
|
||||
DestinationSign.instancing == "name" ? MoverParameters->Name :
|
||||
DestinationSign.instancing == "type" ? MoverParameters->TypeName :
|
||||
"none" );
|
||||
}
|
||||
// optionl extra parameters
|
||||
if( false == DestinationSign.parameters.empty() ) {
|
||||
signrequest += "&" + DestinationSign.parameters;
|
||||
}
|
||||
|
||||
DestinationSign.destination = GfxRenderer.Fetch_Material( signrequest );
|
||||
}
|
||||
|
||||
material_handle TDynamicObject::DestinationFind( std::string Destination ) {
|
||||
|
||||
if( Destination.empty() ) { return null_handle; }
|
||||
|
||||
Destination = Bezogonkow( Destination ); // do szukania pliku obcinamy ogonki
|
||||
// destination textures are kept in the vehicle's directory so we point the current texture path there
|
||||
auto const currenttexturepath { Global.asCurrentTexturePath };
|
||||
Global.asCurrentTexturePath = asBaseDir;
|
||||
// now see if we can find any version of the texture
|
||||
std::vector<std::string> destinations = {
|
||||
numer + '@' + MoverParameters->TypeName,
|
||||
numer,
|
||||
to + '@' + MoverParameters->TypeName,
|
||||
to,
|
||||
"nowhere" + '@' + MoverParameters->TypeName,
|
||||
"nowhere" };
|
||||
std::vector<std::string> const destinations {
|
||||
Destination + '@' + MoverParameters->TypeName,
|
||||
Destination };
|
||||
|
||||
auto destinationhandle { null_handle };
|
||||
|
||||
for( auto const &destination : destinations ) {
|
||||
|
||||
auto material = TextureTest( ToLower( destination ) );
|
||||
if( false == material.empty() ) {
|
||||
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.Fetch_Material( material );
|
||||
destinationhandle = GfxRenderer.Fetch_Material( material );
|
||||
break;
|
||||
}
|
||||
}
|
||||
// whether we got anything, restore previous texture path
|
||||
Global.asCurrentTexturePath = currenttexturepath;
|
||||
};
|
||||
|
||||
return destinationhandle;
|
||||
}
|
||||
|
||||
void TDynamicObject::OverheadTrack(float o)
|
||||
{ // ewentualne wymuszanie jazdy
|
||||
|
||||
17
DynObj.h
17
DynObj.h
@@ -204,6 +204,20 @@ public:
|
||||
TModel3d *mdLowPolyInt; // ABu 010305: wnetrze lowpoly
|
||||
std::array<TSubModel *, 3> LowPolyIntCabs {}; // pointers to low fidelity version of individual driver cabs
|
||||
bool JointCabs{ false }; // flag for vehicles with multiple virtual 'cabs' sharing location and 3d model(s)
|
||||
struct destination_data {
|
||||
TSubModel *sign { nullptr }; // submodel mapped with replacable texture -4
|
||||
bool has_light { false }; // the submodel was originally configured with self-illumination attribute
|
||||
material_handle destination { null_handle }; // most recently assigned non-blank destination texture
|
||||
material_handle destination_off { null_handle }; // blank destination sign
|
||||
std::string script; // potential python script used to generate texture data
|
||||
int update_rate { 0 }; // -1: per stop, 0: none, >0: fps // TBD, TODO: implement?
|
||||
std::string instancing; // potential method to generate more than one texture per timetable
|
||||
std::string parameters; // potential extra parameters supplied by mmd file
|
||||
// methods
|
||||
void deserialize( cParser &Input );
|
||||
private:
|
||||
bool deserialize_mapping( cParser &Input );
|
||||
} DestinationSign;
|
||||
float fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?)
|
||||
float LoadOffset { 0.f };
|
||||
std::unordered_map<std::string, std::string> LoadModelOverrides; // potential overrides of default load visualization models
|
||||
@@ -520,6 +534,7 @@ private:
|
||||
TTrack *Track, double fDist, std::string DriverType, double fVel, std::string TrainName,
|
||||
float Load, std::string LoadType, bool Reversed, std::string);
|
||||
int init_sections( TModel3d const *Model, std::string const &Nameprefix );
|
||||
bool init_destination( TModel3d *Model );
|
||||
void create_controller( std::string const Type, bool const Trainset );
|
||||
void AttachPrev(TDynamicObject *Object, int iType = 1);
|
||||
bool UpdateForce(double dt);
|
||||
@@ -534,6 +549,7 @@ private:
|
||||
void update_load_visibility();
|
||||
void update_load_offset();
|
||||
void shuffle_load_sections();
|
||||
void update_destinations();
|
||||
bool Update(double dt, double dt1);
|
||||
bool FastUpdate(double dt);
|
||||
void Move(double fDistance);
|
||||
@@ -636,6 +652,7 @@ private:
|
||||
// zapytanie do AI, po którym segmencie skrzyżowania jechać
|
||||
int RouteWish(TTrack *tr);
|
||||
void DestinationSet(std::string to, std::string numer);
|
||||
material_handle DestinationFind( std::string Destination );
|
||||
void OverheadTrack(float o);
|
||||
glm::dvec3 get_future_movement() const;
|
||||
void move_set(double distance);
|
||||
|
||||
4
EU07.cpp
4
EU07.cpp
@@ -34,8 +34,10 @@ int main( int argc, char *argv[] )
|
||||
auto result { Application.init( argc, argv ) };
|
||||
if( result == 0 ) {
|
||||
result = Application.run();
|
||||
}
|
||||
Application.exit();
|
||||
}
|
||||
std::_Exit(0); // skip destructors, there are ordering errors which causes segfaults
|
||||
return result;
|
||||
}
|
||||
catch( std::bad_alloc const &Error )
|
||||
{
|
||||
|
||||
@@ -650,6 +650,7 @@ global_settings::ConfigParse(cParser &Parser) {
|
||||
Parser.getTokens(1);
|
||||
Parser >> Global.screenshot_dir;
|
||||
}
|
||||
#ifdef WITH_UART
|
||||
else if( token == "uart" ) {
|
||||
uart_conf.enable = true;
|
||||
Parser.getTokens( 3, false );
|
||||
@@ -688,6 +689,7 @@ global_settings::ConfigParse(cParser &Parser) {
|
||||
Parser.getTokens( 1 );
|
||||
Parser >> uart_conf.debug;
|
||||
}
|
||||
#endif
|
||||
else if (token == "loadinglog") {
|
||||
Parser.getTokens( 1 );
|
||||
Parser >> loading_log;
|
||||
|
||||
@@ -14,10 +14,12 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "dumb3d.h"
|
||||
#include "Float3d.h"
|
||||
#include "light.h"
|
||||
#include "uart.h"
|
||||
#include "utilities.h"
|
||||
#include "motiontelemetry.h"
|
||||
#include "version.h"
|
||||
#ifdef WITH_UART
|
||||
#include "uart.h"
|
||||
#endif
|
||||
|
||||
struct global_settings {
|
||||
// members
|
||||
@@ -169,7 +171,9 @@ struct global_settings {
|
||||
0, 0, 0, 0, 0, 0, 0 };
|
||||
int iCalibrateOutDebugInfo { -1 }; // numer wyjścia kalibrowanego dla którego wyświetlać informacje podczas kalibracji
|
||||
int iPoKeysPWM[ 7 ] = { 0, 1, 2, 3, 4, 5, 6 }; // numery wejść dla PWM
|
||||
#ifdef WITH_UART
|
||||
uart_input::conf_t uart_conf;
|
||||
#endif
|
||||
// multiplayer
|
||||
int iMultiplayer{ 0 }; // blokada działania niektórych eventów na rzecz kominikacji
|
||||
// other
|
||||
|
||||
2
Logs.cpp
2
Logs.cpp
@@ -27,7 +27,7 @@ std::deque<std::string> log_scrollback;
|
||||
std::string filename_date() {
|
||||
::SYSTEMTIME st;
|
||||
|
||||
#ifdef __linux__
|
||||
#ifdef __unix__
|
||||
timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
tm *tms = localtime(&ts.tv_sec);
|
||||
|
||||
@@ -1369,6 +1369,7 @@ public:
|
||||
std::string StLinSwitchType;
|
||||
|
||||
bool Heating = false; //ogrzewanie 'Winger 020304
|
||||
bool HeatingAllow { false }; // heating switch // TODO: wrap heating in a basic device
|
||||
int DoubleTr = 1; //trakcja ukrotniona - przedni pojazd 'Winger 160304
|
||||
|
||||
bool PhysicActivation = true;
|
||||
@@ -1514,6 +1515,7 @@ public:
|
||||
|
||||
/*-funkcje typowe dla lokomotywy elektrycznej*/
|
||||
void ConverterCheck( double const Timestep ); // przetwornica
|
||||
void HeatingCheck( double const Timestep );
|
||||
void WaterPumpCheck( double const Timestep );
|
||||
void WaterHeaterCheck( double const Timestep );
|
||||
void FuelPumpCheck( double const Timestep );
|
||||
|
||||
@@ -1186,11 +1186,13 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
|
||||
for( int side = 0; side < 2; ++side ) {
|
||||
// przekazywanie napiec
|
||||
auto const oppositeside = ( side == end::front ? end::rear : end::front );
|
||||
auto const oppositeside { ( side == end::front ? end::rear : end::front ) };
|
||||
auto const liveconnection{
|
||||
( Couplers[ side ].CouplingFlag & ctrain_power )
|
||||
|| ( ( Couplers[ side ].CouplingFlag & ctrain_heating )
|
||||
&& ( Couplers[ side ].Connected->Heating ) ) };
|
||||
|
||||
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
||||
|| ( ( Heating )
|
||||
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
||||
if( liveconnection ) {
|
||||
auto const &connectedcoupler = Couplers[ side ].Connected->Couplers[ Couplers[ side ].ConnectedNr ];
|
||||
Couplers[ oppositeside ].power_high.voltage =
|
||||
std::max(
|
||||
@@ -1214,8 +1216,8 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
Couplers[ side ].power_high.local = false; // power, if any, will be from external source
|
||||
|
||||
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
||||
|| ( ( Heating )
|
||||
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
||||
|| ( ( Couplers[ side ].CouplingFlag & ctrain_heating )
|
||||
&& ( Couplers[ side ].Connected->Heating ) ) ) {
|
||||
auto const &connectedcoupler =
|
||||
Couplers[ side ].Connected->Couplers[
|
||||
( Couplers[ side ].ConnectedNr == end::front ?
|
||||
@@ -1238,8 +1240,8 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
Couplers[ side ].power_high.local = true; // power is coming from local pantographs
|
||||
|
||||
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
||||
|| ( ( Heating )
|
||||
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
||||
|| ( ( Couplers[ side ].CouplingFlag & ctrain_heating )
|
||||
&& ( Couplers[ side ].Connected->Heating ) ) ) {
|
||||
auto const &connectedcoupler =
|
||||
Couplers[ side ].Connected->Couplers[
|
||||
( Couplers[ side ].ConnectedNr == end::front ?
|
||||
@@ -1520,6 +1522,8 @@ void TMoverParameters::compute_movement_( double const Deltatime ) {
|
||||
// w rozrządczym nie (jest błąd w FIZ!) - Ra 2014-07: teraz we wszystkich
|
||||
UpdatePantVolume( Deltatime ); // Ra 2014-07: obsługa zbiornika rozrządu oraz pantografów
|
||||
}
|
||||
// heating
|
||||
HeatingCheck( Deltatime );
|
||||
|
||||
UpdateBrakePressure(Deltatime);
|
||||
UpdatePipePressure(Deltatime);
|
||||
@@ -1573,7 +1577,8 @@ void TMoverParameters::ConverterCheck( double const Timestep ) {
|
||||
if( ( ConverterAllow )
|
||||
&& ( ConverterAllowLocal )
|
||||
&& ( false == PantPressLockActive )
|
||||
&& ( Mains ) ) {
|
||||
&& ( ( Mains )
|
||||
|| ( GetTrainsetVoltage() > 0 ) ) ) {
|
||||
// delay timer can be optionally configured, and is set anew whenever converter goes off
|
||||
if( ConverterStartDelayTimer <= 0.0 ) {
|
||||
ConverterFlag = true;
|
||||
@@ -1588,6 +1593,17 @@ void TMoverParameters::ConverterCheck( double const Timestep ) {
|
||||
}
|
||||
};
|
||||
|
||||
// heating system status check
|
||||
void TMoverParameters::HeatingCheck( double const Timestep ) {
|
||||
|
||||
Heating = (
|
||||
( true == HeatingAllow )
|
||||
// powered vehicles are generally required to activate their power source to provide heating
|
||||
// passive vehicles get a pass in this regard
|
||||
&& ( ( Power < 0.1 )
|
||||
|| ( true == Mains ) ) );
|
||||
}
|
||||
|
||||
// water pump status check
|
||||
void TMoverParameters::WaterPumpCheck( double const Timestep ) {
|
||||
// NOTE: breaker override with start type is sm42 specific hack, replace with ability to define the presence of the breaker
|
||||
@@ -7271,14 +7287,14 @@ double TMoverParameters::GetTrainsetVoltage(void)
|
||||
return std::max(
|
||||
( ( ( Couplers[end::front].Connected )
|
||||
&& ( ( Couplers[ end::front ].CouplingFlag & ctrain_power )
|
||||
|| ( ( Heating )
|
||||
&& ( Couplers[ end::front ].CouplingFlag & ctrain_heating ) ) ) ) ?
|
||||
|| ( ( Couplers[ end::front ].CouplingFlag & ctrain_heating )
|
||||
&& ( Couplers[ end::front ].Connected->Heating ) ) ) ) ?
|
||||
Couplers[end::front].Connected->Couplers[ Couplers[end::front].ConnectedNr ].power_high.voltage :
|
||||
0.0 ),
|
||||
( ( ( Couplers[end::rear].Connected )
|
||||
&& ( ( Couplers[ end::rear ].CouplingFlag & ctrain_power )
|
||||
|| ( ( Heating )
|
||||
&& ( Couplers[ end::rear ].CouplingFlag & ctrain_heating ) ) ) ) ?
|
||||
|| ( ( Couplers[ end::rear ].CouplingFlag & ctrain_heating )
|
||||
&& ( Couplers[ end::rear ].Connected->Heating ) ) ) ) ?
|
||||
Couplers[ end::rear ].Connected->Couplers[ Couplers[ end::rear ].ConnectedNr ].power_high.voltage :
|
||||
0.0 ) );
|
||||
}
|
||||
|
||||
21
Model3d.cpp
21
Model3d.cpp
@@ -826,6 +826,27 @@ int TSubModel::count_children() {
|
||||
1 + Child->count_siblings() );
|
||||
}
|
||||
|
||||
// locates submodel mapped with replacable -4
|
||||
std::tuple<TSubModel *, bool>
|
||||
TSubModel::find_replacable4() {
|
||||
|
||||
if( m_material == -4 ) {
|
||||
return std::make_tuple( this, ( fLight != -1.0 ) );
|
||||
}
|
||||
|
||||
if( Next != nullptr ) {
|
||||
auto lookup { Next->find_replacable4() };
|
||||
if( std::get<TSubModel *>( lookup ) != nullptr ) { return lookup; }
|
||||
}
|
||||
|
||||
if( Child != nullptr ) {
|
||||
auto lookup { Child->find_replacable4() };
|
||||
if( std::get<TSubModel *>( lookup ) != nullptr ) { return lookup; }
|
||||
}
|
||||
|
||||
return std::make_tuple( nullptr, false );
|
||||
}
|
||||
|
||||
uint32_t TSubModel::FlagsCheck()
|
||||
{ // analiza koniecznych zmian pomiędzy submodelami
|
||||
// samo pomijanie glBindTexture() nie poprawi wydajności
|
||||
|
||||
@@ -165,6 +165,8 @@ public:
|
||||
TSubModel * ChildGet() { return Child; };
|
||||
int count_siblings();
|
||||
int count_children();
|
||||
// locates submodel mapped with replacable -4
|
||||
std::tuple<TSubModel *, bool> find_replacable4();
|
||||
int TriangleAdd(TModel3d *m, material_handle tex, int tri);
|
||||
void SetRotate(float3 vNewRotateAxis, float fNewAngle);
|
||||
void SetRotateXYZ( Math3D::vector3 vNewAngles);
|
||||
|
||||
10
PyInt.cpp
10
PyInt.cpp
@@ -10,10 +10,10 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "stdafx.h"
|
||||
#include "PyInt.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "dictionary.h"
|
||||
#include "application.h"
|
||||
#include "renderer.h"
|
||||
#include "Logs.h"
|
||||
#include "Globals.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
@@ -141,6 +141,11 @@ auto python_taskqueue::init() -> bool {
|
||||
Py_SetPythonHome("linuxpython64");
|
||||
else
|
||||
Py_SetPythonHome("linuxpython");
|
||||
#elif __APPLE__
|
||||
if (sizeof(void*) == 8)
|
||||
Py_SetPythonHome("macpython64");
|
||||
else
|
||||
Py_SetPythonHome("macpython");
|
||||
#endif
|
||||
Py_Initialize();
|
||||
PyEval_InitThreads();
|
||||
@@ -209,6 +214,7 @@ void python_taskqueue::exit() {
|
||||
m_condition.notify_all();
|
||||
// let them free up their shit before we proceed
|
||||
for( auto &worker : m_workers ) {
|
||||
if (worker.joinable())
|
||||
worker.join();
|
||||
}
|
||||
// get rid of the leftover tasks
|
||||
|
||||
18
PyInt.h
18
PyInt.h
@@ -50,24 +50,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
#define PyGetBool(param) param ? Py_True : Py_False
|
||||
#define PyGetString(param) PyString_FromString(param)
|
||||
|
||||
// collection of keyword-value pairs
|
||||
// NOTE: since our python dictionary operates on a few types, most of the class was hardcoded for simplicity
|
||||
struct dictionary_source {
|
||||
// types
|
||||
template <typename Type_>
|
||||
using keyvaluepair_sequence = std::vector<std::pair<std::string, Type_>>;
|
||||
// members
|
||||
keyvaluepair_sequence<double> floats;
|
||||
keyvaluepair_sequence<int> integers;
|
||||
keyvaluepair_sequence<bool> bools;
|
||||
keyvaluepair_sequence<std::string> strings;
|
||||
// methods
|
||||
inline void insert( std::string const &Key, double const Value ) { floats.emplace_back( Key, Value ); }
|
||||
inline void insert( std::string const &Key, int const Value ) { integers.emplace_back( Key, Value ); }
|
||||
inline void insert( std::string const &Key, bool const Value ) { bools.emplace_back( Key, Value ); }
|
||||
inline void insert( std::string const &Key, std::string const Value ) { strings.emplace_back( Key, Value ); }
|
||||
};
|
||||
|
||||
// python rendertarget
|
||||
struct python_rt {
|
||||
std::mutex mutex;
|
||||
|
||||
16
Texture.cpp
16
Texture.cpp
@@ -17,14 +17,16 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Texture.h"
|
||||
|
||||
#include "application.h"
|
||||
#include "utilities.h"
|
||||
#include "dictionary.h"
|
||||
#include "Globals.h"
|
||||
#include "Logs.h"
|
||||
#include "utilities.h"
|
||||
#include "sn_utils.h"
|
||||
#include "utilities.h"
|
||||
#include "flip-s3tc.h"
|
||||
#include <png.h>
|
||||
|
||||
|
||||
#define EU07_DEFERRED_TEXTURE_UPLOAD
|
||||
|
||||
texture_manager::texture_manager() {
|
||||
@@ -266,17 +268,9 @@ void
|
||||
opengl_texture::make_request() {
|
||||
|
||||
auto const components { Split( name, '?' ) };
|
||||
auto const query { Split( components.back(), '&' ) };
|
||||
|
||||
auto *dictionary { new dictionary_source };
|
||||
if( dictionary != nullptr ) {
|
||||
for( auto const &querypair : query ) {
|
||||
auto const valuepos { querypair.find( '=' ) };
|
||||
dictionary->insert(
|
||||
ToLower( querypair.substr( 0, valuepos ) ),
|
||||
querypair.substr( valuepos + 1 ) );
|
||||
}
|
||||
}
|
||||
auto *dictionary { new dictionary_source( components.back() ) };
|
||||
if( dictionary == nullptr ) { return; }
|
||||
|
||||
auto rt = std::make_shared<python_rt>();
|
||||
rt->shared_tex = id;
|
||||
|
||||
@@ -61,7 +61,7 @@ void UpdateTimers(bool pause)
|
||||
#ifdef _WIN32
|
||||
QueryPerformanceFrequency((LARGE_INTEGER *)&fr);
|
||||
QueryPerformanceCounter((LARGE_INTEGER *)&count);
|
||||
#elif __linux__
|
||||
#elif __unix__
|
||||
timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
count = (uint64_t)ts.tv_sec * 1000000000 + (uint64_t)ts.tv_nsec;
|
||||
@@ -85,7 +85,7 @@ void UpdateTimers(bool pause)
|
||||
|
||||
oldCount = count;
|
||||
// Keep track of the time lapse and frame count
|
||||
#if __linux__
|
||||
#if __unix__
|
||||
double fTime = (double)(count / 1000000000);
|
||||
#elif _WIN32_WINNT >= _WIN32_WINNT_VISTA
|
||||
double fTime = ::GetTickCount64() * 0.001f; // Get current time in seconds
|
||||
|
||||
43
Train.cpp
43
Train.cpp
@@ -30,6 +30,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Console.h"
|
||||
#include "application.h"
|
||||
#include "renderer.h"
|
||||
#include "dictionary.h"
|
||||
/*
|
||||
namespace input {
|
||||
|
||||
@@ -552,31 +553,8 @@ dictionary_source *TTrain::GetTrainState() {
|
||||
dict->insert( "velnext", driver->VelNext );
|
||||
dict->insert( "actualproximitydist", driver->ActualProximityDist );
|
||||
// train data
|
||||
auto const *timetable{ driver->TrainTimetable() };
|
||||
|
||||
dict->insert( "trainnumber", driver->TrainName() );
|
||||
dict->insert( "train_brakingmassratio", timetable->BrakeRatio );
|
||||
dict->insert( "train_enginetype", timetable->LocSeries );
|
||||
dict->insert( "train_engineload", timetable->LocLoad );
|
||||
|
||||
dict->insert( "train_stationindex", driver->iStationStart );
|
||||
auto const stationcount { driver->StationCount() };
|
||||
dict->insert( "train_stationcount", stationcount );
|
||||
if( stationcount > 0 ) {
|
||||
// timetable stations data, if there's any
|
||||
for( auto stationidx = 1; stationidx <= stationcount; ++stationidx ) {
|
||||
auto const stationlabel { "train_station" + std::to_string( stationidx ) + "_" };
|
||||
auto const &timetableline { timetable->TimeTable[ stationidx ] };
|
||||
dict->insert( ( stationlabel + "name" ), Bezogonkow( timetableline.StationName ) );
|
||||
dict->insert( ( stationlabel + "fclt" ), Bezogonkow( timetableline.StationWare ) );
|
||||
dict->insert( ( stationlabel + "lctn" ), timetableline.km );
|
||||
dict->insert( ( stationlabel + "vmax" ), timetableline.vmax );
|
||||
dict->insert( ( stationlabel + "ah" ), timetableline.Ah );
|
||||
dict->insert( ( stationlabel + "am" ), timetableline.Am );
|
||||
dict->insert( ( stationlabel + "dh" ), timetableline.Dh );
|
||||
dict->insert( ( stationlabel + "dm" ), timetableline.Dm );
|
||||
}
|
||||
}
|
||||
driver->TrainTimetable()->serialize( dict );
|
||||
dict->insert( "train_stationstart", driver->iStationStart );
|
||||
dict->insert( "train_atpassengerstop", driver->IsAtPassengerStop );
|
||||
// world state data
|
||||
dict->insert( "scenario", Global.SceneryFile );
|
||||
@@ -4148,7 +4126,7 @@ void TTrain::OnCommand_heatingtoggle( TTrain *Train, command_data const &Command
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( false == Train->mvControlled->Heating ) {
|
||||
if( false == Train->mvControlled->HeatingAllow ) {
|
||||
// turn on
|
||||
OnCommand_heatingenable( Train, Command );
|
||||
}
|
||||
@@ -4162,24 +4140,20 @@ void TTrain::OnCommand_heatingtoggle( TTrain *Train, command_data const &Command
|
||||
void TTrain::OnCommand_heatingenable( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
|
||||
Train->mvControlled->HeatingAllow = true;
|
||||
// visual feedback
|
||||
Train->ggTrainHeatingButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
|
||||
if( true == Train->mvControlled->Heating ) { return; } // already enabled
|
||||
|
||||
Train->mvControlled->Heating = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_heatingdisable( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
|
||||
Train->mvControlled->HeatingAllow = false;
|
||||
// visual feedback
|
||||
Train->ggTrainHeatingButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
|
||||
if( false == Train->mvControlled->Heating ) { return; } // already disabled
|
||||
|
||||
Train->mvControlled->Heating = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6028,7 +6002,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
//---------
|
||||
// hunter-080812: poprawka na ogrzewanie w elektrykach - usuniete uzaleznienie od przetwornicy
|
||||
if( ( mvControlled->Heating == true )
|
||||
&& ( mvControlled->Mains == true )
|
||||
&& ( mvControlled->ConvOvldFlag == false ) )
|
||||
btLampkaOgrzewanieSkladu.Turn( true );
|
||||
else
|
||||
|
||||
@@ -31,8 +31,6 @@ bool TTrackFollower::Init(TTrack *pTrack, TDynamicObject *NewOwner, double fDir)
|
||||
fDirection = fDir;
|
||||
Owner = NewOwner;
|
||||
SetCurrentTrack(pTrack, 0);
|
||||
fCurrentDistance = 0.0;
|
||||
fDirection = 1.0;
|
||||
iEventFlag = 3; // na torze startowym również wykonać eventy 1/2
|
||||
iEventallFlag = 3;
|
||||
if ((pCurrentSegment)) // && (pCurrentSegment->GetLength()<fFirstDistance))
|
||||
@@ -40,6 +38,12 @@ bool TTrackFollower::Init(TTrack *pTrack, TDynamicObject *NewOwner, double fDir)
|
||||
return true;
|
||||
}
|
||||
|
||||
void TTrackFollower::Reset()
|
||||
{
|
||||
fCurrentDistance = 0.0;
|
||||
fDirection = 1.0;
|
||||
}
|
||||
|
||||
TTrack * TTrackFollower::SetCurrentTrack(TTrack *pTrack, int end)
|
||||
{ // przejechanie na inny odcinkek toru, z ewentualnym rozpruciem
|
||||
if (pTrack)
|
||||
|
||||
@@ -40,6 +40,7 @@ public:
|
||||
//{ return pCurrentSegment->ComputeLength(p1,cp1,cp2,p2); };
|
||||
// inline double GetRadius(double L, double d); //McZapkie-150503
|
||||
bool Init(TTrack *pTrack, TDynamicObject *NewOwner, double fDir);
|
||||
void Reset();
|
||||
void Render(float fNr);
|
||||
// members
|
||||
double fOffsetH = 0.0; // Ra: odległość środka osi od osi toru (dla samochodów) - użyć do wężykowania
|
||||
|
||||
@@ -24,6 +24,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "translation.h"
|
||||
#include "Train.h"
|
||||
#include "Timer.h"
|
||||
#include "dictionary.h"
|
||||
|
||||
#pragma comment (lib, "glu32.lib")
|
||||
#pragma comment (lib, "dsound.lib")
|
||||
@@ -32,7 +33,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#pragma comment (lib, "dbghelp.lib")
|
||||
#pragma comment (lib, "version.lib")
|
||||
|
||||
#ifdef __linux__
|
||||
#ifdef __unix__
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
@@ -560,7 +561,7 @@ eu07_application::init_files() {
|
||||
DeleteFile( "log.txt" );
|
||||
DeleteFile( "errors.txt" );
|
||||
CreateDirectory( "logs", NULL );
|
||||
#elif __linux__
|
||||
#elif __unix__
|
||||
unlink("log.txt");
|
||||
unlink("errors.txt");
|
||||
mkdir("logs", 0755);
|
||||
|
||||
5
audio.h
5
audio.h
@@ -9,8 +9,13 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenAL/al.h>
|
||||
#include <OpenAL/alc.h>
|
||||
#else
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#endif
|
||||
|
||||
namespace audio {
|
||||
|
||||
|
||||
@@ -26,6 +26,26 @@ jobs:
|
||||
artifactName: binaries
|
||||
displayName: 'Publish binaries'
|
||||
|
||||
- job: macos1013
|
||||
pool:
|
||||
vmImage: 'macOS-10.13'
|
||||
displayName: 'MacOS 10.13'
|
||||
steps:
|
||||
- script: |
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install glew glfw python2 libpng glm luajit libserialport libsndfile asio pkg-config
|
||||
displayName: 'Install dependencies'
|
||||
- script: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DWITH_UART=OFF
|
||||
cmake --build .
|
||||
displayName: 'Build'
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathtoPublish: 'build/bin'
|
||||
artifactName: binaries
|
||||
displayName: 'Publish binaries'
|
||||
|
||||
- job: windows_x64
|
||||
pool:
|
||||
vmImage: 'vs2017-win2016'
|
||||
|
||||
55
dictionary.cpp
Normal file
55
dictionary.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
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/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "dictionary.h"
|
||||
|
||||
#include "simulation.h"
|
||||
#include "utilities.h"
|
||||
#include "DynObj.h"
|
||||
#include "Driver.h"
|
||||
#include "mtable.h"
|
||||
|
||||
dictionary_source::dictionary_source( std::string const &Input ) {
|
||||
|
||||
auto const keyvaluepairs { Split( Input, '&' ) };
|
||||
|
||||
for( auto const &keyvaluepair : keyvaluepairs ) {
|
||||
|
||||
auto const valuepos { keyvaluepair.find( '=' ) };
|
||||
if( keyvaluepair[ 0 ] != '$' ) {
|
||||
// regular key, value pairs
|
||||
insert(
|
||||
ToLower( keyvaluepair.substr( 0, valuepos ) ),
|
||||
keyvaluepair.substr( valuepos + 1 ) );
|
||||
}
|
||||
else {
|
||||
// special case, $key indicates request to include certain dataset clarified by value
|
||||
auto const key { ToLower( keyvaluepair.substr( 0, valuepos ) ) };
|
||||
auto const value { keyvaluepair.substr( valuepos + 1 ) };
|
||||
|
||||
if( key == "$timetable" ) {
|
||||
// timetable pulled from (preferably) the owner/direct controller of specified vehicle
|
||||
auto const *vehicle { simulation::Vehicles.find( value ) };
|
||||
auto const *controller { (
|
||||
vehicle == nullptr ? nullptr :
|
||||
vehicle->ctOwner == nullptr ? vehicle->Mechanik :
|
||||
vehicle->ctOwner ) };
|
||||
auto const *timetable { (
|
||||
controller != nullptr ?
|
||||
controller->TrainTimetable() :
|
||||
nullptr ) };
|
||||
|
||||
if( timetable != nullptr ) {
|
||||
timetable->serialize( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
dictionary.h
Normal file
31
dictionary.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
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/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// collection of keyword-value pairs
|
||||
// NOTE: since our python dictionary operates on a few types, most of the class was hardcoded for simplicity
|
||||
struct dictionary_source {
|
||||
// types
|
||||
template <typename Type_>
|
||||
using keyvaluepair_sequence = std::vector<std::pair<std::string, Type_>>;
|
||||
// members
|
||||
keyvaluepair_sequence<double> floats;
|
||||
keyvaluepair_sequence<int> integers;
|
||||
keyvaluepair_sequence<bool> bools;
|
||||
keyvaluepair_sequence<std::string> strings;
|
||||
// constructors
|
||||
dictionary_source() = default;
|
||||
dictionary_source( std::string const &Input );
|
||||
// methods
|
||||
inline void insert( std::string const &Key, double const Value ) { floats.emplace_back( Key, Value ); }
|
||||
inline void insert( std::string const &Key, int const Value ) { integers.emplace_back( Key, Value ); }
|
||||
inline void insert( std::string const &Key, bool const Value ) { bools.emplace_back( Key, Value ); }
|
||||
inline void insert( std::string const &Key, std::string const Value ) { strings.emplace_back( Key, Value ); }
|
||||
};
|
||||
@@ -45,9 +45,11 @@ driver_mode::drivermode_input::poll() {
|
||||
if( true == Global.InputGamepad ) {
|
||||
gamepad.poll();
|
||||
}
|
||||
#ifdef WITH_UART
|
||||
if( uart != nullptr ) {
|
||||
uart->poll();
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
// TBD, TODO: wrap current command in object, include other input sources?
|
||||
input::command = (
|
||||
@@ -67,10 +69,12 @@ driver_mode::drivermode_input::init() {
|
||||
if( true == Global.InputGamepad ) {
|
||||
gamepad.init();
|
||||
}
|
||||
#ifdef WITH_UART
|
||||
if( true == Global.uart_conf.enable ) {
|
||||
uart = std::make_unique<uart_input>();
|
||||
uart->init();
|
||||
}
|
||||
#endif
|
||||
if (Global.motiontelemetry_conf.enable)
|
||||
telemetry = std::make_unique<motiontelemetry>();
|
||||
|
||||
|
||||
@@ -14,10 +14,12 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "driverkeyboardinput.h"
|
||||
#include "drivermouseinput.h"
|
||||
#include "gamepadinput.h"
|
||||
#include "uart.h"
|
||||
#include "Console.h"
|
||||
#include "Camera.h"
|
||||
#include "Classes.h"
|
||||
#ifdef WITH_UART
|
||||
#include "uart.h"
|
||||
#endif
|
||||
|
||||
class driver_mode : public application_mode {
|
||||
|
||||
@@ -77,7 +79,9 @@ private:
|
||||
#ifdef _WIN32
|
||||
Console console;
|
||||
#endif
|
||||
#ifdef WITH_UART
|
||||
std::unique_ptr<uart_input> uart;
|
||||
#endif
|
||||
std::unique_ptr<motiontelemetry> telemetry;
|
||||
|
||||
bool init();
|
||||
|
||||
27
mtable.cpp
27
mtable.cpp
@@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "mtable.h"
|
||||
#include "Globals.h"
|
||||
#include "simulationtime.h"
|
||||
#include "dictionary.h"
|
||||
#include "utilities.h"
|
||||
|
||||
double TTrainParameters::CheckTrainLatency()
|
||||
@@ -524,3 +525,29 @@ bool TTrainParameters::DirectionChange()
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void TTrainParameters::serialize( dictionary_source *Output ) const {
|
||||
|
||||
Output->insert( "trainnumber", TrainName );
|
||||
Output->insert( "train_brakingmassratio", BrakeRatio );
|
||||
Output->insert( "train_enginetype", LocSeries );
|
||||
Output->insert( "train_engineload", LocLoad );
|
||||
|
||||
Output->insert( "train_stationindex", StationIndex );
|
||||
Output->insert( "train_stationcount", StationCount );
|
||||
if( StationCount > 0 ) {
|
||||
// timetable stations data, if there's any
|
||||
for( auto stationidx = 1; stationidx <= StationCount; ++stationidx ) {
|
||||
auto const stationlabel { "train_station" + std::to_string( stationidx ) + "_" };
|
||||
auto const &timetableline { TimeTable[ stationidx ] };
|
||||
Output->insert( ( stationlabel + "name" ), Bezogonkow( timetableline.StationName ) );
|
||||
Output->insert( ( stationlabel + "fclt" ), Bezogonkow( timetableline.StationWare ) );
|
||||
Output->insert( ( stationlabel + "lctn" ), timetableline.km );
|
||||
Output->insert( ( stationlabel + "vmax" ), timetableline.vmax );
|
||||
Output->insert( ( stationlabel + "ah" ), timetableline.Ah );
|
||||
Output->insert( ( stationlabel + "am" ), timetableline.Am );
|
||||
Output->insert( ( stationlabel + "dh" ), timetableline.Dh );
|
||||
Output->insert( ( stationlabel + "dm" ), timetableline.Dm );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
1
mtable.h
1
mtable.h
@@ -83,6 +83,7 @@ class TTrainParameters
|
||||
bool LoadTTfile(std::string scnpath, int iPlus, double vmax);
|
||||
bool DirectionChange();
|
||||
void StationIndexInc();
|
||||
void serialize( dictionary_source *Output ) const;
|
||||
};
|
||||
|
||||
class TMTableTime
|
||||
|
||||
@@ -38,7 +38,7 @@ void screenshot_manager::screenshot_save_thread( char *img, int w, int h )
|
||||
uint64_t perf;
|
||||
#ifdef _WIN32
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&perf);
|
||||
#elif __linux__
|
||||
#elif __unix__
|
||||
timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
perf = ts.tv_nsec;
|
||||
|
||||
17
stdafx.h
17
stdafx.h
@@ -6,6 +6,12 @@
|
||||
#ifndef STDAFX_H
|
||||
#define STDAFX_H
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifndef __unix__
|
||||
#define __unix__ 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
#ifdef _MSC_VER
|
||||
@@ -29,7 +35,7 @@
|
||||
#include <shlobj.h>
|
||||
#undef NOMINMAX
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
#ifdef __unix__
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
// stl
|
||||
@@ -71,18 +77,9 @@
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
|
||||
#ifdef EU07_BUILD_STATIC
|
||||
#define GLEW_STATIC
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#define GLFW_DLL
|
||||
#endif // _windows
|
||||
#endif // build_static
|
||||
|
||||
#include "glad/glad.h"
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
//#define GLFW_INCLUDE_GLU
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#ifndef GLFW_TRUE
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define VERSION_INFO "M7 (GL3 NET) 02.04.2019"
|
||||
#define VERSION_INFO "M7 (GL3 NET) 15.04.2019"
|
||||
|
||||
@@ -12,7 +12,7 @@ class popup
|
||||
|
||||
public:
|
||||
popup(ui_panel &panel);
|
||||
~popup();
|
||||
virtual ~popup();
|
||||
|
||||
bool render();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user