mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
Merge remote-tracking branch 'Milek7/lua' into mover_in_c++
This commit is contained in:
@@ -156,5 +156,6 @@ TButton::play( sound* Sound ) {
|
||||
|
||||
Sound->stop();
|
||||
Sound->play();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
1
Button.h
1
Button.h
@@ -49,6 +49,7 @@ class TButton
|
||||
Turn( !m_state ); };
|
||||
inline bool Active() {
|
||||
return (pModelOn) || (pModelOff); };
|
||||
inline uint8_t b() { return m_state ? 1 : 0; };
|
||||
void Update();
|
||||
void Init(std::string const &asName, TModel3d *pModel, bool bNewOn = false);
|
||||
void Load(cParser &Parser, TModel3d *pModel1, TModel3d *pModel2 = NULL);
|
||||
|
||||
@@ -5,6 +5,7 @@ include(PrecompiledHeader)
|
||||
set(DEPS_DIR ${DEPS_DIR} "${CMAKE_SOURCE_DIR}/ref")
|
||||
project("eu07")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
include_directories("." "Console" "McZapkie")
|
||||
file(GLOB HEADERS "*.h" "Console/*.h" "McZapkie/*.h")
|
||||
|
||||
@@ -70,6 +71,7 @@ set(SOURCES
|
||||
"material.cpp"
|
||||
"lua.cpp"
|
||||
"stdafx.cpp"
|
||||
"uart.cpp"
|
||||
)
|
||||
|
||||
set (ARCH "x86")
|
||||
@@ -78,7 +80,7 @@ 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
|
||||
|
||||
set(SOURCES ${SOURCES} "windows.cpp" "Console.cpp" "Console/LPT.cpp" "Console/MWD.cpp" "Console/PoKeys55.cpp" "wavread.cpp")
|
||||
set(SOURCES ${SOURCES} "windows.cpp" "Console.cpp" "Console/LPT.cpp" "Console/PoKeys55.cpp" "wavread.cpp")
|
||||
set(GLEW_INCLUDE_DIR ${GLEW_INCLUDE_DIR} "${DEPS_DIR}/glew/include/")
|
||||
set(GLFW3_INCLUDE_DIR ${GLFW3_INCLUDE_DIR} "${DEPS_DIR}/glfw/include/")
|
||||
set(GLUT_INCLUDE_DIR ${GLUT_INCLUDE_DIR} "${DEPS_DIR}/freeglut/include/")
|
||||
@@ -193,8 +195,12 @@ find_package(LuaJIT REQUIRED)
|
||||
include_directories(${LUAJIT_INCLUDE_DIR})
|
||||
target_link_libraries(${PROJECT_NAME} ${LUAJIT_LIBRARIES})
|
||||
|
||||
find_package(libserialport REQUIRED)
|
||||
include_directories(${libserialport_INCLUDE_DIR})
|
||||
target_link_libraries(${PROJECT_NAME} ${libserialport_LIBRARY})
|
||||
|
||||
if (UNIX)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -g")
|
||||
endif()
|
||||
|
||||
#cotire(${PROJECT_NAME})
|
||||
|
||||
9
CMake_modules/Findlibserialport.cmake
Normal file
9
CMake_modules/Findlibserialport.cmake
Normal file
@@ -0,0 +1,9 @@
|
||||
find_path(libserialport_INCLUDE_DIR libserialport.h)
|
||||
find_library(libserialport_LIBRARY serialport)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(libserialport DEFAULT_MSG libserialport_LIBRARY libserialport_INCLUDE_DIR)
|
||||
if(libserialport_FOUND)
|
||||
set(libserialport_LIBRARIES ${libserialport_LIBRARY})
|
||||
set(libserialport_INCLUDE_DIRS ${libserialport_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
127
Console.cpp
127
Console.cpp
@@ -13,7 +13,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "McZapkie/mctools.h"
|
||||
#include "LPT.h"
|
||||
#include "Logs.h"
|
||||
#include "MWD.h" // maciek001: obsluga portu COM
|
||||
#include "PoKeys55.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -118,7 +117,6 @@ Console::~Console()
|
||||
{
|
||||
delete PoKeys55[0];
|
||||
delete PoKeys55[1];
|
||||
delete MWDComm;
|
||||
};
|
||||
|
||||
void Console::ModeSet(int m, int h)
|
||||
@@ -166,18 +164,6 @@ int Console::On()
|
||||
break;
|
||||
}
|
||||
|
||||
if (Global::bMWDmasterEnable)
|
||||
{
|
||||
WriteLog("Opening ComPort");
|
||||
MWDComm = new TMWDComm();
|
||||
if (!(MWDComm->Open())) // jeżeli nie otwarł portu
|
||||
{
|
||||
WriteLog("ERROR: ComPort is NOT OPEN!");
|
||||
delete MWDComm;
|
||||
MWDComm = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
@@ -196,8 +182,6 @@ void Console::Off()
|
||||
PoKeys55[1] = NULL;
|
||||
delete LPT;
|
||||
LPT = NULL;
|
||||
delete MWDComm;
|
||||
MWDComm = NULL;
|
||||
};
|
||||
|
||||
void Console::BitsSet(int mask, int entry)
|
||||
@@ -289,56 +273,6 @@ void Console::BitsUpdate(int mask)
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (Global::bMWDmasterEnable)
|
||||
{
|
||||
// maciek001: MWDComm lampki i kontrolki
|
||||
// out3: ogrzewanie sk?adu, opory rozruchowe, poslizg, zaluzjewent, -, -, czuwak, shp
|
||||
// out4: stycz.liniowe, pezekaznikr??nicobwpomoc, nadmiarprzetw, roznicowy obw. g?, nadmiarsilniki, wylszybki, zanikpr?duprzyje?dzienaoporach, nadmiarsprezarki
|
||||
// out5: HASLER */
|
||||
if (mask & 0x0001) if (iBits & 1) {
|
||||
MWDComm->WriteDataBuff[4] |= 1 << 7; // SHP HASLER też
|
||||
if (!MWDComm->bSHPstate) {
|
||||
MWDComm->bSHPstate = true;
|
||||
MWDComm->bPrzejazdSHP = true;
|
||||
}
|
||||
else MWDComm->bPrzejazdSHP = false;
|
||||
}
|
||||
else {
|
||||
MWDComm->WriteDataBuff[4] &= ~(1 << 7);
|
||||
MWDComm->bPrzejazdSHP = false;
|
||||
MWDComm->bSHPstate = false;
|
||||
}
|
||||
if (mask & 0x0002) if (iBits & 2) MWDComm->WriteDataBuff[4] |= 1 << 6; // CA
|
||||
else MWDComm->WriteDataBuff[4] &= ~(1 << 6);
|
||||
if (mask & 0x0004) if (iBits & 4) MWDComm->WriteDataBuff[4] |= 1 << 1; // jazda na oporach rozruchowych
|
||||
else MWDComm->WriteDataBuff[4] &= ~(1 << 1);
|
||||
if (mask & 0x0008) if (iBits & 8) MWDComm->WriteDataBuff[5] |= 1 << 5; // wyłącznik szybki
|
||||
else MWDComm->WriteDataBuff[5] &= ~(1 << 5);
|
||||
if (mask & 0x0010) if (iBits & 0x10) MWDComm->WriteDataBuff[5] |= 1 << 4; // nadmiarowy silników trakcyjnych
|
||||
else MWDComm->WriteDataBuff[5] &= ~(1 << 4);
|
||||
if (mask & 0x0020) if (iBits & 0x20) MWDComm->WriteDataBuff[5] |= 1 << 0; // styczniki liniowe
|
||||
else MWDComm->WriteDataBuff[5] &= ~(1 << 0);
|
||||
if (mask & 0x0040) if (iBits & 0x40) MWDComm->WriteDataBuff[4] |= 1 << 2; // poślizg
|
||||
else MWDComm->WriteDataBuff[4] &= ~(1 << 2);
|
||||
if (mask & 0x0080) if (iBits & 0x80) MWDComm->WriteDataBuff[5] |= 1 << 2; // (nadmiarowy) przetwornicy? ++
|
||||
else MWDComm->WriteDataBuff[5] &= ~(1 << 2);
|
||||
if (mask & 0x0100) if (iBits & 0x100) MWDComm->WriteDataBuff[5] |= 1 << 7; // nadmiarowy sprężarki
|
||||
else MWDComm->WriteDataBuff[5] &= ~(1 << 7);
|
||||
if (mask & 0x0200) if (iBits & 0x200) MWDComm->WriteDataBuff[2] |= 1 << 1; // wentylatory i opory
|
||||
else MWDComm->WriteDataBuff[2] &= ~(1 << 1);
|
||||
if (mask & 0x0400) if (iBits & 0x400) MWDComm->WriteDataBuff[2] |= 1 << 2; // wysoki rozruch
|
||||
else MWDComm->WriteDataBuff[2] &= ~(1 << 2);
|
||||
if (mask & 0x0800) if (iBits & 0x800) MWDComm->WriteDataBuff[4] |= 1 << 0; // ogrzewanie pociągu
|
||||
else MWDComm->WriteDataBuff[4] &= ~(1 << 0);
|
||||
if (mask & 0x1000) if (iBits & 0x1000) MWDComm->bHamowanie = true; // hasler: ciśnienie w hamulcach HASLER rysik 2
|
||||
else MWDComm->bHamowanie = false;
|
||||
if (mask & 0x2000) if (iBits & 0x2000) MWDComm->WriteDataBuff[6] |= 1 << 4; // hasler: prąd "na" silnikach - HASLER rysik 3
|
||||
else MWDComm->WriteDataBuff[6] &= ~(1 << 4);
|
||||
if (mask & 0x4000) if (iBits & 0x4000) MWDComm->WriteDataBuff[6] |= 1 << 7; // brzęczyk SHP/CA
|
||||
else MWDComm->WriteDataBuff[6] &= ~(1 << 7);
|
||||
//if(mask & 0x8000) if(iBits & 0x8000) MWDComm->WriteDataBuff[1] |= 1<<7; (puste)
|
||||
//else MWDComm->WriteDataBuff[0] &= ~(1<<7);
|
||||
}
|
||||
};
|
||||
|
||||
void Console::ValueSet(int x, double y)
|
||||
@@ -371,57 +305,6 @@ void Console::ValueSet(int x, double y)
|
||||
WriteLog(" calibrated=" + std::to_string(temp));
|
||||
PoKeys55[0]->PWM(x, temp);
|
||||
}
|
||||
if (Global::bMWDmasterEnable)
|
||||
{
|
||||
unsigned int iliczba;
|
||||
switch (x)
|
||||
{
|
||||
case 0: iliczba = (unsigned int)floor((y / (Global::fMWDzg[0] * 10) * Global::fMWDzg[1]) + 0.5); // zbiornik główny
|
||||
MWDComm->WriteDataBuff[12] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[11] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main tank press " + to_string(MWDComm->WriteDataBuff[12]) + " " + to_string(MWDComm->WriteDataBuff[11]));
|
||||
break;
|
||||
case 1: iliczba = (unsigned int)floor((y / (Global::fMWDpg[0] * 10) * Global::fMWDpg[1]) + 0.5); // przewód główny
|
||||
MWDComm->WriteDataBuff[10] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[9] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Main pipe press " + to_string(MWDComm->WriteDataBuff[10]) + " " + to_string(MWDComm->WriteDataBuff[9]));
|
||||
break;
|
||||
case 2: iliczba = (unsigned int)floor((y / (Global::fMWDph[0] * 10) * Global::fMWDph[1]) + 0.5); // cylinder hamulcowy
|
||||
MWDComm->WriteDataBuff[8] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[7] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Break press " + to_string(MWDComm->WriteDataBuff[8]) + " " + to_string(MWDComm->WriteDataBuff[7]));
|
||||
break;
|
||||
case 3: iliczba = (unsigned int)floor((y / Global::fMWDvolt[0] * Global::fMWDvolt[1]) + 0.5); // woltomierz WN
|
||||
MWDComm->WriteDataBuff[14] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[13] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Hi Volt meter " + to_string(MWDComm->WriteDataBuff[14]) + " " + to_string(MWDComm->WriteDataBuff[13]));
|
||||
break;
|
||||
case 4: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 1
|
||||
MWDComm->WriteDataBuff[16] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[15] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Apm meter1 " + to_string(MWDComm->WriteDataBuff[16]) + " " + to_string(MWDComm->WriteDataBuff[15]));
|
||||
break;
|
||||
case 5: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 2
|
||||
MWDComm->WriteDataBuff[18] = (unsigned char)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[17] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Apm meter2 " + to_string(MWDComm->WriteDataBuff[18]) + " " + to_string(MWDComm->WriteDataBuff[17]));
|
||||
break;
|
||||
case 6: iliczba = (unsigned int)floor((y / Global::fMWDamp[0] * Global::fMWDamp[1]) + 0.5); // amp WN 3
|
||||
MWDComm->WriteDataBuff[20] = (unsigned int)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[19] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Apm meter3 " + to_string(MWDComm->WriteDataBuff[20]) + " " + to_string(MWDComm->WriteDataBuff[19]));
|
||||
break;
|
||||
case 7: if (Global::iPause) MWDComm->WriteDataBuff[0] = 0; //skoro pauza to hasler stoi i nie nabija kilometrów CHYBA NIE DZIAŁA!
|
||||
else MWDComm->WriteDataBuff[0] = (unsigned char)floor(y); // prędkość dla np haslera
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Speed: " + to_string(MWDComm->WriteDataBuff[0]));
|
||||
break;
|
||||
case 8: iliczba = (unsigned int)floor((y / Global::fMWDlowVolt[0] * Global::fMWDlowVolt[1]) + 0.5); // volt NN
|
||||
MWDComm->WriteDataBuff[22] = (unsigned int)(iliczba >> 8);
|
||||
MWDComm->WriteDataBuff[21] = (unsigned char)iliczba;
|
||||
if (Global::bMWDmasterEnable && Global::iMWDDebugMode & 8) WriteLog("Low Volt meter " + to_string(MWDComm->WriteDataBuff[22]) + " " + to_string(MWDComm->WriteDataBuff[21]));
|
||||
break; // przygotowane do wdrożenia, jeszcze nie wywoływane
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void Console::Update()
|
||||
@@ -439,11 +322,6 @@ void Console::Update()
|
||||
Global::iPause |= 8; // tak???
|
||||
PoKeys55[0]->Connect(); // próba ponownego podłączenia
|
||||
}
|
||||
if (Global::bMWDmasterEnable)
|
||||
{
|
||||
if (MWDComm->GetMWDState()) MWDComm->Run();
|
||||
else MWDComm->Close();
|
||||
}
|
||||
};
|
||||
|
||||
float Console::AnalogGet(int x)
|
||||
@@ -468,11 +346,6 @@ float Console::AnalogCalibrateGet(int x)
|
||||
if (x == 1) return b/10;
|
||||
else return b;
|
||||
}
|
||||
if (Global::bMWDmasterEnable && Global::bMWDBreakEnable)
|
||||
{
|
||||
float b = (float)MWDComm->uiAnalog[x];
|
||||
return (b - Global::fMWDAnalogInCalib[x][0]) / (Global::fMWDAnalogInCalib[x][1] - Global::fMWDAnalogInCalib[x][0]);
|
||||
}
|
||||
return -1.0; // odcięcie
|
||||
};
|
||||
|
||||
|
||||
763
Console/MWD.cpp
763
Console/MWD.cpp
@@ -1,763 +0,0 @@
|
||||
/*
|
||||
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/.
|
||||
*/
|
||||
|
||||
/*
|
||||
Program obsługi portu COM i innych na potrzeby sterownika MWDevice
|
||||
(oraz innych wykorzystujących komunikację przez port COM)
|
||||
dla Symulatora Pojazdów Szynowych MaSzyna
|
||||
author: Maciej Witek 2016
|
||||
Autor nie ponosi odpowiedzialności za niewłaciwe używanie lub działanie programu!
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
#include "MWD.h"
|
||||
#include "Globals.h"
|
||||
#include "Logs.h"
|
||||
#include "World.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
HANDLE hComm;
|
||||
|
||||
TMWDComm::TMWDComm() // konstruktor
|
||||
{
|
||||
MWDTime = 0;
|
||||
bSHPstate = false;
|
||||
bPrzejazdSHP = false;
|
||||
bKabina1 = true; // pasuje wyciągnąć dane na temat kabiny
|
||||
bKabina2 = false; // i ustawiać te dwa parametry!
|
||||
bHamowanie = false;
|
||||
bCzuwak = false;
|
||||
|
||||
bRysik1H = false;
|
||||
bRysik1L = false;
|
||||
bRysik2H = false;
|
||||
bRysik2L = false;
|
||||
|
||||
bocznik = 0;
|
||||
nastawnik = 0;
|
||||
kierunek = 0;
|
||||
bnkMask = 0;
|
||||
|
||||
int i = 6;
|
||||
|
||||
while (i)
|
||||
{
|
||||
i--;
|
||||
lastStateData[i] = 0;
|
||||
maskData[i] = 0;
|
||||
maskSwitch[i] = 0;
|
||||
bitSwitch[i] = 0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (i<BYTETOWRITE)
|
||||
{
|
||||
if (i<BYTETOREAD)ReadDataBuff[i] = 0;
|
||||
WriteDataBuff[i] = 0;
|
||||
i++;
|
||||
}
|
||||
i = 0;
|
||||
while (i<6)
|
||||
{
|
||||
lastStateData[i] = 0;
|
||||
maskSwitch[i] = 0;
|
||||
bitSwitch[i] = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
TMWDComm::~TMWDComm() // destruktor
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool TMWDComm::Open() // otwieranie portu COM
|
||||
{
|
||||
LPCSTR portId = Global::sMWDPortId.c_str();
|
||||
hComm = CreateFile(portId, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hComm == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (GetLastError() == ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
WriteLog("PortCOM ERROR: serial port does not exist"); // serial port does not exist.
|
||||
// Inform user.
|
||||
}
|
||||
WriteLog("PortCOM ERROR! not open!");
|
||||
// some other error occurred. Inform user.
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DCB CommDCB;
|
||||
CommDCB.DCBlength = sizeof(DCB);
|
||||
GetCommState(hComm, &CommDCB);
|
||||
|
||||
CommDCB.BaudRate = Global::iMWDBaudrate;
|
||||
CommDCB.fBinary = TRUE;
|
||||
CommDCB.fParity = FALSE;
|
||||
CommDCB.fOutxCtsFlow = FALSE; // No CTS output flow control
|
||||
CommDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
|
||||
CommDCB.fDtrControl = FALSE; // DTR flow control type
|
||||
|
||||
CommDCB.fDsrSensitivity = FALSE; // DSR sensitivity
|
||||
CommDCB.fTXContinueOnXoff = FALSE; // XOFF continues Tx
|
||||
CommDCB.fOutX = FALSE; // No XON/XOFF out flow control
|
||||
CommDCB.fInX = FALSE; // No XON/XOFF in flow control
|
||||
CommDCB.fErrorChar = FALSE; // Disable error replacement
|
||||
CommDCB.fNull = FALSE; // Disable null stripping
|
||||
CommDCB.fRtsControl = RTS_CONTROL_DISABLE;
|
||||
|
||||
CommDCB.fAbortOnError = FALSE;
|
||||
|
||||
CommDCB.ByteSize = 8;
|
||||
CommDCB.Parity = NOPARITY;
|
||||
CommDCB.StopBits = ONESTOPBIT;
|
||||
|
||||
// konfiguracja portu
|
||||
if (!SetCommState(hComm, &CommDCB))
|
||||
{
|
||||
// dwError = GetLastError ();
|
||||
WriteLog("Unable to configure the serial port!");
|
||||
return FALSE;
|
||||
}
|
||||
WriteLog("PortCOM OPEN and CONFIG!");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool TMWDComm::Close() // zamykanie portu COM
|
||||
{
|
||||
Global::bMWDmasterEnable = false; // główne włączenie portu!
|
||||
Global::bMWDInputEnable = false; // włącz wejścia
|
||||
Global::bMWDBreakEnable = false; // włącz wejścia analogowe
|
||||
|
||||
WriteLog("COM Port is closing...");
|
||||
int i = 0;
|
||||
while (i < BYTETOWRITE) // zerowanie danych...
|
||||
{
|
||||
WriteDataBuff[i] = 0;
|
||||
i++;
|
||||
}
|
||||
Sleep(100);
|
||||
SendData(); // wysyłanie do pulpitu: zatrzymanie haslera i zgaszenie lampek
|
||||
Sleep(700);
|
||||
CloseHandle(hComm);
|
||||
WriteLog("COM is close!");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool TMWDComm::GetMWDState() // sprawdzanie otwarcia portu COM
|
||||
{
|
||||
if (hComm > 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool TMWDComm::ReadData() // odbieranie danych + odczyta danych analogowych i zapis do zmiennych
|
||||
{
|
||||
DWORD bytes_read;
|
||||
ReadFile(hComm, &ReadDataBuff[0], BYTETOREAD, &bytes_read, NULL);
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog("Data receive. Checking data...");
|
||||
if (Global::bMWDBreakEnable)
|
||||
{
|
||||
uiAnalog[0] = (ReadDataBuff[9] << 8) + ReadDataBuff[8];
|
||||
uiAnalog[1] = (ReadDataBuff[11] << 8) + ReadDataBuff[10];
|
||||
uiAnalog[2] = (ReadDataBuff[13] << 8) + ReadDataBuff[12];
|
||||
uiAnalog[3] = (ReadDataBuff[15] << 8) + ReadDataBuff[14];
|
||||
if (Global::bMWDdebugEnable && (Global::iMWDDebugMode & 1))
|
||||
{
|
||||
WriteLog("Main Break = " + to_string(uiAnalog[0]));
|
||||
WriteLog("Locomotiv Break = " + to_string(uiAnalog[1]));
|
||||
}
|
||||
if (Global::bMWDdebugEnable && (Global::iMWDDebugMode & 2))
|
||||
{
|
||||
WriteLog("Analog input 1 = " + to_string(uiAnalog[2]));
|
||||
WriteLog("Analog imput 2 = " + to_string(uiAnalog[3]));
|
||||
}
|
||||
}
|
||||
if (Global::bMWDInputEnable) CheckData();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool TMWDComm::SendData() // wysyłanie danych
|
||||
{
|
||||
DWORD bytes_write;
|
||||
|
||||
WriteFile(hComm, &WriteDataBuff[0], BYTETOWRITE, &bytes_write, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool TMWDComm::Run() // wywoływanie obsługi MWD + generacja większego opóźnienia
|
||||
{
|
||||
if (GetMWDState())
|
||||
{
|
||||
MWDTime++;
|
||||
if (!(MWDTime % Global::iMWDdivider))
|
||||
{
|
||||
MWDTime = 0;
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog("Sending data...");
|
||||
SendData();
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog(" complet!\nReceiving data...");
|
||||
ReadData();
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode == 128) WriteLog(" complet!");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLog("Port COM: connection ERROR!");
|
||||
Close();
|
||||
// może spróbować się połączyć znowu?
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void TMWDComm::CheckData() // sprawdzanie wejść cyfrowych i odpowiednie sterowanie maszyną
|
||||
{
|
||||
int i = 0;
|
||||
while (i < 6)
|
||||
{
|
||||
maskData[i] = ReadDataBuff[i] ^ lastStateData[i];
|
||||
lastStateData[i] = ReadDataBuff[i];
|
||||
i++;
|
||||
}
|
||||
/*
|
||||
Rozpiska portów!
|
||||
Port0: 0 NC odblok. przek. sprężarki i wentyl. oporów
|
||||
1 M wyłącznik wył. szybkiego
|
||||
2 Shift+M impuls załączający wył. szybki
|
||||
3 N odblok. przekaźników nadmiarowych
|
||||
i różnicowego obwodu głównegoMMm
|
||||
4 NC rezerwa
|
||||
5 Ctrl+N odblok. przek. nadmiarowych
|
||||
przetwornicy, ogrzewania pociągu i różnicowych obw. pomocniczych
|
||||
6 L wył. styczników liniowych
|
||||
7 SPACE kasowanie czuwaka
|
||||
|
||||
Port1: 0 NC
|
||||
1 (Shift) X przetwornica
|
||||
2 (Shift) C sprężarka
|
||||
3 S piasecznice
|
||||
4 (Shift) H ogrzewanie składu
|
||||
5 przel. hamowania Shift+B
|
||||
pspbpwy Ctrl+B pospieszny B towarowy
|
||||
6 przel. hamowania
|
||||
7 (Shift) F rozruch w/n
|
||||
|
||||
Port2: 0 (Shift) P pantograf przedni
|
||||
1 (Shift) O pantograf tylni
|
||||
2 ENTER przyhamowanie przy poślizgu
|
||||
3 () przyciemnienie świateł
|
||||
4 () przyciemnienie świateł
|
||||
5 NUM6 odluźniacz
|
||||
6 a syrena lok W
|
||||
7 A syrena lok N
|
||||
|
||||
Port3: 0 Shift+J bateria
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
*/
|
||||
|
||||
/* po przełączeniu bistabilnego najpierw wciskamy klawisz i przy następnym
|
||||
wejściu w pętlę MWD puszczamy bo inaczej nie działa
|
||||
*/
|
||||
|
||||
// wciskanie przycisków klawiatury
|
||||
/*PORT0*/
|
||||
if (maskData[0] & 0x02) if (lastStateData[0] & 0x02)
|
||||
KeyBoard('M', 1); // wyłączenie wyłącznika szybkiego
|
||||
else KeyBoard('M', 0); // monostabilny
|
||||
if (maskData[0] & 0x04) if (lastStateData[0] & 0x04) // impuls załączający wyłącznik szybki
|
||||
{
|
||||
KeyBoard(0x10, 1); // monostabilny
|
||||
KeyBoard('M', 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyBoard('M', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
if (maskData[0] & 0x08) if (lastStateData[0] & 0x08)
|
||||
KeyBoard('N', 1); // odblok nadmiarowego silników trakcyjnych
|
||||
else KeyBoard('N', 0); // monostabilny
|
||||
if (maskData[0] & 0x20) if (lastStateData[0] & 0x20)
|
||||
{ // odblok nadmiarowego przetwornicy, ogrzewania poc.
|
||||
KeyBoard(0x11, 1); // różnicowego obwodów pomocniczych
|
||||
KeyBoard('N', 1); // monostabilny
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyBoard('N', 0);
|
||||
KeyBoard(0x11, 0);
|
||||
}
|
||||
if (maskData[0] & 0x40) if (lastStateData[0] & 0x40) KeyBoard('L', 1); // wył. styczników liniowych
|
||||
else KeyBoard('L', 0); // monostabilny
|
||||
if (maskData[0] & 0x80) if (lastStateData[0] & 0x80) KeyBoard(0x20, 1); // kasowanie czuwaka/SHP
|
||||
else KeyBoard(0x20, 0); // kasowanie czuwaka/SHP
|
||||
|
||||
/*PORT1*/
|
||||
|
||||
// puszczanie przycisku bistabilnego klawiatury
|
||||
if (maskSwitch[1] & 0x02)
|
||||
{
|
||||
if (bitSwitch[1] & 0x02)
|
||||
{
|
||||
KeyBoard('X', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('X', 0);
|
||||
maskSwitch[1] &= ~0x02;
|
||||
}
|
||||
if (maskSwitch[1] & 0x04) {
|
||||
if (bitSwitch[1] & 0x04) {
|
||||
KeyBoard('C', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('C', 0);
|
||||
maskSwitch[1] &= ~0x04;
|
||||
}
|
||||
if (maskSwitch[1] & 0x10) {
|
||||
if (bitSwitch[1] & 0x10) {
|
||||
KeyBoard('H', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('H', 0);
|
||||
maskSwitch[1] &= ~0x10;
|
||||
}
|
||||
if (maskSwitch[1] & 0x20 || maskSwitch[1] & 0x40) {
|
||||
if (maskSwitch[1] & 0x20) KeyBoard(0x10, 0);
|
||||
if (maskSwitch[1] & 0x40) KeyBoard(0x11, 0);
|
||||
KeyBoard('B', 0);
|
||||
maskSwitch[1] &= ~0x60;
|
||||
}
|
||||
if (maskSwitch[1] & 0x80) {
|
||||
if (bitSwitch[1] & 0x80) {
|
||||
KeyBoard('F', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('F', 0);
|
||||
maskSwitch[1] &= ~0x80;
|
||||
}
|
||||
|
||||
// przetwornica
|
||||
if (maskData[1] & 0x02) if (lastStateData[1] & 0x02)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('X', 1);
|
||||
maskSwitch[1] |= 0x02;
|
||||
bitSwitch[1] |= 0x02;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[1] |= 0x02;
|
||||
bitSwitch[1] &= ~0x02;
|
||||
KeyBoard('X', 1);
|
||||
}
|
||||
// sprężarka
|
||||
if (maskData[1] & 0x04) if (lastStateData[1] & 0x04)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('C', 1);
|
||||
maskSwitch[1] |= 0x04;
|
||||
bitSwitch[1] |= 0x04;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[1] |= 0x04;
|
||||
bitSwitch[1] &= ~0x04;
|
||||
KeyBoard('C', 1);
|
||||
}
|
||||
// piasecznica
|
||||
if (maskData[1] & 0x08) if (lastStateData[1] & 0x08)
|
||||
KeyBoard('S', 1);
|
||||
else
|
||||
KeyBoard('S', 0); // monostabilny
|
||||
// ogrzewanie składu
|
||||
if (maskData[1] & 0x10) if (lastStateData[1] & 0x10)
|
||||
{
|
||||
KeyBoard(0x11, 1); // bistabilny
|
||||
KeyBoard('H', 1);
|
||||
maskSwitch[1] |= 0x10;
|
||||
bitSwitch[1] |= 0x10;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[1] |= 0x10;
|
||||
bitSwitch[1] &= ~0x10;
|
||||
KeyBoard('H', 1);
|
||||
}
|
||||
// przełącznik hamowania
|
||||
if (maskData[1] & 0x20 || maskData[1] & 0x40)
|
||||
{
|
||||
if (lastStateData[1] & 0x20)
|
||||
{ // Shift+B
|
||||
KeyBoard(0x10, 1);
|
||||
maskSwitch[1] |= 0x20;
|
||||
}
|
||||
else if (lastStateData[1] & 0x40)
|
||||
{ // Ctrl+B
|
||||
KeyBoard(0x11, 1);
|
||||
maskSwitch[1] |= 0x40;
|
||||
}
|
||||
KeyBoard('B', 1);
|
||||
}
|
||||
// rozruch wysoki/niski
|
||||
if (maskData[1] & 0x80) if (lastStateData[1] & 0x80)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('F', 1);
|
||||
maskSwitch[1] |= 0x80;
|
||||
bitSwitch[1] |= 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[1] |= 0x80;
|
||||
bitSwitch[1] &= ~0x80;
|
||||
KeyBoard('F', 1);
|
||||
}
|
||||
|
||||
|
||||
//PORT2
|
||||
if (maskSwitch[2] & 0x01)
|
||||
{
|
||||
if (bitSwitch[2] & 0x01)
|
||||
{
|
||||
KeyBoard('P', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('P', 0);
|
||||
maskSwitch[2] &= ~0x01;
|
||||
}
|
||||
if (maskSwitch[2] & 0x02)
|
||||
{
|
||||
if (bitSwitch[2] & 0x02)
|
||||
{
|
||||
KeyBoard('O', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('O', 0);
|
||||
maskSwitch[2] &= ~0x02;
|
||||
}
|
||||
|
||||
// pantograf przedni
|
||||
if (maskData[2] & 0x01) if (lastStateData[2] & 0x01)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('P', 1);
|
||||
maskSwitch[2] |= 0x01;
|
||||
bitSwitch[2] |= 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[2] |= 0x01;
|
||||
bitSwitch[2] &= ~0x01;
|
||||
KeyBoard('P', 1);
|
||||
}
|
||||
// pantograf tylni
|
||||
if (maskData[2] & 0x02) if (lastStateData[2] & 0x02)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('O', 1);
|
||||
maskSwitch[2] |= 0x02;
|
||||
bitSwitch[2] |= 0x02;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[2] |= 0x02;
|
||||
bitSwitch[2] &= ~0x02;
|
||||
KeyBoard('O', 1);
|
||||
}
|
||||
// przyhamowanie przy poślizgu
|
||||
if (maskData[2] & 0x04) if (lastStateData[2] & 0x04) {
|
||||
KeyBoard(0x10, 1); // monostabilny
|
||||
KeyBoard(0x0D, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyBoard(0x0D, 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
/*if(maskData[2] & 0x08) if (lastStateData[2] & 0x08){ // przyciemnienie świateł
|
||||
KeyBoard(' ',0); // bistabilny
|
||||
KeyBoard(0x10,1);
|
||||
KeyBoard(' ',1);
|
||||
}else{
|
||||
KeyBoard(' ',0);
|
||||
KeyBoard(0x10,0);
|
||||
KeyBoard(' ',1);
|
||||
}
|
||||
if(maskData[2] & 0x10) if (lastStateData[2] & 0x10) { // przyciemnienie świateł
|
||||
KeyBoard(' ',0); // bistabilny
|
||||
KeyBoard(0x11,1);
|
||||
KeyBoard(' ',1);
|
||||
}else{
|
||||
KeyBoard(' ',0);
|
||||
KeyBoard(0x11,0);
|
||||
KeyBoard(' ',1);
|
||||
}*/
|
||||
// odluźniacz
|
||||
if (maskData[2] & 0x20) if (lastStateData[2] & 0x20)
|
||||
KeyBoard(0x66, 1);
|
||||
else
|
||||
KeyBoard(0x66, 0); // monostabilny
|
||||
// syrena wysoka
|
||||
if (maskData[2] & 0x40) if (lastStateData[2] & 0x40)
|
||||
{
|
||||
KeyBoard(0x10, 1); // monostabilny
|
||||
KeyBoard('A', 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyBoard('A', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
if (maskData[2] & 0x80) if (lastStateData[2] & 0x80)
|
||||
KeyBoard('A', 1); // syrena niska
|
||||
else
|
||||
KeyBoard('A', 0); // monostabilny
|
||||
|
||||
|
||||
//PORT3
|
||||
|
||||
if (maskSwitch[3] & 0x01)
|
||||
{
|
||||
if (bitSwitch[3] & 0x01)
|
||||
{
|
||||
KeyBoard('J', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('J', 0);
|
||||
maskSwitch[3] &= ~0x01;
|
||||
}
|
||||
if (maskSwitch[3] & 0x02)
|
||||
{
|
||||
if (bitSwitch[3] & 0x02)
|
||||
{
|
||||
KeyBoard('Y', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('Y', 0);
|
||||
maskSwitch[3] &= ~0x02;
|
||||
}
|
||||
if (maskSwitch[3] & 0x04)
|
||||
{
|
||||
if (bitSwitch[3] & 0x04)
|
||||
{
|
||||
KeyBoard('U', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('U', 0);
|
||||
maskSwitch[3] &= ~0x04;
|
||||
}
|
||||
if (maskSwitch[3] & 0x08)
|
||||
{
|
||||
if (bitSwitch[3] & 0x08)
|
||||
{
|
||||
KeyBoard('I', 0);
|
||||
KeyBoard(0x10, 0);
|
||||
}
|
||||
else KeyBoard('I', 0);
|
||||
maskSwitch[3] &= ~0x08;
|
||||
}
|
||||
|
||||
|
||||
// bateria
|
||||
if (maskData[3] & 0x01) if (lastStateData[3] & 0x01)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('J', 1);
|
||||
maskSwitch[3] |= 0x01;
|
||||
bitSwitch[3] |= 0x01;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[3] |= 0x01;
|
||||
bitSwitch[3] &= ~0x01;
|
||||
KeyBoard('J', 1);
|
||||
}
|
||||
//Światło lewe
|
||||
if (maskData[3] & 0x02) if (lastStateData[3] & 0x02)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('Y', 1);
|
||||
maskSwitch[3] |= 0x02;
|
||||
bitSwitch[3] |= 0x02;
|
||||
}else
|
||||
{
|
||||
maskSwitch[3] |= 0x02;
|
||||
bitSwitch[3] &= ~0x02;
|
||||
KeyBoard('Y', 1);
|
||||
}
|
||||
//światło górne
|
||||
if (maskData[3] & 0x04) if (lastStateData[3] & 0x04)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('U', 1);
|
||||
maskSwitch[3] |= 0x04;
|
||||
bitSwitch[3] |= 0x04;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[3] |= 0x04;
|
||||
bitSwitch[3] &= ~0x04;
|
||||
KeyBoard('U', 1);
|
||||
}
|
||||
//światło prawe
|
||||
if (maskData[3] & 0x08) if (lastStateData[3] & 0x08)
|
||||
{
|
||||
KeyBoard(0x10, 1); // bistabilny
|
||||
KeyBoard('I', 1);
|
||||
maskSwitch[3] |= 0x08;
|
||||
bitSwitch[3] |= 0x08;
|
||||
}
|
||||
else
|
||||
{
|
||||
maskSwitch[3] |= 0x08;
|
||||
bitSwitch[3] &= ~0x08;
|
||||
KeyBoard('I', 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* NASTAWNIK, BOCZNIK i KIERUNEK */
|
||||
|
||||
if (bnkMask & 1)
|
||||
{ // puszczanie klawiszy
|
||||
KeyBoard(0x6B, 0);
|
||||
bnkMask &= ~1;
|
||||
}
|
||||
if (bnkMask & 2)
|
||||
{
|
||||
KeyBoard(0x6D, 0);
|
||||
bnkMask &= ~2;
|
||||
}
|
||||
if (bnkMask & 4)
|
||||
{
|
||||
KeyBoard(0x6F, 0);
|
||||
bnkMask &= ~4;
|
||||
}
|
||||
if (bnkMask & 8)
|
||||
{
|
||||
KeyBoard(0x6A, 0);
|
||||
bnkMask &= ~8;
|
||||
}
|
||||
|
||||
if (nastawnik < ReadDataBuff[6])
|
||||
{
|
||||
bnkMask |= 1;
|
||||
nastawnik++;
|
||||
KeyBoard(0x6B, 1); // wciśnij + i dodaj 1 do nastawnika
|
||||
}
|
||||
if (nastawnik > ReadDataBuff[6])
|
||||
{
|
||||
bnkMask |= 2;
|
||||
nastawnik--;
|
||||
KeyBoard(0x6D, 1); // wciśnij - i odejmij 1 do nastawnika
|
||||
}
|
||||
if (bocznik < ReadDataBuff[7])
|
||||
{
|
||||
bnkMask |= 4;
|
||||
bocznik++;
|
||||
KeyBoard(0x6F, 1); // wciśnij / i dodaj 1 do bocznika
|
||||
}
|
||||
if (bocznik > ReadDataBuff[7])
|
||||
{
|
||||
bnkMask |= 8;
|
||||
bocznik--;
|
||||
KeyBoard(0x6A, 1); // wciśnij * i odejmij 1 do bocznika
|
||||
}
|
||||
|
||||
/* Obsługa HASLERA */
|
||||
if (ReadDataBuff[0] & 0x80)
|
||||
bCzuwak = true;
|
||||
|
||||
if (bKabina1)
|
||||
{ // logika rysika 1
|
||||
bRysik1H = true;
|
||||
bRysik1L = false;
|
||||
if (bPrzejazdSHP)
|
||||
bRysik1H = false;
|
||||
}
|
||||
else if (bKabina2)
|
||||
{
|
||||
bRysik1L = true;
|
||||
bRysik1H = false;
|
||||
if (bPrzejazdSHP)
|
||||
bRysik1L = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bRysik1H = false;
|
||||
bRysik1L = false;
|
||||
}
|
||||
|
||||
if (bHamowanie)
|
||||
{ // logika rysika 2
|
||||
bRysik2H = false;
|
||||
bRysik2L = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bCzuwak)
|
||||
bRysik2H = true;
|
||||
else
|
||||
bRysik2H = false;
|
||||
bRysik2L = false;
|
||||
}
|
||||
bCzuwak = false;
|
||||
if (bRysik1H)
|
||||
WriteDataBuff[6] |= 1 << 0;
|
||||
else
|
||||
WriteDataBuff[6] &= ~(1 << 0);
|
||||
if (bRysik1L)
|
||||
WriteDataBuff[6] |= 1 << 1;
|
||||
else
|
||||
WriteDataBuff[6] &= ~(1 << 1);
|
||||
if (bRysik2H)
|
||||
WriteDataBuff[6] |= 1 << 2;
|
||||
else
|
||||
WriteDataBuff[6] &= ~(1 << 2);
|
||||
if (bRysik2L)
|
||||
WriteDataBuff[6] |= 1 << 3;
|
||||
else
|
||||
WriteDataBuff[6] &= ~(1 << 3);
|
||||
}
|
||||
|
||||
void TMWDComm::KeyBoard(int key, bool s) // emulacja klawiatury
|
||||
{
|
||||
INPUT ip;
|
||||
// Set up a generic keyboard event.
|
||||
ip.type = INPUT_KEYBOARD;
|
||||
ip.ki.wScan = 0; // hardware scan code for key
|
||||
ip.ki.time = 0;
|
||||
ip.ki.dwExtraInfo = 0;
|
||||
|
||||
ip.ki.wVk = key; // virtual-key code for the "a" key
|
||||
|
||||
if (s)
|
||||
{ // Press the "A" key
|
||||
ip.ki.dwFlags = 0; // 0 for key press
|
||||
SendInput(1, &ip, sizeof(INPUT));
|
||||
}
|
||||
else
|
||||
{
|
||||
ip.ki.dwFlags = KEYEVENTF_KEYUP; // KEYEVENTF_KEYUP for key release
|
||||
SendInput(1, &ip, sizeof(INPUT));
|
||||
}
|
||||
|
||||
// return 1;
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
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/.
|
||||
*/
|
||||
|
||||
/*
|
||||
Program obsługi portu COM i innych na potrzeby sterownika MWDevice
|
||||
(oraz innych wykorzystujących komunikację przez port COM)
|
||||
dla Symulatora Pojazdów Szynowych MaSzyna
|
||||
author: Maciej Witek 2016
|
||||
Autor nie ponosi odpowiedzialności za niewłaciwe używanie lub działanie programu!
|
||||
*/
|
||||
|
||||
#ifndef MWDH
|
||||
#define MWDH
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#define BYTETOWRITE 31 // ilość bajtów przesyłanych z MaSzyny
|
||||
#define BYTETOREAD 16 // ilość bajtów przesyłanych do MaSzyny
|
||||
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned long DWORD;
|
||||
|
||||
class TMWDComm
|
||||
{
|
||||
private:
|
||||
int MWDTime; //
|
||||
char lastStateData[6], maskData[6], maskSwitch[6], bitSwitch[6];
|
||||
int bocznik, nastawnik, kierunek;
|
||||
char bnkMask;
|
||||
|
||||
bool ReadData(); //BYTE *pReadDataBuff);
|
||||
bool SendData(); //BYTE *pWriteDataBuff);
|
||||
void CheckData(); //sprawdzanie zmian wejść i kontrola mazaków HASLERA
|
||||
void KeyBoard(int key, bool s);
|
||||
|
||||
//void CheckData2();
|
||||
|
||||
bool bRysik1H;
|
||||
bool bRysik1L;
|
||||
bool bRysik2H;
|
||||
bool bRysik2L;
|
||||
|
||||
public:
|
||||
bool Open(); // Otwarcie portu
|
||||
bool Close(); // Zamknięcie portu
|
||||
bool Run(); // Obsługa portu
|
||||
bool GetMWDState(); // sprawdź czy port jest otwarty, 0 zamknięty, 1 otwarty
|
||||
|
||||
// zmienne do rysików HASLERA
|
||||
bool bSHPstate;
|
||||
bool bPrzejazdSHP;
|
||||
bool bKabina1;
|
||||
bool bKabina2;
|
||||
bool bHamowanie;
|
||||
bool bCzuwak;
|
||||
|
||||
unsigned int uiAnalog[4]; // trzymanie danych z wejść analogowych
|
||||
|
||||
BYTE ReadDataBuff[BYTETOREAD+2]; //17]; // bufory danych
|
||||
BYTE WriteDataBuff[BYTETOWRITE+2]; //31];
|
||||
|
||||
TMWDComm(); // konstruktor
|
||||
~TMWDComm(); // destruktor
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
INFO - wpisy do eu07.ini:
|
||||
|
||||
mwdmasterenable yes // włącz MWD (master MWD Enable)
|
||||
mwddebugenable yes // włącz logowanie
|
||||
mwddebugmode 4 // tryb debugowania (które logi)
|
||||
|
||||
mwdcomportname COM3 // nazwa portu
|
||||
mwdbaudrate 500000 // prędkość transmisji
|
||||
|
||||
mwdinputenable yes // włącz wejścia (przyciski, przełączniki)
|
||||
mwdbreakenable yes // włącz hamulce (wejścia analogowe)
|
||||
|
||||
mwdmainbreakconfig 0 1023 // konfiguracja kranu zespolonego -> min, max (położenie kranu - odczyt z ADC)
|
||||
mwdlocbreakconfig 0 1023 // konfiguracja kranu maszynisty -> min, max (położenie kranu - odczyt z ADC)
|
||||
mwdanalogin2config 0 1023
|
||||
mwdanalogin2config 0 1023
|
||||
|
||||
mwdmaintankpress 0.9 1023 // max ciśnienie w zbiorniku głownym i rozdzielczość
|
||||
mwdmainpipepress 0.7 1023 // max ciśnienie w przewodzie głównym i rozdzielczość
|
||||
mwdbreakpress 0.5 1023 // max ciśnienie w cylindrach hamulcowych i rozdzielczość
|
||||
|
||||
mwdhivoltmeter 4000 1023 // max napięcie na woltomierzu WN
|
||||
mwdhiampmeter 800 1023 // max prąd amperomierza WN
|
||||
|
||||
mwddivider 5 // dzielnik - czym większy tym rzadziej czyta diwajs
|
||||
*/
|
||||
78
Driver.cpp
78
Driver.cpp
@@ -1422,11 +1422,15 @@ void TController::TablePurger()
|
||||
iLast = sSpeedTable.size() - 1;
|
||||
};
|
||||
|
||||
void TController::TableSort()
|
||||
{
|
||||
void TController::TableSort() {
|
||||
|
||||
if( sSpeedTable.size() < 3 ) {
|
||||
// we skip last slot and no point in checking if there's only one other entry
|
||||
return;
|
||||
}
|
||||
TSpeedPos sp_temp = TSpeedPos(); // uzywany do przenoszenia
|
||||
for (std::size_t i = 0; i < (iLast - 1) && iLast > 0; ++i)
|
||||
{ // pętla tylko do dwóch pozycji od końca bo ostatniej nie modyfikujemy
|
||||
for( std::size_t i = 0; i < ( iLast - 1 ); ++i ) {
|
||||
// pętla tylko do dwóch pozycji od końca bo ostatniej nie modyfikujemy
|
||||
if (sSpeedTable[i].fDist > sSpeedTable[i + 1].fDist)
|
||||
{ // jesli pozycja wcześniejsza jest dalej to źle
|
||||
sp_temp = sSpeedTable[i + 1];
|
||||
@@ -4574,24 +4578,52 @@ TController::UpdateSituation(double dt) {
|
||||
}
|
||||
// koniec predkosci nastepnej
|
||||
|
||||
if( vel > VelDesired ) {
|
||||
// jesli jedzie za szybko do AKTUALNEGO
|
||||
if( VelDesired == 0.0 ) {
|
||||
// jesli stoj, to hamuj, ale i tak juz za pozno :)
|
||||
AccDesired = std::min( AccDesired, -0.85 ); // hamuj solidnie
|
||||
}
|
||||
else {
|
||||
// try to estimate increase of current velocity before engaged brakes start working
|
||||
// if it looks like we'll exceed maximum allowed speed start thinking about slight slowing down
|
||||
if( ( vel + vel * ( 1.0 - fBrake_a0[ 0 ] ) * AbsAccS ) > ( VelDesired + fVelPlus ) ) {
|
||||
// hamuj tak średnio
|
||||
AccDesired = std::min( AccDesired, -0.25 );
|
||||
// decisions based on current speed
|
||||
if( mvOccupied->CategoryFlag == 1 ) {
|
||||
// try to estimate increase of current velocity before engaged brakes start working
|
||||
auto const speedestimate = vel + vel * ( 1.0 - fBrake_a0[ 0 ] ) * AbsAccS;
|
||||
if( speedestimate > VelDesired ) {
|
||||
// jesli jedzie za szybko do AKTUALNEGO
|
||||
if( VelDesired == 0.0 ) {
|
||||
// jesli stoj, to hamuj, ale i tak juz za pozno :)
|
||||
AccDesired = std::min( AccDesired, -0.85 ); // hamuj solidnie
|
||||
}
|
||||
else {
|
||||
// o 5 km/h to olej (zacznij luzować)
|
||||
AccDesired = std::min(
|
||||
AccDesired, // but don't override decceleration for VelNext
|
||||
std::max( 0.0, AccPreferred ) );
|
||||
if( speedestimate > ( VelDesired + fVelPlus ) ) {
|
||||
// if it looks like we'll exceed maximum allowed speed start thinking about slight slowing down
|
||||
AccDesired = std::min( AccDesired, -0.25 );
|
||||
}
|
||||
else {
|
||||
// close enough to target to stop accelerating
|
||||
AccDesired = std::min(
|
||||
AccDesired, // but don't override decceleration for VelNext
|
||||
interpolate( // ease off as you close to the target velocity
|
||||
-0.06, AccPreferred,
|
||||
clamp( speedestimate - vel, 0.0, fVelPlus ) / fVelPlus ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// for cars the older version works better
|
||||
if( vel > VelDesired ) {
|
||||
// jesli jedzie za szybko do AKTUALNEGO
|
||||
if( VelDesired == 0.0 ) {
|
||||
// jesli stoj, to hamuj, ale i tak juz za pozno :)
|
||||
AccDesired = std::min( AccDesired, -0.9 ); // hamuj solidnie
|
||||
}
|
||||
else {
|
||||
// slow down, not full stop
|
||||
if( vel > ( VelDesired + fVelPlus ) ) {
|
||||
// hamuj tak średnio
|
||||
AccDesired = std::min( AccDesired, -fBrake_a0[ 0 ] * 0.5 );
|
||||
}
|
||||
else {
|
||||
// o 5 km/h to olej (zacznij luzować)
|
||||
AccDesired = std::min(
|
||||
AccDesired, // but don't override decceleration for VelNext
|
||||
std::max( 0.0, AccPreferred ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4599,8 +4631,10 @@ TController::UpdateSituation(double dt) {
|
||||
|
||||
// last step sanity check, until the whole calculation is straightened out
|
||||
AccDesired = std::min( AccDesired, AccPreferred );
|
||||
// also take into account impact of gravity
|
||||
AccDesired = clamp( AccDesired - fAccGravity, -0.9, 0.9 );
|
||||
if( mvOccupied->CategoryFlag == 1 ) {
|
||||
// also take into account impact of gravity
|
||||
AccDesired = clamp( AccDesired - fAccGravity, -0.9, 0.9 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
10
Driver.h
10
Driver.h
@@ -171,8 +171,8 @@ extern bool WriteLogFlag; // logowanie parametrów fizycznych
|
||||
static const int BrakeAccTableSize = 20;
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class TController
|
||||
{
|
||||
class TController {
|
||||
|
||||
private: // obsługa tabelki prędkości (musi mieć możliwość odhaczania stacji w rozkładzie)
|
||||
int iLast{ 0 }; // ostatnia wypełniona pozycja w tabeli <iFirst (modulo iSpeedTableSize)
|
||||
int iTableDirection{ 0 }; // kierunek zapełnienia tabelki względem pojazdu z AI
|
||||
@@ -183,7 +183,7 @@ class TController
|
||||
std::size_t SemNextIndex{ std::size_t(-1) };
|
||||
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
|
||||
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
|
||||
private: // parametry aktualnego składu
|
||||
// parametry aktualnego składu
|
||||
double fLength = 0.0; // długość składu (do wyciągania z ograniczeń)
|
||||
double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji
|
||||
public:
|
||||
@@ -191,11 +191,11 @@ public:
|
||||
TEvent *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
|
||||
std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu
|
||||
int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu
|
||||
private: // parametry sterowania pojazdem (stan, hamowanie)
|
||||
// parametry sterowania pojazdem (stan, hamowanie)
|
||||
private:
|
||||
double fShuntVelocity = 40.0; // maksymalna prędkość manewrowania, zależy m.in. od składu // domyślna prędkość manewrowa
|
||||
int iVehicles = 0; // ilość pojazdów w składzie
|
||||
int iEngineActive = 0; // ABu: Czy silnik byl juz zalaczony; Ra: postęp w załączaniu
|
||||
// vector3 vMechLoc; //pozycja pojazdu do liczenia odległości od semafora (?)
|
||||
bool Psyche = false;
|
||||
int iDrivigFlags = // flagi bitowe ruchu
|
||||
moveStopPoint | // podjedź do W4 możliwie blisko
|
||||
|
||||
9
EU07.cpp
9
EU07.cpp
@@ -33,6 +33,7 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
|
||||
#include "Timer.h"
|
||||
#include "resource.h"
|
||||
#include "uilayer.h"
|
||||
#include "uart.h"
|
||||
|
||||
#pragma comment (lib, "glu32.lib")
|
||||
#pragma comment (lib, "dsound.lib")
|
||||
@@ -54,7 +55,7 @@ keyboard_input Keyboard;
|
||||
mouse_input Mouse;
|
||||
gamepad_input Gamepad;
|
||||
glm::dvec2 mouse_pickmodepos; // stores last mouse position in control picking mode
|
||||
|
||||
std::unique_ptr<uart_input> uart;
|
||||
}
|
||||
|
||||
void screenshot_save_thread( char *img )
|
||||
@@ -354,9 +355,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
sound_man = std::make_unique<sound_manager>();
|
||||
|
||||
Global::pWorld = &World;
|
||||
|
||||
input::Keyboard.init();
|
||||
input::Mouse.init();
|
||||
input::Gamepad.init();
|
||||
if (Global::uart_conf.enable)
|
||||
input::uart = std::make_unique<uart_input>();
|
||||
|
||||
Global::pWorld = &World;
|
||||
if( false == World.Init( window ) ) {
|
||||
@@ -398,6 +403,8 @@ int main(int argc, char *argv[])
|
||||
&& ( true == GfxRenderer.Render() ) ) {
|
||||
glfwPollEvents();
|
||||
input::Keyboard.poll();
|
||||
if (input::uart)
|
||||
input::uart->poll();
|
||||
if( true == Global::InputMouse ) { input::Mouse.poll(); }
|
||||
if( true == Global::InputGamepad ) { input::Gamepad.poll(); }
|
||||
}
|
||||
|
||||
@@ -25,6 +25,11 @@ class float3
|
||||
};
|
||||
float Length() const;
|
||||
float LengthSquared() const;
|
||||
|
||||
operator glm::vec3() const
|
||||
{
|
||||
return glm::vec3(x, y, z);
|
||||
}
|
||||
};
|
||||
|
||||
inline bool operator==(const float3 &v1, const float3 &v2)
|
||||
|
||||
31
Gauge.cpp
31
Gauge.cpp
@@ -19,6 +19,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Model3d.h"
|
||||
#include "Timer.h"
|
||||
#include "Logs.h"
|
||||
#include "World.h"
|
||||
#include "Train.h"
|
||||
|
||||
void TGauge::Init(TSubModel *NewSubModel, TGaugeType eNewType, double fNewScale, double fNewOffset, double fNewFriction, double fNewValue)
|
||||
{ // ustawienie parametrów animacji submodelu
|
||||
@@ -315,14 +317,33 @@ void TGauge::UpdateValue()
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
TGauge::play( sound *Sound ) {
|
||||
// todo: ugly approach to getting train translation
|
||||
// maybe cache gauge position
|
||||
|
||||
if( Sound == nullptr ) { return; }
|
||||
extern TWorld World;
|
||||
|
||||
void TGauge::play( sound *Sound )
|
||||
{
|
||||
if (!Sound)
|
||||
return;
|
||||
|
||||
Sound->stop();
|
||||
|
||||
if (SubModel && World.train())
|
||||
{
|
||||
float4x4 mat;
|
||||
SubModel->ParentMatrix(&mat);
|
||||
glm::vec3 pos = *mat.TranslationGet();
|
||||
|
||||
if (glm::length(pos) > 1.0f)
|
||||
{
|
||||
pos = glm::vec3(glm::vec4(pos, 1.0f) * glm::inverse((glm::mat4)World.train()->Dynamic()->mMatrix));
|
||||
pos = pos + (glm::vec3)World.train()->Dynamic()->GetPosition();
|
||||
|
||||
Sound->set_mode(sound::anchored).dist(1.5f).position(pos);
|
||||
}
|
||||
}
|
||||
|
||||
Sound->play();
|
||||
return;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
2
Gauge.h
2
Gauge.h
@@ -68,7 +68,7 @@ class TGauge {
|
||||
void AssignDouble(double *dValue);
|
||||
void AssignInt(int *iValue);
|
||||
void UpdateValue();
|
||||
TSubModel *SubModel; // McZapkie-310302: zeby mozna bylo sprawdzac czy zainicjowany poprawnie
|
||||
TSubModel *SubModel = nullptr; // McZapkie-310302: zeby mozna bylo sprawdzac czy zainicjowany poprawnie
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
142
Globals.cpp
142
Globals.cpp
@@ -166,24 +166,11 @@ int Global::iPoKeysPWM[7] = {0, 1, 2, 3, 4, 5, 6};
|
||||
bool Global::bnewAirCouplers = true;
|
||||
double Global::fTimeSpeed = 1.0; // przyspieszenie czasu, zmienna do testów
|
||||
bool Global::bHideConsole = false; // hunter-271211: ukrywanie konsoli
|
||||
|
||||
Global::uart_conf_t Global::uart_conf;
|
||||
|
||||
//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;
|
||||
|
||||
opengl_light Global::DayLight;
|
||||
Global::soundmode_t Global::soundpitchmode = Global::linear;
|
||||
@@ -756,102 +743,33 @@ void Global::ConfigParse(cParser &Parser)
|
||||
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));
|
||||
}
|
||||
else if (token == "uart")
|
||||
{
|
||||
Parser.getTokens(3, false);
|
||||
Global::uart_conf.enable = true;
|
||||
Parser >> Global::uart_conf.port;
|
||||
Parser >> Global::uart_conf.baud;
|
||||
Parser >> Global::uart_conf.interval;
|
||||
Parser >> Global::uart_conf.updatetime;
|
||||
}
|
||||
else if (token == "uarttune")
|
||||
{
|
||||
Parser.getTokens(14);
|
||||
Parser >> Global::uart_conf.mainbrakemin
|
||||
>> Global::uart_conf.mainbrakemax
|
||||
>> Global::uart_conf.localbrakemin
|
||||
>> Global::uart_conf.localbrakemax
|
||||
>> Global::uart_conf.tankmax
|
||||
>> Global::uart_conf.tankuart
|
||||
>> Global::uart_conf.pipemax
|
||||
>> Global::uart_conf.pipeuart
|
||||
>> Global::uart_conf.brakemax
|
||||
>> Global::uart_conf.brakeuart
|
||||
>> Global::uart_conf.hvmax
|
||||
>> Global::uart_conf.hvuart
|
||||
>> Global::uart_conf.currentmax
|
||||
>> Global::uart_conf.currentuart;
|
||||
}
|
||||
} while ((token != "") && (token != "endconfig")); //(!Parser->EndOfFile)
|
||||
// na koniec trochę zależności
|
||||
if (!bLoadTraction) // wczytywanie drutów i słupów
|
||||
|
||||
42
Globals.h
42
Globals.h
@@ -293,6 +293,31 @@ class Global
|
||||
//randomizacja
|
||||
static std::mt19937 random_engine;
|
||||
|
||||
struct uart_conf_t
|
||||
{
|
||||
bool enable = false;
|
||||
std::string port;
|
||||
int baud;
|
||||
int interval;
|
||||
float updatetime;
|
||||
|
||||
float mainbrakemin = 0.0f;
|
||||
float mainbrakemax = 65535.0f;
|
||||
float localbrakemin = 0.0f;
|
||||
float localbrakemax = 65535.0f;
|
||||
float tankmax = 10.0f;
|
||||
float tankuart = 65535.0f;
|
||||
float pipemax = 10.0f;
|
||||
float pipeuart = 65535.0f;
|
||||
float brakemax = 10.0f;
|
||||
float brakeuart = 65535.0f;
|
||||
float hvmax = 100000.0f;
|
||||
float hvuart = 65535.0f;
|
||||
float currentmax = 10000.0f;
|
||||
float currentuart = 65535.0f;
|
||||
};
|
||||
static uart_conf_t uart_conf;
|
||||
|
||||
// metody
|
||||
static void TrainDelete(TDynamicObject *d);
|
||||
static void ConfigParse(cParser &parser);
|
||||
@@ -303,23 +328,6 @@ class Global
|
||||
static std::string Bezogonkow(std::string str, bool _ = false);
|
||||
static double Min0RSpeed(double vel1, double vel2);
|
||||
|
||||
// maciek001: zmienne dla MWD
|
||||
static bool bMWDmasterEnable; // główne włączenie portu COM
|
||||
static bool bMWDdebugEnable; // logowanie pracy
|
||||
static int iMWDDebugMode;
|
||||
static std::string sMWDPortId; // nazwa portu COM
|
||||
static unsigned long int iMWDBaudrate; // prędkość transmisji
|
||||
static bool bMWDInputEnable; // włącz wejścia
|
||||
static bool bMWDBreakEnable; // włącz wejścia analogowe (hamulce)
|
||||
static double fMWDAnalogInCalib[4][2]; // ustawienia kranów hamulca zespolonego i dodatkowego - min i max
|
||||
static double fMWDzg[2]; // max wartość wskazywana i max wartość generowana (rozdzielczość)
|
||||
static double fMWDpg[2];
|
||||
static double fMWDph[2];
|
||||
static double fMWDvolt[2];
|
||||
static double fMWDamp[2];
|
||||
static double fMWDlowVolt[2];
|
||||
static int iMWDdivider;
|
||||
|
||||
static opengl_light DayLight;
|
||||
|
||||
enum soundmode_t
|
||||
|
||||
39
Ground.cpp
39
Ground.cpp
@@ -3593,6 +3593,45 @@ TGround::Update_Lights() {
|
||||
m_lights.update();
|
||||
}
|
||||
|
||||
void
|
||||
TGround::Update_Hidden() {
|
||||
|
||||
// rednerowanie globalnych (nie za często?)
|
||||
for( TGroundNode *node = srGlobal.nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
|
||||
// render events and sounds from sectors near enough to the viewer
|
||||
auto const range = 2750.0; // audible range of 100 db sound
|
||||
int const camerax = static_cast<int>( std::floor( Global::pCameraPosition.x / 1000.0 ) + iNumRects / 2 );
|
||||
int const cameraz = static_cast<int>( std::floor( Global::pCameraPosition.z / 1000.0 ) + iNumRects / 2 );
|
||||
int const segmentcount = 2 * static_cast<int>( std::ceil( range / 1000.0 ) );
|
||||
int const originx = std::max( 0, camerax - segmentcount / 2 );
|
||||
int const originz = std::max( 0, cameraz - segmentcount / 2 );
|
||||
|
||||
for( int column = originx; column <= originx + segmentcount; ++column ) {
|
||||
for( int row = originz; row <= originz + segmentcount; ++row ) {
|
||||
|
||||
auto &cell = Rects[ column ][ row ];
|
||||
|
||||
for( int subcellcolumn = 0; subcellcolumn < iNumSubRects; ++subcellcolumn ) {
|
||||
for( int subcellrow = 0; subcellrow < iNumSubRects; ++subcellrow ) {
|
||||
auto subcell = cell.FastGetSubRect( subcellcolumn, subcellrow );
|
||||
if( subcell == nullptr ) { continue; }
|
||||
// renderowanie obiektów aktywnych a niewidocznych
|
||||
for( auto node = subcell->nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
// jeszcze dźwięki pojazdów by się przydały, również niewidocznych
|
||||
// TODO: move to sound renderer
|
||||
subcell->RenderSounds();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Winger 170204 - szukanie trakcji nad pantografami
|
||||
bool TGround::GetTraction(TDynamicObject *model)
|
||||
{ // aktualizacja drutu zasilającego dla każdego pantografu, żeby odczytać napięcie
|
||||
|
||||
3
Ground.h
3
Ground.h
@@ -228,7 +228,7 @@ public:
|
||||
return pSubRects + iRow * iNumSubRects + iCol; // zwrócenie właściwego
|
||||
};
|
||||
// pobranie wskaźnika do małego kwadratu, bez tworzenia jeśli nie ma
|
||||
TSubRect * FastGetSubRect(int iCol, int iRow) {
|
||||
TSubRect *FastGetSubRect(int iCol, int iRow) const {
|
||||
return (
|
||||
pSubRects ?
|
||||
pSubRects + iRow * iNumSubRects + iCol :
|
||||
@@ -289,6 +289,7 @@ class TGround
|
||||
void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem
|
||||
bool Update(double dt, int iter); // aktualizacja przesunięć zgodna z FPS
|
||||
void Update_Lights(); // updates scene lights array
|
||||
void Update_Hidden(); // updates invisible elements of the scene
|
||||
bool AddToQuery(TEvent *Event, TDynamicObject *Node);
|
||||
bool GetTraction(TDynamicObject *model);
|
||||
bool CheckQuery();
|
||||
|
||||
@@ -1090,7 +1090,9 @@ void TSubModel::ParentMatrix(float4x4 *m)
|
||||
// jeśli nie zostało wykonane Init() (tzn. zaraz po wczytaniu T3D), to
|
||||
// dodatkowy obrót
|
||||
// obrót T3D jest wymagany np. do policzenia wysokości pantografów
|
||||
*m = float4x4(*fMatrix); // skopiowanie, bo będziemy mnożyć
|
||||
m->Identity();
|
||||
if (fMatrix)
|
||||
*m = float4x4(*fMatrix); // skopiowanie, bo będziemy mnożyć
|
||||
// m(3)[1]=m[3][1]+0.054; //w górę o wysokość ślizgu (na razie tak)
|
||||
TSubModel *sm = this;
|
||||
while (sm->Parent)
|
||||
|
||||
@@ -479,6 +479,7 @@ void TPythonScreens::update()
|
||||
void TPythonScreens::setLookupPath(std::string const &path)
|
||||
{
|
||||
_lookupPath = path;
|
||||
std::replace(_lookupPath.begin(), _lookupPath.end(), '\\', '/');
|
||||
}
|
||||
|
||||
TPythonScreens::TPythonScreens()
|
||||
|
||||
255
Train.cpp
255
Train.cpp
@@ -824,8 +824,7 @@ void TTrain::OnCommand_trainbrakedecrease( TTrain *Train, command_data const &Co
|
||||
if( ( Train->mvOccupied->BrakeCtrlPos == -1 )
|
||||
&& ( Train->mvOccupied->BrakeHandle == FVel6 )
|
||||
&& ( Train->DynamicObject->Controller != AIdriver )
|
||||
&& ( Global::iFeedbackMode != 4 )
|
||||
&& ( !( Global::bMWDmasterEnable && Global::bMWDBreakEnable ) ) ) {
|
||||
&& ( Global::iFeedbackMode != 4 ) ) {
|
||||
// Odskakiwanie hamulce EP
|
||||
Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->BrakeCtrlPos + 1 );
|
||||
Train->keybrakecount = 0;
|
||||
@@ -856,8 +855,7 @@ void TTrain::OnCommand_trainbrakecharging( TTrain *Train, command_data const &Co
|
||||
if( ( Train->mvOccupied->BrakeCtrlPos == -1 )
|
||||
&& ( Train->mvOccupied->BrakeHandle == FVel6 )
|
||||
&& ( Train->DynamicObject->Controller != AIdriver )
|
||||
&& ( Global::iFeedbackMode != 4 )
|
||||
&& ( !( Global::bMWDmasterEnable && Global::bMWDBreakEnable ) ) ) {
|
||||
&& ( Global::iFeedbackMode != 4 ) ) {
|
||||
// Odskakiwanie hamulce EP
|
||||
Train->mvOccupied->BrakeLevelSet( Train->mvOccupied->BrakeCtrlPos + 1 );
|
||||
Train->keybrakecount = 0;
|
||||
@@ -1248,7 +1246,12 @@ void TTrain::OnCommand_alerteracknowledge( TTrain *Train, command_data const &Co
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command ) {
|
||||
void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command )
|
||||
{
|
||||
if (Command.desired_state == command_data::ON && Train->mvOccupied->Battery)
|
||||
return;
|
||||
if (Command.desired_state == command_data::OFF && !Train->mvOccupied->Battery)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
@@ -1289,7 +1292,19 @@ void TTrain::OnCommand_batterytoggle( TTrain *Train, command_data const &Command
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const &Command ) {
|
||||
void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const &cmd )
|
||||
{
|
||||
command_data Command = cmd;
|
||||
|
||||
if (Train->mvOccupied->PantSwitchType != "impulse")
|
||||
{
|
||||
if (Command.desired_state == Command.ON && Train->mvControlled->PantFrontUp)
|
||||
return;
|
||||
if (Command.desired_state == Command.OFF && !Train->mvControlled->PantFrontUp)
|
||||
return;
|
||||
}
|
||||
else if (Command.desired_state == Command.OFF)
|
||||
Command.action = GLFW_RELEASE;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
@@ -1369,7 +1384,18 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &Command ) {
|
||||
void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &cmd ) {
|
||||
command_data Command = cmd;
|
||||
|
||||
if (Train->mvOccupied->PantSwitchType != "impulse")
|
||||
{
|
||||
if (Command.desired_state == Command.ON && Train->mvControlled->PantRearUp)
|
||||
return;
|
||||
if (Command.desired_state == Command.OFF && !Train->mvControlled->PantRearUp)
|
||||
return;
|
||||
}
|
||||
else if (Command.desired_state == Command.OFF)
|
||||
Command.action = GLFW_RELEASE;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
@@ -1562,7 +1588,8 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
// press or hold...
|
||||
if( Train->m_linebreakerstate == 0 ) {
|
||||
if ((Command.desired_state == command_data::TOGGLE && Train->m_linebreakerstate == 0)
|
||||
|| Command.desired_state == command_data::ON) {
|
||||
// ...to close the circuit
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// fresh press, start fresh closing delay calculation
|
||||
@@ -1609,39 +1636,26 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( Train->m_linebreakerstate == 1 ) {
|
||||
else if ((Command.desired_state == command_data::TOGGLE && Train->m_linebreakerstate == 1)
|
||||
|| Command.desired_state == command_data::OFF) {
|
||||
// ...to open the circuit
|
||||
if( true == Train->mvControlled->MainSwitch( false ) ) {
|
||||
Train->mvControlled->MainSwitch( false );
|
||||
|
||||
Train->m_linebreakerstate = -1;
|
||||
Train->m_linebreakerstate = -1;
|
||||
|
||||
if( Train->ggMainOffButton.SubModel != nullptr ) {
|
||||
// two separate switches to close and break the circuit
|
||||
if( Train->ggMainOffButton.SubModel != nullptr ) {
|
||||
// two separate switches to close and break the circuit
|
||||
// visual feedback
|
||||
Train->ggMainOffButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
}
|
||||
else if( Train->ggMainButton.SubModel != nullptr ) {
|
||||
// single two-state switch
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggMainOffButton.UpdateValue( 1.0, Train->dsbSwitch );
|
||||
}
|
||||
else if( Train->ggMainButton.SubModel != nullptr ) {
|
||||
// single two-state switch
|
||||
/*
|
||||
// NOTE: we don't have switch type definition for the line breaker switch
|
||||
// so for the time being we have hard coded "impulse" switches for all EMUs
|
||||
// TODO: have proper switch type config for all switches, and put it in the cab switch descriptions, not in the .fiz
|
||||
if( Train->mvControlled->TrainType == dt_EZT ) {
|
||||
// audio feedback
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggMainButton.UpdateValue( 1.0 );
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
// visual feedback
|
||||
Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
}
|
||||
Train->ggMainButton.UpdateValue( 0.0, Train->dsbSwitch );
|
||||
}
|
||||
}
|
||||
|
||||
// play sound immediately when the switch is hit, not after release
|
||||
if( Train->fMainRelayTimer > 0.0f ) {
|
||||
Train->play_sound( Train->dsbRelay );
|
||||
@@ -1713,6 +1727,11 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvControlled->ConverterAllow && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
if (!Train->mvControlled->ConverterAllow && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
|
||||
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->ConverterAllow )
|
||||
@@ -1866,6 +1885,11 @@ void TTrain::OnCommand_compressortoggle( TTrain *Train, command_data const &Comm
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvControlled->CompressorAllow && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
if (!Train->mvControlled->CompressorAllow && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
|
||||
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->CompressorAllow ) {
|
||||
@@ -1945,8 +1969,8 @@ void TTrain::OnCommand_compressortogglelocal( TTrain *Train, command_data const
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &cmd ) {
|
||||
command_data Command = cmd;
|
||||
// TODO: don't rely on presense of 3d model to determine presence of the switch
|
||||
if( Train->ggStLinOffButton.SubModel == nullptr ) {
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
@@ -1954,6 +1978,17 @@ void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &C
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvControlled->StLinSwitchType == "toggle")
|
||||
{
|
||||
if (Command.desired_state == Command.ON && Train->mvControlled->StLinSwitchOff)
|
||||
return;
|
||||
if (Command.desired_state == Command.OFF && !Train->mvControlled->StLinSwitchOff)
|
||||
return;
|
||||
}
|
||||
else if (Command.desired_state == Command.OFF)
|
||||
Command.action = GLFW_RELEASE;
|
||||
|
||||
// NOTE: because we don't have modeled actual circuits this is a simplification of the real mechanics
|
||||
// namely, pressing the button will flip it in the entire unit, which isn't exactly physically possible
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
@@ -2064,7 +2099,12 @@ void TTrain::OnCommand_motordisconnect( TTrain *Train, command_data const &Comma
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command ) {
|
||||
void TTrain::OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command )
|
||||
{
|
||||
if (Train->mvControlled->Imax < Train->mvControlled->ImaxHi && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
if (!(Train->mvControlled->Imax < Train->mvControlled->ImaxHi) && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
@@ -2119,9 +2159,16 @@ void TTrain::OnCommand_headlighttoggleleft( TTrain *Train, command_data const &C
|
||||
0 :
|
||||
1 );
|
||||
|
||||
bool current_state = (bool)(Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_left);
|
||||
|
||||
if (Command.desired_state == command_data::ON && current_state)
|
||||
return;
|
||||
if (Command.desired_state == command_data::OFF && !current_state)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_left ) == 0 ) {
|
||||
if( !current_state ) {
|
||||
// turn on
|
||||
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left;
|
||||
// visual feedback
|
||||
@@ -2152,9 +2199,16 @@ void TTrain::OnCommand_headlighttoggleright( TTrain *Train, command_data const &
|
||||
0 :
|
||||
1 );
|
||||
|
||||
bool current_state = (bool)(Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_right);
|
||||
|
||||
if (Command.desired_state == command_data::ON && current_state)
|
||||
return;
|
||||
if (Command.desired_state == command_data::OFF && !current_state)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_right ) == 0 ) {
|
||||
if( !current_state ) {
|
||||
// turn on
|
||||
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right;
|
||||
// visual feedback
|
||||
@@ -2185,9 +2239,16 @@ void TTrain::OnCommand_headlighttoggleupper( TTrain *Train, command_data const &
|
||||
0 :
|
||||
1 );
|
||||
|
||||
bool current_state = (bool)(Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_upper);
|
||||
|
||||
if (Command.desired_state == command_data::ON && current_state)
|
||||
return;
|
||||
if (Command.desired_state == command_data::OFF && !current_state)
|
||||
return;
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_upper ) == 0 ) {
|
||||
if( !current_state ) {
|
||||
// turn on
|
||||
Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_upper;
|
||||
// visual feedback
|
||||
@@ -2452,6 +2513,11 @@ void TTrain::OnCommand_headlightsdimtoggle( TTrain *Train, command_data const &C
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->DynamicObject->DimHeadlights && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
if (!Train->DynamicObject->DimHeadlights && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
|
||||
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->DynamicObject->DimHeadlights ) {
|
||||
@@ -2509,6 +2575,11 @@ void TTrain::OnCommand_interiorlightdimtoggle( TTrain *Train, command_data const
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->bCabLightDim && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
if (!Train->bCabLightDim && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
|
||||
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->bCabLightDim ) {
|
||||
@@ -2564,6 +2635,11 @@ void TTrain::OnCommand_heatingtoggle( TTrain *Train, command_data const &Command
|
||||
return;
|
||||
}
|
||||
|
||||
if (Train->mvControlled->Heating && Command.desired_state == command_data::ON)
|
||||
return;
|
||||
if (!Train->mvControlled->Heating && Command.desired_state == command_data::OFF)
|
||||
return;
|
||||
|
||||
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 ) {
|
||||
@@ -3719,20 +3795,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
/// skakanie zapewnia mechanika
|
||||
/// napędu
|
||||
}
|
||||
|
||||
if (Global::bMWDmasterEnable) // pobieranie danych dla pulpitu port (COM)
|
||||
{
|
||||
Console::ValueSet(0, mvOccupied->Compressor); // zbiornik główny
|
||||
Console::ValueSet(1, mvOccupied->PipePress); // przewód główny
|
||||
Console::ValueSet(2, mvOccupied->BrakePress); // cylinder hamulcowy
|
||||
Console::ValueSet(3, fHVoltage); // woltomierz wysokiego napięcia
|
||||
Console::ValueSet(4, fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]);
|
||||
// pierwszy amperomierz; dla EZT prąd całkowity
|
||||
Console::ValueSet(5, fHCurrent[2]); // drugi amperomierz 2
|
||||
Console::ValueSet(6, fHCurrent[3]); // drugi amperomierz 3
|
||||
Console::ValueSet(7, fTachoVelocity);
|
||||
//Console::ValueSet(8, mvControlled->BatteryVoltage); // jeszcze nie pora ;)
|
||||
}
|
||||
#endif
|
||||
|
||||
// hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia
|
||||
@@ -4654,7 +4716,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
#ifdef _WIN32
|
||||
if (DynamicObject->Mechanik ?
|
||||
(DynamicObject->Mechanik->AIControllFlag ? false :
|
||||
(Global::iFeedbackMode == 4 || (Global::bMWDmasterEnable && Global::bMWDBreakEnable))) :
|
||||
(Global::iFeedbackMode == 4)) :
|
||||
false) // nie blokujemy AI
|
||||
{ // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba
|
||||
// Firleju: dlatego kasujemy i zastepujemy funkcją w Console
|
||||
@@ -4663,7 +4725,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
double b = Console::AnalogCalibrateGet(0);
|
||||
b = b * 8.0 - 2.0;
|
||||
b = clamp<double>( b, -2.0, mvOccupied->BrakeCtrlPosNo ); // przycięcie zmiennej do granic
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("FV4a break position = " + to_string(b));
|
||||
ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia
|
||||
mvOccupied->BrakeLevelSet(b);
|
||||
}
|
||||
@@ -4672,7 +4733,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
double b = Console::AnalogCalibrateGet(0);
|
||||
b = b * 7.0 - 1.0;
|
||||
b = clamp<double>( b, -1.0, mvOccupied->BrakeCtrlPosNo ); // przycięcie zmiennej do granic
|
||||
if (Global::bMWDdebugEnable && Global::iMWDDebugMode & 4) WriteLog("FVel6 break position = " + to_string(b));
|
||||
ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia
|
||||
mvOccupied->BrakeLevelSet(b);
|
||||
}
|
||||
@@ -4690,8 +4750,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
if( ( DynamicObject->Mechanik != nullptr )
|
||||
&& ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI
|
||||
&& ( mvOccupied->BrakeLocHandle == FD1 )
|
||||
&& ( ( Global::iFeedbackMode == 4 )
|
||||
|| ( Global::bMWDmasterEnable && Global::bMWDBreakEnable ) ) ) {
|
||||
&& ( ( Global::iFeedbackMode == 4 ) ) ) {
|
||||
// Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba
|
||||
// Firleju: dlatego kasujemy i zastepujemy funkcją w Console
|
||||
auto const b = clamp<double>(
|
||||
@@ -4700,10 +4759,6 @@ bool TTrain::Update( double const Deltatime )
|
||||
ManualBrakePosNo );
|
||||
ggLocalBrake.UpdateValue( b ); // przesów bez zaokrąglenia
|
||||
mvOccupied->LocalBrakePos = int( 1.09 * b ); // sposób zaokrąglania jest do ustalenia
|
||||
if( ( true == Global::bMWDdebugEnable )
|
||||
&& ( ( Global::iMWDDebugMode & 4 ) != 0 ) ) {
|
||||
WriteLog( "FD1 break position = " + to_string( b ) );
|
||||
}
|
||||
}
|
||||
else // standardowa prodedura z kranem powiązanym z klawiaturą
|
||||
#endif
|
||||
@@ -7419,3 +7474,75 @@ TTrain::play_sound( sound* Sound, sound* Fallbacksound, float gain ) {
|
||||
play_sound( Fallbacksound, gain );
|
||||
}
|
||||
|
||||
float TTrain::get_tacho()
|
||||
{
|
||||
return fTachoVelocity;
|
||||
}
|
||||
|
||||
float TTrain::get_tank_pressure()
|
||||
{
|
||||
return mvOccupied->Compressor;
|
||||
}
|
||||
|
||||
float TTrain::get_pipe_pressure()
|
||||
{
|
||||
return mvOccupied->PipePress;
|
||||
}
|
||||
|
||||
float TTrain::get_brake_pressure()
|
||||
{
|
||||
return mvOccupied->BrakePress;
|
||||
}
|
||||
|
||||
float TTrain::get_hv_voltage()
|
||||
{
|
||||
return fHVoltage;
|
||||
}
|
||||
|
||||
std::array<float, 3> TTrain::get_current()
|
||||
{
|
||||
return { fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1], fHCurrent[2], fHCurrent[3] };
|
||||
}
|
||||
|
||||
bool TTrain::get_alarm()
|
||||
{
|
||||
return (TestFlag(mvOccupied->SecuritySystem.Status, s_CAalarm) ||
|
||||
TestFlag(mvOccupied->SecuritySystem.Status, s_SHPalarm));
|
||||
}
|
||||
|
||||
void TTrain::set_mainctrl(int pos)
|
||||
{
|
||||
if (pos < mvControlled->MainCtrlPos)
|
||||
mvControlled->DecMainCtrl(1);
|
||||
else if (pos > mvControlled->MainCtrlPos)
|
||||
mvControlled->IncMainCtrl(1);
|
||||
}
|
||||
|
||||
void TTrain::set_scndctrl(int pos)
|
||||
{
|
||||
if (pos < mvControlled->ScndCtrlPos)
|
||||
mvControlled->DecScndCtrl(1);
|
||||
else if (pos > mvControlled->ScndCtrlPos)
|
||||
mvControlled->IncScndCtrl(1);
|
||||
}
|
||||
|
||||
void TTrain::set_trainbrake(float val)
|
||||
{
|
||||
val = std::min(1.0f, std::max(0.0f, val));
|
||||
float min = mvControlled->Handle->GetPos(bh_MIN);
|
||||
float max = mvControlled->Handle->GetPos(bh_MAX);
|
||||
mvControlled->BrakeLevelSet(min + val * (max - min));
|
||||
}
|
||||
|
||||
void TTrain::set_localbrake(float val)
|
||||
{
|
||||
val = std::min(1.0f, std::max(0.0f, val));
|
||||
float min = 0.0f;
|
||||
float max = (float)LocalBrakePosNo;
|
||||
mvControlled->LocalBrakePos = std::round(min + val * (max - min));
|
||||
}
|
||||
|
||||
int TTrain::get_drive_direction()
|
||||
{
|
||||
return mvOccupied->ActiveDir * mvOccupied->CabNo;
|
||||
}
|
||||
|
||||
14
Train.h
14
Train.h
@@ -493,5 +493,19 @@ public: // reszta może by?publiczna
|
||||
inline TMoverParameters *Controlled() { return mvControlled; };
|
||||
void DynamicSet(TDynamicObject *d);
|
||||
void Silence();
|
||||
|
||||
float get_tacho();
|
||||
float get_tank_pressure();
|
||||
float get_pipe_pressure();
|
||||
float get_brake_pressure();
|
||||
float get_hv_voltage();
|
||||
std::array<float, 3> get_current();
|
||||
bool get_alarm();
|
||||
int get_drive_direction();
|
||||
|
||||
void set_mainctrl(int);
|
||||
void set_scndctrl(int);
|
||||
void set_trainbrake(float);
|
||||
void set_localbrake(float);
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -1052,6 +1052,7 @@ bool TWorld::Update()
|
||||
|
||||
Ground.CheckQuery();
|
||||
|
||||
Ground.Update_Hidden();
|
||||
Ground.Update_Lights();
|
||||
|
||||
{
|
||||
@@ -1059,10 +1060,7 @@ bool TWorld::Update()
|
||||
Camera.SetMatrix(cam_matrix);
|
||||
|
||||
glm::vec3 pos(Camera.Pos.x, Camera.Pos.y, Camera.Pos.z);
|
||||
glm::vec3 at = glm::vec3(0.0, 0.0, -1.0) * glm::mat3(cam_matrix);
|
||||
glm::vec3 up = glm::vec3(0.0, 1.0, 0.0) * glm::mat3(cam_matrix);
|
||||
|
||||
sound_man->set_listener(pos, at, up);
|
||||
sound_man->set_listener(pos, glm::mat3(cam_matrix));
|
||||
sound_man->update(dt);
|
||||
}
|
||||
|
||||
|
||||
3
World.h
3
World.h
@@ -108,8 +108,7 @@ TWorld();
|
||||
void OnCommandGet(DaneRozkaz *pRozkaz);
|
||||
bool Update();
|
||||
void TrainDelete(TDynamicObject *d = NULL);
|
||||
TTrain const *
|
||||
train() const { return Train; }
|
||||
TTrain* train() { return Train; }
|
||||
// switches between static and dynamic daylight calculation
|
||||
void ToggleDaylight();
|
||||
|
||||
|
||||
@@ -17,5 +17,7 @@ cmake ../.. -T v140_xp ^
|
||||
-DLIBSNDFILE_INCLUDE_DIR=%DEPS_DIR%/libsndfile/include ^
|
||||
-DLIBSNDFILE_LIBRARY=%DEPS_DIR%/libsndfile/lib/win32/libsndfile-1.lib ^
|
||||
-DLUAJIT_INCLUDE_DIR=%DEPS_DIR%/luajit/include ^
|
||||
-DLUAJIT_LIBRARIES=%DEPS_DIR%/luajit/lib/win32/lua51.lib
|
||||
-DLUAJIT_LIBRARIES=%DEPS_DIR%/luajit/lib/win32/lua51.lib ^
|
||||
-Dlibserialport_INCLUDE_DIR=%DEPS_DIR%/libserialport/include ^
|
||||
-Dlibserialport_LIBRARY=%DEPS_DIR%/libserialport/lib/win32/libserialport-0.lib
|
||||
popd
|
||||
23
builds/cmake_win64.bat
Normal file
23
builds/cmake_win64.bat
Normal file
@@ -0,0 +1,23 @@
|
||||
if not exist deps_win call %~dp0download_windeps.bat
|
||||
set DEPS_DIR="%cd%/deps_win"
|
||||
if not exist build_win64 mkdir build_win64
|
||||
pushd build_win64
|
||||
cmake ../.. -A x64 ^
|
||||
-DGLEW_INCLUDE_DIR=%DEPS_DIR%/glew-2.0.0/include ^
|
||||
-DGLEW_LIBRARY=%DEPS_DIR%/glew-2.0.0/lib/Release/x64/glew32.lib ^
|
||||
-DGLFW3_ROOT_PATH=%DEPS_DIR%/glfw-3.2.1.bin.WIN64 ^
|
||||
-DGLUT_INCLUDE_DIR=%DEPS_DIR%/freeglut/include ^
|
||||
-DGLUT_glut_LIBRARY=%DEPS_DIR%/freeglut/lib/x64/freeglut.lib ^
|
||||
-DPNG_PNG_INCLUDE_DIR=%DEPS_DIR%/libpng/include ^
|
||||
-DPNG_LIBRARY=%DEPS_DIR%/libpng/lib/win64/libpng16.lib ^
|
||||
-DZLIB_INCLUDE_DIR=%DEPS_DIR%/zlib-1.2.11 ^
|
||||
-DGLM_ROOT_DIR=%DEPS_DIR%/glm-0.9.8.4 ^
|
||||
-DOPENAL_INCLUDE_DIR=%DEPS_DIR%/openal/include ^
|
||||
-DOPENAL_LIBRARY=%DEPS_DIR%/openal/lib/win64/OpenAL32.lib ^
|
||||
-DLIBSNDFILE_INCLUDE_DIR=%DEPS_DIR%/libsndfile/include ^
|
||||
-DLIBSNDFILE_LIBRARY=%DEPS_DIR%/libsndfile/lib/win64/libsndfile-1.lib ^
|
||||
-DLUAJIT_INCLUDE_DIR=%DEPS_DIR%/luajit/include ^
|
||||
-DLUAJIT_LIBRARIES=%DEPS_DIR%/luajit/lib/win64/lua51.lib ^
|
||||
-Dlibserialport_INCLUDE_DIR=%DEPS_DIR%/libserialport/include ^
|
||||
-Dlibserialport_LIBRARY=%DEPS_DIR%/libserialport/lib/win64/libserialport-0.lib
|
||||
popd
|
||||
2
builds/download_windeps.bat
Normal file
2
builds/download_windeps.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
powershell "$wc = New-Object System.Net.WebClient; $wc.DownloadFile(\"https://milek7.pl/.stuff/eu07exe/builddep4.zip\", \"%cd%\deps_win.zip\")"
|
||||
powershell "$s = New-Object -ComObject shell.application; $z = $s.Namespace(\"%cd%\deps_win.zip\"); foreach ($i in $z.items()) { $s.Namespace(\"%cd%\").CopyHere($i) }"
|
||||
@@ -174,7 +174,9 @@ command_queue::pop( command_data &Command, std::size_t const Recipient ) {
|
||||
}
|
||||
|
||||
void
|
||||
command_relay::post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2, int const Action, std::uint16_t const Recipient ) const {
|
||||
command_relay::post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2,
|
||||
int const Action, std::uint16_t const Recipient,
|
||||
command_data::desired_state_t state) const {
|
||||
|
||||
auto const &command = simulation::Commands_descriptions[ static_cast<std::size_t>( Command ) ];
|
||||
if( ( command.target == command_target::vehicle )
|
||||
@@ -191,7 +193,7 @@ command_relay::post( user_command const Command, std::uint64_t const Param1, std
|
||||
Action,
|
||||
Param1,
|
||||
Param2,
|
||||
Timer::GetDeltaTime() },
|
||||
state, Timer::GetDeltaTime() },
|
||||
static_cast<std::size_t>( command.target ) | Recipient );
|
||||
/*
|
||||
#ifdef _DEBUG
|
||||
|
||||
11
command.h
11
command.h
@@ -169,6 +169,13 @@ struct command_data {
|
||||
int action; // press, repeat or release
|
||||
std::uint64_t param1;
|
||||
std::uint64_t param2;
|
||||
enum desired_state_t
|
||||
{
|
||||
TOGGLE,
|
||||
OFF,
|
||||
ON
|
||||
};
|
||||
desired_state_t desired_state;
|
||||
double time_delta;
|
||||
};
|
||||
|
||||
@@ -218,7 +225,9 @@ public:
|
||||
// posts specified command for the specified recipient
|
||||
// TODO: replace uint16_t with recipient handle, based on item id
|
||||
void
|
||||
post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2, int const Action, std::uint16_t const Recipient ) const;
|
||||
post( user_command const Command, std::uint64_t const Param1, std::uint64_t const Param2,
|
||||
int const Action, std::uint16_t const Recipient,
|
||||
command_data::desired_state_t state = command_data::TOGGLE ) const;
|
||||
private:
|
||||
// types
|
||||
// members
|
||||
|
||||
9
dumb3d.h
9
dumb3d.h
@@ -118,6 +118,10 @@ class vector3
|
||||
return true;
|
||||
};
|
||||
|
||||
operator glm::vec3() const
|
||||
{
|
||||
return glm::vec3(x, y, z);
|
||||
}
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -208,6 +212,11 @@ class matrix4x4
|
||||
return true;
|
||||
}
|
||||
|
||||
operator glm::mat4() const
|
||||
{
|
||||
return glm::make_mat4(e);
|
||||
}
|
||||
|
||||
private:
|
||||
scalar_t e[16];
|
||||
};
|
||||
|
||||
1714
ref/libserialport/include/libserialport.h
Normal file
1714
ref/libserialport/include/libserialport.h
Normal file
File diff suppressed because it is too large
Load Diff
BIN
ref/libserialport/lib/win32/libserialport-0.lib
Normal file
BIN
ref/libserialport/lib/win32/libserialport-0.lib
Normal file
Binary file not shown.
BIN
ref/libserialport/lib/win64/libserialport-0.lib
Normal file
BIN
ref/libserialport/lib/win64/libserialport-0.lib
Normal file
Binary file not shown.
27
renderer.cpp
27
renderer.cpp
@@ -1345,19 +1345,6 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
|
||||
m_drawqueue.clear();
|
||||
|
||||
switch( m_renderpass.draw_mode ) {
|
||||
case rendermode::color: {
|
||||
// rednerowanie globalnych (nie za często?)
|
||||
for( TGroundNode *node = Ground->srGlobal.nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 const cameraposition { m_renderpass.camera.position() };
|
||||
int const camerax = static_cast<int>( std::floor( cameraposition.x / 1000.0f ) + iNumRects / 2 );
|
||||
int const cameraz = static_cast<int>( std::floor( cameraposition.z / 1000.0f ) + iNumRects / 2 );
|
||||
@@ -1374,20 +1361,6 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
for( int row = originz; row <= originz + segmentcount; ++row ) {
|
||||
|
||||
auto *cell = &Ground->Rects[ column ][ row ];
|
||||
|
||||
for( int subcellcolumn = 0; subcellcolumn < iNumSubRects; ++subcellcolumn ) {
|
||||
for( int subcellrow = 0; subcellrow < iNumSubRects; ++subcellrow ) {
|
||||
auto subcell = cell->FastGetSubRect( subcellcolumn, subcellrow );
|
||||
if( subcell == nullptr ) { continue; }
|
||||
// renderowanie obiektów aktywnych a niewidocznych
|
||||
for( auto node = subcell->nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
// jeszcze dźwięki pojazdów by się przydały, również niewidocznych
|
||||
subcell->RenderSounds();
|
||||
}
|
||||
}
|
||||
|
||||
if( m_renderpass.camera.visible( cell->m_area ) ) {
|
||||
Render( cell );
|
||||
}
|
||||
|
||||
53
sound.cpp
53
sound.cpp
@@ -259,28 +259,26 @@ void sound_manager::update(float dt)
|
||||
}
|
||||
}
|
||||
|
||||
void sound_manager::set_listener(glm::vec3 const &p, glm::vec3 const &at, glm::vec3 const &up)
|
||||
void sound_manager::set_listener(glm::vec3 const &p, glm::mat3 const &r)
|
||||
{
|
||||
pos = p;
|
||||
alListenerfv(AL_POSITION, glm::value_ptr(p));
|
||||
rot = r;
|
||||
glm::vec3 at = glm::vec3(0.0, 0.0, -1.0) * r;
|
||||
glm::vec3 up = glm::vec3(0.0, 1.0, 0.0) * r;
|
||||
|
||||
alListenerfv(AL_POSITION, glm::value_ptr(pos));
|
||||
glm::vec3 ori[] = { at, up };
|
||||
alListenerfv(AL_ORIENTATION, (ALfloat*)ori);
|
||||
}
|
||||
|
||||
void sound_manager::set_listener(Math3D::vector3 const &p, Math3D::vector3 const &at, Math3D::vector3 const &up)
|
||||
{
|
||||
set_listener((glm::vec3)glm::make_vec3(&p.x), (glm::vec3)glm::make_vec3(&at.x), (glm::vec3)glm::make_vec3(&up.x));
|
||||
}
|
||||
|
||||
sound::sound()
|
||||
{
|
||||
id = 0;
|
||||
alGenSources(1, &id);
|
||||
if (!id)
|
||||
throw std::runtime_error("sound: cannot generate source");
|
||||
alSourcei(id, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
dist(5.0f * 3.82f);
|
||||
spatial = false;
|
||||
set_mode(global);
|
||||
gain_off = 0.0f;
|
||||
gain_mul = 1.0f;
|
||||
pitch_off = 0.0f;
|
||||
@@ -288,6 +286,18 @@ sound::sound()
|
||||
dt_sum = 0.0f;
|
||||
}
|
||||
|
||||
sound& sound::set_mode(mode_t m)
|
||||
{
|
||||
mode = m;
|
||||
|
||||
if (mode == global || mode == anchored)
|
||||
alSourcei(id, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
else if (mode == spatial)
|
||||
alSourcei(id, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
simple_sound::simple_sound(sound_buffer *buf) : sound::sound()
|
||||
{
|
||||
looping = false;
|
||||
@@ -308,22 +318,25 @@ simple_sound::~simple_sound()
|
||||
buffer->unref();
|
||||
}
|
||||
|
||||
sound& sound::position(glm::vec3 const &p)
|
||||
sound& sound::position(glm::vec3 p)
|
||||
{
|
||||
if (!spatial)
|
||||
if (mode == global)
|
||||
{
|
||||
alSourcei(id, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
spatial = true;
|
||||
set_mode(spatial);
|
||||
last_pos = p;
|
||||
}
|
||||
|
||||
if (p != pos)
|
||||
if (p != pos || mode == anchored)
|
||||
{
|
||||
pos = p;
|
||||
pos_dirty = true;
|
||||
|
||||
if (mode == anchored)
|
||||
p = (p - sound_man->pos) * glm::inverse(sound_man->rot);
|
||||
|
||||
alSourcefv(id, AL_POSITION, glm::value_ptr(p));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -343,7 +356,7 @@ sound& sound::dist(float dist)
|
||||
|
||||
void simple_sound::play()
|
||||
{
|
||||
if (playing || (spatial && glm::distance(pos, sound_man->pos) > max_dist))
|
||||
if (playing || (mode != global && glm::distance(pos, sound_man->pos) > max_dist))
|
||||
return;
|
||||
|
||||
alSourcePlay(id);
|
||||
@@ -361,9 +374,9 @@ void simple_sound::stop()
|
||||
|
||||
void sound::update(float dt)
|
||||
{
|
||||
if (spatial)
|
||||
if (mode == spatial)
|
||||
dt_sum += dt;
|
||||
if (spatial && pos_dirty)
|
||||
if (mode == spatial && pos_dirty)
|
||||
{
|
||||
glm::vec3 velocity = (pos - last_pos) / dt_sum; // m/s
|
||||
alSourcefv(id, AL_VELOCITY, glm::value_ptr(velocity));
|
||||
@@ -383,7 +396,7 @@ void simple_sound::update(float dt)
|
||||
alGetSourcei(id, AL_SOURCE_STATE, &v);
|
||||
if (v != AL_PLAYING)
|
||||
playing = false;
|
||||
else if (spatial && glm::distance(pos, sound_man->pos) > max_dist)
|
||||
else if (mode != global && glm::distance(pos, sound_man->pos) > max_dist)
|
||||
stop();
|
||||
}
|
||||
}
|
||||
@@ -464,7 +477,7 @@ void complex_sound::play()
|
||||
if (cs != state::post)
|
||||
return;
|
||||
|
||||
if (spatial && glm::distance(pos, sound_man->pos) > max_dist)
|
||||
if (mode != global && glm::distance(pos, sound_man->pos) > max_dist)
|
||||
return;
|
||||
|
||||
alSourceRewind(id);
|
||||
@@ -554,7 +567,7 @@ void complex_sound::update(float dt)
|
||||
}
|
||||
|
||||
if (cs == state::main)
|
||||
if (spatial && glm::distance(pos, sound_man->pos) > max_dist)
|
||||
if (mode != global && glm::distance(pos, sound_man->pos) > max_dist)
|
||||
{
|
||||
shut_by_dist = true;
|
||||
stop();
|
||||
|
||||
17
sound.h
17
sound.h
@@ -45,9 +45,17 @@ class sound
|
||||
glm::vec3 last_pos;
|
||||
float dt_sum;
|
||||
|
||||
public:
|
||||
enum mode_t
|
||||
{
|
||||
global,
|
||||
spatial,
|
||||
anchored
|
||||
};
|
||||
|
||||
protected:
|
||||
float max_dist;
|
||||
bool spatial;
|
||||
mode_t mode;
|
||||
glm::vec3 pos;
|
||||
int samplerate;
|
||||
|
||||
@@ -68,12 +76,13 @@ public:
|
||||
virtual void stop() = 0;
|
||||
virtual void update(float dt);
|
||||
|
||||
sound& set_mode(mode_t);
|
||||
sound& dist(float);
|
||||
sound& gain(float);
|
||||
sound& pitch(float);
|
||||
virtual sound& loop(bool loop = true) = 0;
|
||||
|
||||
sound& position(glm::vec3 const &);
|
||||
sound& position(glm::vec3);
|
||||
sound& position(Math3D::vector3 const &);
|
||||
};
|
||||
|
||||
@@ -155,6 +164,7 @@ class sound_manager
|
||||
|
||||
public:
|
||||
glm::vec3 pos, last_pos;
|
||||
glm::mat3 rot;
|
||||
|
||||
sound_manager();
|
||||
~sound_manager();
|
||||
@@ -166,8 +176,7 @@ public:
|
||||
void destroy_sound(sound**);
|
||||
|
||||
void update(float dt);
|
||||
void set_listener(glm::vec3 const &pos, glm::vec3 const &at, glm::vec3 const &up);
|
||||
void set_listener(Math3D::vector3 const &pos, Math3D::vector3 const &at, Math3D::vector3 const &up);
|
||||
void set_listener(glm::vec3 const &pos, glm::mat3 const &rot);
|
||||
};
|
||||
|
||||
extern std::unique_ptr<sound_manager> sound_man;
|
||||
|
||||
173
uart.cpp
Normal file
173
uart.cpp
Normal file
@@ -0,0 +1,173 @@
|
||||
#include "stdafx.h"
|
||||
#include "uart.h"
|
||||
#include "Globals.h"
|
||||
#include "World.h"
|
||||
#include "Train.h"
|
||||
#include "Logs.h"
|
||||
|
||||
uart_input::uart_input()
|
||||
{
|
||||
conf = Global::uart_conf;
|
||||
|
||||
if (sp_get_port_by_name(conf.port.c_str(), &port) != SP_OK)
|
||||
throw std::runtime_error("uart: cannot find specified port");
|
||||
|
||||
if (sp_open(port, SP_MODE_READ_WRITE) != SP_OK)
|
||||
throw std::runtime_error("uart: cannot open port");
|
||||
|
||||
if (sp_set_baudrate(port, conf.baud) != SP_OK)
|
||||
throw std::runtime_error("uart: cannot set baudrate");
|
||||
|
||||
if (sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE) != SP_OK)
|
||||
throw std::runtime_error("uart: cannot set flowcontrol");
|
||||
|
||||
if (sp_flush(port, SP_BUF_BOTH) != SP_OK)
|
||||
throw std::runtime_error("uart: cannot flush");
|
||||
|
||||
old_packet.fill(0);
|
||||
last_update = std::chrono::high_resolution_clock::now();
|
||||
}
|
||||
|
||||
uart_input::~uart_input()
|
||||
{
|
||||
sp_close(port);
|
||||
sp_free_port(port);
|
||||
}
|
||||
|
||||
#define SPLIT_INT16(x) (uint8_t)x, (uint8_t)(x >> 8)
|
||||
|
||||
void uart_input::poll()
|
||||
{
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
if (std::chrono::duration<float>(now - last_update).count() < conf.updatetime)
|
||||
return;
|
||||
last_update = now;
|
||||
|
||||
TTrain *t = Global::pWorld->train();
|
||||
|
||||
sp_return ret;
|
||||
|
||||
if (sp_input_waiting(port) >= 16)
|
||||
{
|
||||
std::array<uint8_t, 16> buffer;
|
||||
ret = sp_blocking_read(port, (void*)buffer.data(), buffer.size(), 0);
|
||||
if (ret < 0)
|
||||
throw std::runtime_error("uart: failed to read from port");
|
||||
|
||||
sp_drain(port);
|
||||
data_pending = false;
|
||||
|
||||
for (auto entry : input_bits)
|
||||
{
|
||||
input_type_t type = std::get<2>(entry);
|
||||
|
||||
size_t byte = std::get<0>(entry) / 8;
|
||||
size_t bit = std::get<0>(entry) % 8;
|
||||
|
||||
bool state = (bool)(buffer[byte] & (1 << bit));
|
||||
|
||||
bool repeat = (type == impulse_r ||
|
||||
type == impulse_r_off ||
|
||||
type == impulse_r_on);
|
||||
|
||||
bool changed = (state != (bool)(old_packet[byte] & (1 << bit)));
|
||||
|
||||
if (!changed && !(repeat && state))
|
||||
continue;
|
||||
|
||||
int action;
|
||||
command_data::desired_state_t desired_state;
|
||||
|
||||
if (type == toggle)
|
||||
{
|
||||
action = GLFW_PRESS;
|
||||
desired_state = state ? command_data::ON : command_data::OFF;
|
||||
}
|
||||
else if (type == impulse_r_on)
|
||||
{
|
||||
action = state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE;
|
||||
desired_state = command_data::ON;
|
||||
}
|
||||
else if (type == impulse_r_off)
|
||||
{
|
||||
action = state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE;
|
||||
desired_state = command_data::OFF;
|
||||
}
|
||||
else if (type == impulse || type == impulse_r)
|
||||
{
|
||||
action = state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE;
|
||||
desired_state = command_data::TOGGLE;
|
||||
}
|
||||
|
||||
relay.post(std::get<1>(entry), 0, 0, action, 0, desired_state);
|
||||
}
|
||||
|
||||
int mainctrl = buffer[6];
|
||||
int scndctrl = buffer[7];
|
||||
float trainbrake = (float)(((uint16_t)buffer[8] | ((uint16_t)buffer[9] << 8)) - conf.mainbrakemin) / (conf.mainbrakemax - conf.mainbrakemin);
|
||||
float localbrake = (float)(((uint16_t)buffer[10] | ((uint16_t)buffer[11] << 8)) - conf.mainbrakemin) / (conf.localbrakemax - conf.localbrakemin);
|
||||
|
||||
t->set_mainctrl(mainctrl);
|
||||
t->set_scndctrl(scndctrl);
|
||||
t->set_trainbrake(trainbrake);
|
||||
t->set_localbrake(localbrake);
|
||||
|
||||
old_packet = buffer;
|
||||
}
|
||||
|
||||
if (!data_pending && sp_output_waiting(port) == 0)
|
||||
{
|
||||
// TODO: ugly! move it into structure like input_bits
|
||||
|
||||
uint8_t buzzer = (uint8_t)t->get_alarm();
|
||||
uint8_t tacho = (uint8_t)t->get_tacho();
|
||||
uint16_t tank_press = (uint16_t)std::min(conf.tankuart, t->get_tank_pressure() / conf.tankmax * conf.tankuart);
|
||||
uint16_t pipe_press = (uint16_t)std::min(conf.pipeuart, t->get_pipe_pressure() / conf.pipemax * conf.pipeuart);
|
||||
uint16_t brake_press = (uint16_t)std::min(conf.brakeuart, t->get_brake_pressure() / conf.brakemax * conf.brakeuart);
|
||||
uint16_t hv_voltage = (uint16_t)std::min(conf.hvuart, t->get_hv_voltage() / conf.hvmax * conf.hvuart);
|
||||
auto current = t->get_current();
|
||||
uint16_t current1 = (uint16_t)std::min(conf.currentuart, current[0]) / conf.currentmax * conf.currentuart;
|
||||
uint16_t current2 = (uint16_t)std::min(conf.currentuart, current[1]) / conf.currentmax * conf.currentuart;
|
||||
uint16_t current3 = (uint16_t)std::min(conf.currentuart, current[2]) / conf.currentmax * conf.currentuart;
|
||||
|
||||
std::array<uint8_t, 31> buffer =
|
||||
{
|
||||
0, 0, //byte 0-1
|
||||
tacho, //byte 2
|
||||
0, 0, 0, 0, 0, 0, //byte 3-8
|
||||
SPLIT_INT16(brake_press), //byte 9-10
|
||||
SPLIT_INT16(pipe_press), //byte 11-12
|
||||
SPLIT_INT16(tank_press), //byte 13-14
|
||||
SPLIT_INT16(hv_voltage), //byte 15-16
|
||||
SPLIT_INT16(current1), //byte 17-18
|
||||
SPLIT_INT16(current2), //byte 19-20
|
||||
SPLIT_INT16(current3), //byte 21-22
|
||||
0, 0, 0, 0, 0, 0, 0, 0 //byte 23-30
|
||||
};
|
||||
|
||||
buffer[4] |= t->btLampkaOpory.b() << 1;
|
||||
buffer[4] |= t->btLampkaWysRozr.b() << 2;
|
||||
|
||||
buffer[6] |= t->btLampkaOgrzewanieSkladu.b() << 0;
|
||||
buffer[6] |= t->btLampkaOpory.b() << 1;
|
||||
buffer[6] |= t->btLampkaPoslizg.b() << 2;
|
||||
buffer[6] |= t->btLampkaCzuwaka.b() << 6;
|
||||
buffer[6] |= t->btLampkaSHP.b() << 7;
|
||||
|
||||
buffer[7] |= t->btLampkaStyczn.b() << 0;
|
||||
buffer[7] |= t->btLampkaNadmPrzetw.b() << 2;
|
||||
buffer[7] |= t->btLampkaNadmSil.b() << 4;
|
||||
buffer[7] |= t->btLampkaWylSzybki.b() << 5;
|
||||
buffer[7] |= t->btLampkaNadmSpr.b() << 6;
|
||||
|
||||
buffer[8] |= buzzer << 7;
|
||||
|
||||
sp_flush(port, SP_BUF_INPUT); // flush input buffer in preparation for reply packet
|
||||
|
||||
ret = sp_blocking_write(port, (void*)buffer.data(), buffer.size(), 0);
|
||||
if (ret != buffer.size())
|
||||
throw std::runtime_error("uart: failed to write to port");
|
||||
|
||||
data_pending = true;
|
||||
}
|
||||
}
|
||||
58
uart.h
Normal file
58
uart.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
#include <libserialport.h>
|
||||
#include "command.h"
|
||||
#include "Globals.h"
|
||||
|
||||
class uart_input
|
||||
{
|
||||
enum input_type_t
|
||||
{
|
||||
toggle,
|
||||
impulse,
|
||||
impulse_r,
|
||||
impulse_r_on,
|
||||
impulse_r_off
|
||||
};
|
||||
|
||||
std::array<std::tuple<size_t, user_command, input_type_t>, 23> input_bits =
|
||||
{
|
||||
std::make_tuple(1, user_command::linebreakertoggle, impulse_r_off),
|
||||
std::make_tuple(2, user_command::linebreakertoggle, impulse_r_on),
|
||||
std::make_tuple(3, user_command::motoroverloadrelayreset, impulse),
|
||||
std::make_tuple(5, user_command::converteroverloadrelayreset, impulse),
|
||||
std::make_tuple(6, user_command::motorconnectorsopen, toggle),
|
||||
std::make_tuple(7, user_command::alerteracknowledge, impulse_r),
|
||||
|
||||
std::make_tuple(9, user_command::convertertoggle, toggle),
|
||||
std::make_tuple(10, user_command::compressortoggle, toggle),
|
||||
std::make_tuple(11, user_command::sandboxactivate, impulse),
|
||||
std::make_tuple(12, user_command::heatingtoggle, toggle),
|
||||
|
||||
std::make_tuple(15, user_command::motoroverloadrelaythresholdtoggle, toggle),
|
||||
std::make_tuple(16, user_command::pantographtogglefront, toggle),
|
||||
std::make_tuple(17, user_command::pantographtogglerear, toggle),
|
||||
std::make_tuple(18, user_command::wheelspinbrakeactivate, impulse),
|
||||
std::make_tuple(19, user_command::headlightsdimtoggle, toggle),
|
||||
std::make_tuple(20, user_command::interiorlightdimtoggle, toggle),
|
||||
std::make_tuple(21, user_command::independentbrakebailoff, impulse),
|
||||
std::make_tuple(22, user_command::hornhighactivate, impulse),
|
||||
std::make_tuple(23, user_command::hornlowactivate, impulse),
|
||||
|
||||
std::make_tuple(24, user_command::batterytoggle, toggle),
|
||||
std::make_tuple(25, user_command::headlighttoggleleft, toggle),
|
||||
std::make_tuple(26, user_command::headlighttoggleupper, toggle),
|
||||
std::make_tuple(27, user_command::headlighttoggleright, toggle)
|
||||
};
|
||||
|
||||
sp_port *port = nullptr;
|
||||
command_relay relay;
|
||||
std::array<uint8_t, 16> old_packet;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> last_update;
|
||||
Global::uart_conf_t conf;
|
||||
bool data_pending = false;
|
||||
|
||||
public:
|
||||
uart_input();
|
||||
~uart_input();
|
||||
void poll();
|
||||
};
|
||||
Reference in New Issue
Block a user