diff --git a/.gitignore b/.gitignore index ec4a4f77e..5d458f212 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,15 @@ install_manifest.txt *.~h *.~bpr *.~pas +*.opensdf +*.sdf +*.sln +*.vcxproj +*.filters +format_all_files.py +MaSzyna.opensdf +MaSzyna.sdf +MaSzyna.sln +MaSzyna.vcxproj +MaSzyna.vcxproj.filters +*.suo diff --git a/AnimModel.cpp b/AnimModel.cpp index 56d2e4062..738c4dc5d 100644 --- a/AnimModel.cpp +++ b/AnimModel.cpp @@ -28,6 +28,7 @@ obtain one at //--------------------------------------------------------------------------- TAnimAdvanced::TAnimAdvanced(){}; + TAnimAdvanced::~TAnimAdvanced(){ // delete[] pVocaloidMotionData; //plik został zmodyfikowany }; @@ -530,7 +531,7 @@ bool TAnimModel::Load(cParser *parser, bool ter) return true; } -TAnimContainer *__fastcall TAnimModel::AddContainer(char *pName) +TAnimContainer * TAnimModel::AddContainer(char *pName) { // dodanie sterowania submodelem dla egzemplarza if (!pModel) return NULL; @@ -546,7 +547,7 @@ TAnimContainer *__fastcall TAnimModel::AddContainer(char *pName) return NULL; } -TAnimContainer *__fastcall TAnimModel::GetContainer(char *pName) +TAnimContainer * TAnimModel::GetContainer(char *pName) { // szukanie/dodanie sterowania submodelem dla egzemplarza if (!pName) return pRoot; // pobranie pierwszego (dla obrotnicy) @@ -690,7 +691,7 @@ int TAnimModel::TerrainCount() { // zliczanie kwadratów kilometrowych (główna linia po Next) do tworznia tablicy return pModel ? pModel->TerrainCount() : 0; }; -TSubModel *__fastcall TAnimModel::TerrainSquare(int n) +TSubModel * TAnimModel::TerrainSquare(int n) { // pobieranie wskaźników do pierwszego submodelu return pModel ? pModel->TerrainSquare(n) : 0; }; diff --git a/AnimModel.h b/AnimModel.h index adfe2c460..be8558812 100644 --- a/AnimModel.h +++ b/AnimModel.h @@ -80,7 +80,7 @@ class TAnimContainer // std::string(pSubModel?pSubModel->asName.c_str():""); }; // std::string inline GetName() { return std::string(pSubModel?pSubModel->pName:""); // }; - char *__fastcall NameGet() + char * NameGet() { return (pSubModel ? pSubModel->pName : NULL); }; @@ -107,7 +107,7 @@ class TAnimContainer pSubModel->WillBeAnimated(); }; void EventAssign(TEvent *ev); - TEvent *__fastcall Event() + TEvent * Event() { return evDone; }; @@ -156,8 +156,8 @@ class TAnimModel bool Init(TModel3d *pNewModel); bool Init(AnsiString asName, AnsiString asReplacableTexture); bool Load(cParser *parser, bool ter = false); - TAnimContainer *__fastcall AddContainer(char *pName); - TAnimContainer *__fastcall GetContainer(char *pName); + TAnimContainer * AddContainer(char *pName); + TAnimContainer * GetContainer(char *pName); void RenderDL(vector3 pPosition = vector3(0, 0, 0), double fAngle = 0); void RenderAlphaDL(vector3 pPosition = vector3(0, 0, 0), double fAngle = 0); void RenderVBO(vector3 pPosition = vector3(0, 0, 0), double fAngle = 0); @@ -175,7 +175,7 @@ class TAnimModel }; bool TerrainLoaded(); int TerrainCount(); - TSubModel *__fastcall TerrainSquare(int n); + TSubModel * TerrainSquare(int n); void TerrainRenderVBO(int n); void AnimationVND(void *pData, double a, double b, double c, double d); void LightSet(int n, float v); diff --git a/Button.cpp b/Button.cpp index 7b5f90c28..3f2f51b2c 100644 --- a/Button.cpp +++ b/Button.cpp @@ -21,6 +21,7 @@ obtain one at TButton::TButton() { iFeedbackBit = 0; + bData = NULL; Clear(); }; @@ -54,8 +55,8 @@ void TButton::Load(TQueryParserComp *Parser, TModel3d *pModel1, TModel3d *pModel Init(str, pModel1, false); if (pModel2) if (!pModelOn && !pModelOff) - Init(str, pModel2, - false); // może w drugim będzie (jak nie w kabinie, to w zewnętrznym) + Init(str, pModel2, false); // może w drugim będzie (jak nie w kabinie, + // to w zewnętrznym) } else { @@ -66,6 +67,8 @@ void TButton::Load(TQueryParserComp *Parser, TModel3d *pModel1, TModel3d *pModel void TButton::Update() { + if (bData != NULL) + bOn = (*bData); if (pModelOn) pModelOn->iVisible = bOn; if (pModelOff) @@ -78,3 +81,8 @@ void TButton::Update() Console::BitsClear(iFeedbackBit); } }; + +void TButton::AssignBool(bool *bValue) +{ + bData = bValue; +} diff --git a/Button.h b/Button.h index 013e0d616..a7dbffb50 100644 --- a/Button.h +++ b/Button.h @@ -14,12 +14,13 @@ obtain one at #include "QueryParserComp.hpp" class TButton -{ // animacja dwustanowa, włącza jeden z dwóch submodeli (jednego z nich może nie być) +{ // animacja dwustanowa, włącza jeden z dwóch submodeli (jednego + // z nich może nie być) private: TSubModel *pModelOn, *pModelOff; // submodel dla stanu załączonego i wyłączonego bool bOn; + bool *bData; int iFeedbackBit; // Ra: bit informacji zwrotnej, do wyprowadzenia na pulpit - void Update(); public: TButton(); @@ -53,8 +54,10 @@ class TButton { return (pModelOn) || (pModelOff); }; + void Update(); void Init(AnsiString asName, TModel3d *pModel, bool bNewOn = false); void Load(TQueryParserComp *Parser, TModel3d *pModel1, TModel3d *pModel2 = NULL); + void AssignBool(bool *bValue); }; //--------------------------------------------------------------------------- diff --git a/Classes.h b/Classes.h index 0de7a712c..90e875d1a 100644 --- a/Classes.h +++ b/Classes.h @@ -48,9 +48,11 @@ typedef enum { // binarne odpowiedniki komend w komórce pamięci cm_Unknown, // ciąg nierozpoznany (nie jest komendą) cm_Ready, // W4 zezwala na odjazd, ale semafor może zatrzymać - cm_SetVelocity, - cm_ShuntVelocity, - cm_SetProximityVelocity, + cm_SetVelocity, // prędkość pociągowa zadawana na semaforze + cm_RoadVelocity, // prędkość drogowa + cm_SectionVelocity, //ograniczenie prędkości na odcinku + cm_ShuntVelocity, // prędkość manewrowa na semaforze + cm_SetProximityVelocity, // informacja wstępna o ograniczeniu cm_ChangeDirection, cm_PassengerStopPoint, cm_OutsideStation, diff --git a/Console.cpp b/Console.cpp index f5d99f996..33b31275d 100644 --- a/Console.cpp +++ b/Console.cpp @@ -197,6 +197,8 @@ void Console::BitsSet(int mask, int entry) int old = iBits; // poprzednie stany iBits |= mask; BitsUpdate(old ^ iBits); // 1 dla bitów zmienionych + if (iMode == 4) + WriteLog("PoKeys::BitsSet: mask: " + AnsiString(mask) + " iBits: " + AnsiString(iBits)); } }; @@ -269,26 +271,52 @@ void Console::BitsUpdate(int mask) PoKeys55[0]->Write(0x40, 52 - 1, iBits & 0x1000 ? 1 : 0); if (mask & 0x2000) // b13 Prąd na silnikach do odbijania w haslerze PoKeys55[0]->Write(0x40, 53 - 1, iBits & 0x2000 ? 1 : 0); - } + if (mask & 0x4000) // b14 Brzęczyk SHP lub CA + PoKeys55[0]->Write(0x40, 16 - 1, iBits & 0x4000 ? 1 : 0); + } break; } }; bool Console::Pressed(int x) -{ +{ // na razie tak - czyta się tylko klawiatura return Global::bActive && (GetKeyState(x) < 0); -}; // na razie tak - czyta się tylko klawiatura +}; void Console::ValueSet(int x, double y) { // ustawienie wartości (y) na kanale analogowym (x) if (iMode == 4) if (PoKeys55[0]) { - PoKeys55[0]->PWM( - x, (((Global::fCalibrateOut[x][3] * y) + Global::fCalibrateOut[x][2]) * y + - Global::fCalibrateOut[x][1]) * - y + - Global::fCalibrateOut[x][0]); // zakres <0;1> + //if (x == 7) + //{ + // PoKeys55[0]->PoExtUpdate(8, y); + //} // nbmx: wal kulakowy + //else + //{ + if (Global::iCalibrateOutDebugInfo == x) + WriteLog("CalibrateOutDebugInfo: oryginal=" + AnsiString(y), false); + if (Global::fCalibrateOutMax[x] > 0) + { + y = Global::CutValueToRange(0, y, Global::fCalibrateOutMax[x]); + if (Global::iCalibrateOutDebugInfo == x) + WriteLog(" cutted=" + AnsiString(y),false); + y = y / Global::fCalibrateOutMax[x]; // sprowadzenie do <0,1> jeśli podana maksymalna wartość + if (Global::iCalibrateOutDebugInfo == x) + WriteLog(" fraction=" + AnsiString(y),false); + } + double temp = (((((Global::fCalibrateOut[x][5] * y) + Global::fCalibrateOut[x][4]) * y + + Global::fCalibrateOut[x][3]) * y + Global::fCalibrateOut[x][2]) * y + + Global::fCalibrateOut[x][1]) * y + + Global::fCalibrateOut[x][0]; // zakres <0;1> + if (Global::iCalibrateOutDebugInfo == x) + WriteLog(" calibrated=" + AnsiString(temp)); + PoKeys55[0]->PWM(x, temp); + //if (x == 6) + //{ + // PoKeys55[0]->PoExtUpdate(9, temp); //dodatkowo hasler na PoExt + //} + //} } }; @@ -317,6 +345,18 @@ float Console::AnalogGet(int x) return -1.0; }; +float Console::AnalogCalibrateGet(int x) +{ // pobranie i kalibracja wartości analogowej, jeśli nie ma PoKeys zwraca NULL + if (iMode == 4 && PoKeys55[0]) + { + float b = PoKeys55[0]->fAnalog[x]; + return (((((Global::fCalibrateIn[x][5] * b) + Global::fCalibrateIn[x][4]) * b + + Global::fCalibrateIn[x][3]) * b + Global::fCalibrateIn[x][2]) * b + + Global::fCalibrateIn[x][1]) *b + Global::fCalibrateIn[x][0]; + } + return -1.0; //odcięcie +}; + unsigned char Console::DigitalGet(int x) { // pobranie wartości cyfrowej if (iMode == 4) diff --git a/Console.h b/Console.h index 8fad4719f..500e9abf1 100644 --- a/Console.h +++ b/Console.h @@ -51,6 +51,7 @@ class Console static void ValueSet(int x, double y); static void Update(); static float AnalogGet(int x); + static float AnalogCalibrateGet(int x); static unsigned char DigitalGet(int x); static void OnKeyDown(int k); static void OnKeyUp(int k); diff --git a/Console/LPT.cpp b/Console/LPT.cpp index 5098af4e5..3cba85f8b 100644 --- a/Console/LPT.cpp +++ b/Console/LPT.cpp @@ -49,6 +49,6 @@ bool TLPT::Connect(int port) }; void TLPT::Out(int x) -{ +{ // wysłanie bajtu do portu OutPort(address, x); -}; // wysłanie bajtu do portu +}; diff --git a/Console/PoKeys55.cpp b/Console/PoKeys55.cpp index d816a7ee4..10aa9cefb 100644 --- a/Console/PoKeys55.cpp +++ b/Console/PoKeys55.cpp @@ -34,7 +34,8 @@ TPoKeys55::TPoKeys55() fAnalog[0] = fAnalog[1] = fAnalog[2] = fAnalog[3] = fAnalog[4] = fAnalog[5] = fAnalog[6] = -1.0; iPWM[0] = iPWM[1] = iPWM[2] = iPWM[3] = iPWM[4] = iPWM[5] = iPWM[6] = 0; iPWM[7] = 4096; - iInputs[0] = 0; // czy normalnie są w stanie wysokim? + PoExt[0] = PoExt[1] = PoExt[2] = PoExt[3] = PoExt[4] = PoExt[5] = PoExt[6] = PoExt[7] = PoExt[8] = PoExt[9] = PoExt[10] = 0; + iInputs[0] = 0; // czy normalnie są w stanie wysokim? iRepeats = 0; bNoError = true; }; @@ -229,6 +230,30 @@ bool TPoKeys55::Write(unsigned char c, unsigned char b3, unsigned char b4, unsig return (BytesWritten == 65); // Read(); //odczyt trzeba zrobić inaczej - w tym miejscu będzie za szybko i nic się nie odczyta } + +bool TPoKeys55::PoExtWrite(unsigned char *c) +{ + DWORD BytesWritten = 0; + OutputBuffer[0] = 0; //The first byte is the "Report ID" and does not get transmitted over the USB bus. Always set=0. + OutputBuffer[1] = 0xBB; //0xBB - bajt rozpoznawczy dla PoKeys55 + OutputBuffer[2] = iLastCommand = 0xDA; //operacja: 0xDA PoExt + OutputBuffer[3] = 1; //1 = enable PoExt + OutputBuffer[4] = 0; // Connector selection 0: dedicated , 1: normal pins + OutputBuffer[5] = 0; + OutputBuffer[6] = 0; + OutputBuffer[7] = ++cRequest; //numer żądania + OutputBuffer[8] = 0; + for (int i = 0; i<10; ++i) + OutputBuffer[9 + i] = c[i]; + for (int i = 0; i<8; ++i) + OutputBuffer[8] += OutputBuffer[i]; //czy sumować też od 9 do 64? + //The basic Windows I/O functions WriteFile() and ReadFile() can be used to read and write to HID class USB devices + //(once we have the read and write handles to the device, which are obtained with CreateFile()). + //The following call to WriteFile() sends 64 bytes of data to the USB device. + WriteFile(WriteHandle, &OutputBuffer, 65, &BytesWritten, 0); //Blocking function, unless an "overlapped" structure is used + return (BytesWritten == 65); + //Read(); //odczyt trzeba zrobić inaczej - w tym miejscu będzie za szybko i nic się nie odczyta +} //--------------------------------------------------------------------------- bool TPoKeys55::Read() @@ -297,6 +322,13 @@ bool TPoKeys55::PWM(int x, float y) return true; } +bool TPoKeys55::PoExtUpdate(int x, char y) +{//ustawienie wskazanego PWM (@12Mhz: 12000=1ms=1000Hz) + //iPWM[7]=1024; //1024==85333.3333333333ns=11718.75Hz + PoExt[x] = y & 0x0FF; //0x0FF=256 + return true; +} + bool TPoKeys55::Update(bool pause) { // funkcja powinna być wywoływana regularnie, np. raz w każdej ramce ekranowej if (pause) @@ -353,10 +385,15 @@ bool TPoKeys55::Update(bool pause) case 3: // ustawienie wyjść analogowych, 0..4095 mapować na 0..65520 (<<4) if (Write(0x41, 43 - 1, (iPWM[6] >> 4), (iPWM[6] << 4))) // wysłanie ustawień iRepeats = 0; // informacja, że poszło dobrze - iFaza = 0; //++iFaza; //ta faza została zakończona + iFaza = 4; //++iFaza; //ta faza została zakończona // powinno jeszcze przyjść potwierdzenie o kodzie 0x41 break; - default: + case 4: //ustawienie + //if (PoExtWrite(PoExt)) + // iRepeats = 0; //informacja, że poszło dobrze + iFaza = 0; //++iFaza; //ta faza została zakończona + break; + default: iFaza = 0; // na wypadek, gdyby zbłądziło po jakichś zmianach w kodzie // iRepeats=0; } diff --git a/Console/PoKeys55.h b/Console/PoKeys55.h index 9815deade..7b08ac05a 100644 --- a/Console/PoKeys55.h +++ b/Console/PoKeys55.h @@ -16,7 +16,8 @@ class TPoKeys55 unsigned char OutputBuffer[65]; // Allocate a memory buffer equal to our endpoint size + 1 unsigned char InputBuffer[65]; // Allocate a memory buffer equal to our endpoint size + 1 int iPWM[8]; // 0-5:wyjścia PWM,6:analogowe,7:częstotliwośc PWM - int iPWMbits; + char PoExt[10];// Wyjscia PoExt + int iPWMbits; int iLastCommand; int iFaza; int iRepeats; // liczba powtórzeń @@ -29,11 +30,13 @@ class TPoKeys55 bool Connect(); bool Close(); bool Write(unsigned char c, unsigned char b3, unsigned char b4 = 0, unsigned char b5 = 0); - bool Read(); + bool PoExtWrite(unsigned char *c); + bool Read(); bool ReadLoop(int i); AnsiString Version(); bool PWM(int x, float y); - bool Update(bool pause); + bool PoExtUpdate(int x, char y); + bool Update(bool pause); }; //--------------------------------------------------------------------------- #endif diff --git a/Curve.cpp b/Curve.cpp index 4d5f05762..d22ba1a2e 100644 --- a/Curve.cpp +++ b/Curve.cpp @@ -13,14 +13,14 @@ obtain one at #include "Curve.h" -__fastcall TCurve::TCurve() + TCurve::TCurve() { Values = NULL; iNumValues = 0; iNumCols = 0; } -__fastcall TCurve::~TCurve() + TCurve::~TCurve() { for (int i = 0; i < iNumValues; i++) SafeDelete(Values[i]); diff --git a/Dokumentacja zmiennych Python.docx b/Dokumentacja zmiennych Python.docx new file mode 100644 index 000000000..f421014b5 Binary files /dev/null and b/Dokumentacja zmiennych Python.docx differ diff --git a/Driver.cpp b/Driver.cpp index 1d640c9fa..cf5a91d11 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -112,6 +112,7 @@ void TSpeedPos::Clear() { iFlags = 0; // brak flag to brak reakcji fVelNext = -1.0; // prędkość bez ograniczeń + fSectionVelocityDist = 0.0; //brak długości fDist = 0.0; vPos = vector3(0, 0, 0); trTrack = NULL; // brak wskaźnika @@ -122,47 +123,65 @@ void TSpeedPos::CommandCheck() TCommandType command = evEvent->Command(); double value1 = evEvent->ValueGet(1); double value2 = evEvent->ValueGet(2); - if (command == cm_ShuntVelocity) - { // prędkość manewrową zapisać, najwyżej AI zignoruje przy analizie tabelki + switch (command) + { + case cm_ShuntVelocity: + // prędkość manewrową zapisać, najwyżej AI zignoruje przy analizie tabelki fVelNext = value1; // powinno być value2, bo druga określa "za"? - iFlags |= 0x200; - } - else if (command == cm_SetVelocity) - { // w semaforze typu "m" jest ShuntVelocity dla Ms2 i SetVelocity dla S1 + iFlags |= spShuntSemaphor; + break; + case cm_SetVelocity: + // w semaforze typu "m" jest ShuntVelocity dla Ms2 i SetVelocity dla S1 // SetVelocity * 0 -> można jechać, ale stanąć przed // SetVelocity 0 20 -> stanąć przed, potem można jechać 20 (SBL) // SetVelocity -1 100 -> można jechać, przy następnym ograniczenie (SBL) // SetVelocity 40 -1 -> PutValues: jechać 40 aż do minięcia (koniec ograniczenia( fVelNext = value1; - iFlags &= ~0xE00; // nie manewrowa, nie przystanek, nie zatrzymać na SBL + iFlags &= ~(spShuntSemaphor | spPassengerStopPoint | spStopOnSBL); + iFlags |= spSemaphor;// nie manewrowa, nie przystanek, nie zatrzymać na SBL, ale semafor if (value1 == 0.0) // jeśli pierwsza zerowa if (value2 != 0.0) // a druga nie { // S1 na SBL, można przejechać po zatrzymaniu (tu nie mamy prędkości ani odległości) fVelNext = value2; // normalnie będzie zezwolenie na jazdę, aby się usunął z tabelki - iFlags |= 0x800; // flaga, że ma zatrzymać; na pewno nie zezwoli na manewry + iFlags |= spStopOnSBL; // flaga, że ma zatrzymać; na pewno nie zezwoli na manewry } - } - else if (command == cm_PassengerStopPoint) // nie ma dostępu do rozkładu - { // przystanek, najwyżej AI zignoruje przy analizie tabelki - if ((iFlags & 0x400) == 0) + break; + case cm_SectionVelocity: + // odcinek z ograniczeniem prędkości + fVelNext = value1; + fSectionVelocityDist = value2; + iFlags |= spSectionVel; + break; + case cm_RoadVelocity: + // prędkość drogowa (od tej pory będzie jako domyślna najwyższa) + fVelNext = value1; + iFlags |= spRoadVel; + break; + case cm_PassengerStopPoint: + // nie ma dostępu do rozkładu + // przystanek, najwyżej AI zignoruje przy analizie tabelki + if ((iFlags & spPassengerStopPoint) == 0) fVelNext = 0.0; // TrainParams->IsStop()?0.0:-1.0; //na razie tak - iFlags |= 0x400; // niestety nie da się w tym miejscu współpracować z rozkładem - } - else if (command == cm_SetProximityVelocity) - { // ignorować - fVelNext = -1; - } - else if (command == cm_OutsideStation) - { // w trybie manewrowym: skanować od niej wstecz i stanąć po wyjechaniu za sygnalizator i + iFlags |= spPassengerStopPoint; // niestety nie da się w tym miejscu współpracować z rozkładem + break; + case cm_SetProximityVelocity: + // musi zostać gdyż inaczej nie działają manewry + fVelNext = -1; + iFlags |= spProximityVelocity; + // fSectionVelocityDist = value2; + break; + case cm_OutsideStation: + // w trybie manewrowym: skanować od niej wstecz i stanąć po wyjechaniu za sygnalizator i // zmienić kierunek // w trybie pociągowym: można przyspieszyć do wskazanej prędkości (po zjechaniu z rozjazdów) fVelNext = -1; - iFlags |= 0x2100; // W5 - } - else - { // inna komenda w evencie skanowanym powoduje zatrzymanie i wysłanie tej komendy - iFlags &= ~0xE00; // nie manewrowa, nie przystanek, nie zatrzymać na SBL - fVelNext = 0; // jak nieznana komenda w komórce sygnałowej, to ma stać + iFlags |= spOutsideStation; // W5 + break; + default: + // inna komenda w evencie skanowanym powoduje zatrzymanie i wysłanie tej komendy + iFlags &= ~(spShuntSemaphor | spPassengerStopPoint | + spStopOnSBL); // nie manewrowa, nie przystanek, nie zatrzymać na SBL + fVelNext = 0.0; // jak nieznana komenda w komórce sygnałowej, to zatrzymujemy } }; @@ -180,17 +199,17 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len) if (iska < 0.0) // iloczyn skalarny jest ujemny, gdy punkt jest z tyłu { // jeśli coś jest z tyłu, to dokładna odległość nie ma już większego znaczenia fDist = -fDist; // potrzebne do badania wyjechania składem poza ograniczenie - if (iFlags & 32) // 32 ustawione, gdy obiekt już został minięty + if (iFlags & spElapsed) // 32 ustawione, gdy obiekt już został minięty { // jeśli minięty (musi być minięty również przez końcówkę składu) } else { - iFlags ^= 32; // 32-minięty - będziemy liczyć odległość względem przeciwnego końca - // toru (nadal może być z przodu i ogdaniczać) + iFlags ^= spElapsed; // 32-minięty - będziemy liczyć odległość względem przeciwnego końca + // toru (nadal może być z przodu i ograniczać) if ((iFlags & 0x43) == 3) // tylko jeśli (istotny) tor, bo eventy są punktowe if (trTrack) // może być NULL, jeśli koniec toru (????) vPos = - (iFlags & 4) ? + (iFlags & spReverse) ? trTrack->CurrentSegment()->FastGetPoint_0() : trTrack->CurrentSegment()->FastGetPoint_1(); // drugi koniec istotny } @@ -201,14 +220,14 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len) // dokładniejsze wartości } if (fDist > 0.0) // nie może być 0.0, a przypadkiem mogło by się trafić i było by źle - if ((iFlags & 32) == 0) // 32 ustawione, gdy obiekt już został minięty + if ((iFlags & spElapsed) == 0) // 32 ustawione, gdy obiekt już został minięty { // jeśli obiekt nie został minięty, można od niego zliczać narastająco (inaczej może być // problem z wektorem kierunku) len = fDist = len + fDist; // zliczanie dlugości narastająco *p = vPos; // nowy punkt odniesienia *dir = Normalize(v); // nowy wektor kierunku od poprzedniego obiektu do aktualnego } - if (iFlags & 2) // jeśli tor + if (iFlags & spTrack) // jeśli tor { if (trTrack) // może być NULL, jeśli koniec toru (???) { @@ -221,34 +240,41 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len) // głównej drogi - chyba że jest równorzędne... fVelNext = 30.0; // uzależnić prędkość od promienia; albo niech będzie // ograniczona w skrzyżowaniu (velocity z ujemną wartością) - if ((iFlags & 32) == 0) // jeśli nie wjechał - if (trTrack->iNumDynamics > 0) // a skrzyżowanie zawiera pojazd - fVelNext = - 0.0; // to zabronić wjazdu (chyba że ten z przodu też jedzie prosto) + if ((iFlags & spElapsed) == 0) // jeśli nie wjechał + if (trTrack->iNumDynamics > 0) // a skrzyżowanie zawiera pojazd + { + WriteLog("Tor " + trTrack->NameGet() + " zajety przed pojazdem. Num=" + trTrack->iNumDynamics + "Dist= " + fDist); + fVelNext = + 0.0; // to zabronić wjazdu (chyba że ten z przodu też jedzie prosto) + } } - if (iFlags & 8) // jeśli odcinek zmienny + if (iFlags & spSwitch) // jeśli odcinek zmienny { if (bool(trTrack->GetSwitchState() & 1) != - bool(iFlags & 16)) // czy stan się zmienił? + bool(iFlags & spSwitchStatus)) // czy stan się zmienił? { // Ra: zakładam, że są tylko 2 możliwe stany - iFlags ^= 16; + iFlags ^= spSwitchStatus; // fVelNext=trTrack->VelocityGet(); //nowa prędkość - if ((iFlags & 32) == 0) + if ((iFlags & spElapsed) == 0) return true; // jeszcze trzeba skanowanie wykonać od tego toru // problem jest chyba, jeśli zwrotnica się przełoży zaraz po zjechaniu z niej // na Mydelniczce potrafi skanować na wprost mimo pojechania na bok } // poniższe nie dotyczy trybu łączenia? - if ((iFlags & 32) ? false : - trTrack->iNumDynamics > - 0) // jeśli jeszcze nie wjechano na tor, a coś na nim jest - fDist -= 30.0, fVelNext = 0.0; // to niech stanie w zwiększonej odległości - // else if (fVelNext==0.0) //jeśli została wyzerowana - // fVelNext=trTrack->VelocityGet(); //odczyt prędkości + if ((iFlags & spElapsed) ? false : + trTrack->iNumDynamics > + 0) // jeśli jeszcze nie wjechano na tor, a coś na nim jest + { + WriteLog("Rozjazd " + trTrack->NameGet() + " zajety przed pojazdem. Num=" + trTrack->iNumDynamics + "Dist= "+fDist); + //fDist -= 30.0; + fVelNext = 0.0; // to niech stanie w zwiększonej odległości + // else if (fVelNext==0.0) //jeśli została wyzerowana + // fVelNext=trTrack->VelocityGet(); //odczyt prędkości + } } } } - else if (iFlags & 0x100) // jeśli event + else if (iFlags & spEvent) // jeśli event { // odczyt komórki pamięci najlepiej by było zrobić jako notyfikację, czyli zmiana komórki // wywoła jakąś podaną funkcję CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości @@ -256,48 +282,90 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len) return false; }; +AnsiString TSpeedPos::GetName() +{ + if (iFlags & spTrack) // jeśli tor + return trTrack->NameGet(); + else if (iFlags & spEvent) // jeśli event + return evEvent->asName; +} + AnsiString TSpeedPos::TableText() { // pozycja tabelki prędkości - if (iFlags & 0x1) + if (iFlags & spEnabled) { // o ile pozycja istotna - if (iFlags & 0x2) // jeśli tor - return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) + - ", Vel=" + AnsiString(fVelNext) + ", Track=" + trTrack->NameGet(); - else if (iFlags & 0x100) // jeśli event - return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) + - ", Vel=" + AnsiString(fVelNext) + ", Event=" + evEvent->asName; + return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) + + ", Vel=" + AnsiString(fVelNext) + ", Name=" + GetName(); + //if (iFlags & spTrack) // jeśli tor + // return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) + + // ", Vel=" + AnsiString(fVelNext) + ", Track=" + trTrack->NameGet(); + //else if (iFlags & spEvent) // jeśli event + // return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) + + // ", Vel=" + AnsiString(fVelNext) + ", Event=" + evEvent->asName; } return "Empty"; } -bool TSpeedPos::Set(TEvent *e, double d) +bool TSpeedPos::IsProperSemaphor(TOrders order) +{ // sprawdzenie czy semafor jest zgodny z trybem jazdy + if (order < 0x40) // Wait_for_orders, Prepare_engine, Change_direction, Connect, Disconnect, Shunt + { + if (iFlags & (spSemaphor | spShuntSemaphor)) + return true; + else if (iFlags & spOutsideStation) + return true; + } + else if (order & Obey_train) + { + if (iFlags & spSemaphor) + return true; + } + return false; // true gdy zatrzymanie, wtedy nie ma po co skanować dalej +} + +bool TSpeedPos::Set(TEvent *event, double dist, TOrders order) { // zapamiętanie zdarzenia - fDist = d; - iFlags = 0x101; // event+istotny - evEvent = e; - vPos = e->PositionGet(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?) + fDist = dist; + iFlags = spEnabled | spEvent; // event+istotny + evEvent = event; + vPos = event->PositionGet(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?) CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości - return fVelNext == 0.0; // true gdy zatrzymanie, wtedy nie ma po co skanować dalej + // zależnie od trybu sprawdzenie czy jest tutaj gdzieś semafor lub tarcza manewrowa + // jeśli wskazuje stop wtedy wystawiamy true jako koniec sprawdzania + // WriteLog("EventSet: Vel=" + AnsiString(fVelNext) + " iFlags=" + AnsiString(iFlags) + " order="+AnsiString(order)); + if (order < 0x40) // Wait_for_orders, Prepare_engine, Change_direction, Connect, Disconnect, Shunt + { + if (iFlags & (spSemaphor | spShuntSemaphor) && fVelNext == 0.0) + return true; + else if (iFlags & spOutsideStation) + return true; + } + else if (order & Obey_train) + { + if (iFlags & spSemaphor && fVelNext == 0.0) + return true; + } + return false; // true gdy zatrzymanie, wtedy nie ma po co skanować dalej }; -void TSpeedPos::Set(TTrack *t, double d, int f) +void TSpeedPos::Set(TTrack *track, double dist, int flag) { // zapamiętanie zmiany prędkości w torze - fDist = d; // odległość do początku toru - trTrack = t; // TODO: (t) może być NULL i nie odczytamy końca poprzedniego :/ + fDist = dist; // odległość do początku toru + trTrack = track; // TODO: (t) może być NULL i nie odczytamy końca poprzedniego :/ if (trTrack) { - iFlags = f | (trTrack->eType == tt_Normal ? 2 : 10); // zapamiętanie kierunku wraz z typem - if (iFlags & 8) + iFlags = flag | (trTrack->eType == tt_Normal ? 2 : 10); // zapamiętanie kierunku wraz z typem + if (iFlags & spSwitch) if (trTrack->GetSwitchState() & 1) - iFlags |= 16; + iFlags |= spSwitchStatus; fVelNext = trTrack->VelocityGet(); if (trTrack->iDamageFlag & 128) fVelNext = 0.0; // jeśli uszkodzony, to też stój - if (iFlags & 64) + if (iFlags & spEnd) fVelNext = (trTrack->iCategoryFlag & 1) ? 0.0 : 20.0; // jeśli koniec, to pociąg stój, a samochód zwolnij - vPos = (bool(iFlags & 4) != bool(iFlags & 64)) ? + vPos = (bool(iFlags & spReverse) != bool(iFlags & spEnd)) ? trTrack->CurrentSegment()->FastGetPoint_1() : trTrack->CurrentSegment()->FastGetPoint_0(); } @@ -318,7 +386,7 @@ void TController::TableClear() eSignSkip = NULL; // nic nie pomijamy }; -TEvent *__fastcall TController::CheckTrackEvent(double fDirection, TTrack *Track) +TEvent * TController::CheckTrackEvent(double fDirection, TTrack *Track) { // sprawdzanie eventów na podanym torze do podstawowego skanowania TEvent *e = (fDirection > 0) ? Track->evEvent2 : Track->evEvent1; if (!e) @@ -342,18 +410,23 @@ bool TController::TableAddNew() bool TController::TableNotFound(TEvent *e) { // sprawdzenie, czy nie został już dodany do tabelki (np. podwójne W4 robi problemy) - int i, j = (iLast + 1) % iSpeedTableSize; // j, aby sprawdzić też ostatnią pozycję - for (i = iFirst; i != j; i = (i + 1) % iSpeedTableSize) - if ((sSpeedTable[i].iFlags & 0x101) == 0x101) // o ile używana pozycja - if (sSpeedTable[i].evEvent == e) - return false; // już jest, drugi raz dodawać nie ma po co + int j = (iLast + 1) % iSpeedTableSize; // j, aby sprawdzić też ostatnią pozycję + for (int i = iFirst; i != j; i = (i + 1) % iSpeedTableSize) + if ((sSpeedTable[i].iFlags & (spEnabled | spEvent)) == (spEnabled | + spEvent)) // o ile używana pozycja + if (sSpeedTable[i].evEvent == e) + { + WriteLog("TableNotFound: Event already in SpeedTable: " + sSpeedTable[i].evEvent->asName); + return false; // już jest, drugi raz dodawać nie ma po co + } return true; // nie ma, czyli można dodać }; void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) { // skanowanie trajektorii na odległość (fDistance) od (pVehicle) w kierunku przodu składu i // uzupełnianie tabelki - if (!iDirection) // kierunek pojazdu z napędem + // WriteLog("Starting TableTraceRoute"); + if (!iDirection) // kierunek pojazdu z napędem { // jeśli kierunek jazdy nie jest okreslony iTableDirection = 0; // czekamy na ustawienie kierunku } @@ -381,37 +454,62 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) } else { // kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor) - if (sSpeedTable[iLast].iFlags & 0x10000) // zatkanie + // WriteLog("TableTraceRoute: check last track"); + if (sSpeedTable[iLast].iFlags & spEndOfTable) // zatkanie { // jeśli zapełniła się tabelka - if ((iLast + 1) % iSpeedTableSize == iFirst) // jeśli nadal jest zapełniona - return; // nic się nie da zrobić - if ((iLast + 2) % iSpeedTableSize == iFirst) // musi być jeszcze miejsce wolne na - // ewentualny event, bo tor jeszcze nie - // sprawdzony - return; // już lepiej, ale jeszcze nie tym razem + if ((iLast + 1) % iSpeedTableSize == iFirst) // jeśli nadal jest zapełniona + { + TablePurger(); // nic się nie da zrobić + return; + } + if ((iLast + 2) % iSpeedTableSize == iFirst) // musi być jeszcze miejsce wolne na + // ewentualny event, bo tor jeszcze nie + // sprawdzony + { + TablePurger(); + return; // już lepiej, ale jeszcze nie tym razem + } sSpeedTable[iLast].iFlags &= 0xBE; // kontynuować próby doskanowania } - else if (VelNext == 0) - return; // znaleziono semafor lub tor z prędkością zero i nie ma co dalej sprawdzać + // znaleziono semafor lub tarczę lub tor z prędkością zero + // trzeba sprawdzić czy to nadał semafor + // WriteLog("TableTraceRoute: "+OwnerName()+" check semaphor... "); + // if (sSemNext) + // WriteLog(sSemNext->TableText()); + if (sSemNextStop && + sSemNextStop->fVelNext == + 0.0) // jeśli jest następny semafor to sprawdzamy czy to on nadał zero + { + // WriteLog("TableTraceRoute: "+sSemNext->TableText()); + if ((OrderCurrentGet() & Obey_train) && (sSemNextStop->iFlags & spSemaphor)) + return; + else if ((OrderCurrentGet() < 0x40) && + (sSemNextStop->iFlags & (spSemaphor | spShuntSemaphor | spOutsideStation))) + return; + } pTrack = sSpeedTable[iLast].trTrack; // ostatnio sprawdzony tor if (!pTrack) return; // koniec toru, to nie ma co sprawdzać (nie ma prawa tak być) - fLastDir = sSpeedTable[iLast].iFlags & 4 ? + fLastDir = sSpeedTable[iLast].iFlags & spReverse ? -1.0 : 1.0; // flaga ustawiona, gdy Point2 toru jest bliżej fCurrentDistance = sSpeedTable[iLast].fDist; // aktualna odległość do jego Point1 fTrackLength = - sSpeedTable[iLast].iFlags & 0x60 ? 0.0 : pTrack->Length(); // nie doliczać długości gdy: + sSpeedTable[iLast].iFlags & (spElapsed | spEnd) ? 0.0 : pTrack->Length(); // nie doliczać długości gdy: // 32-minięty początek, // 64-jazda do końca toru } if (fCurrentDistance < fDistance) { // jeśli w ogóle jest po co analizować + // WriteLog("TableTraceRoute: checking next tracks"); --iLast; // jak coś się znajdzie, zostanie wpisane w tę pozycję, którą właśnie odczytano while (fCurrentDistance < fDistance) { if (pTrack != tLast) // ostatni zapisany w tabelce nie był jeszcze sprawdzony { // jeśli tor nie był jeszcze sprawdzany + // if (pTrack) + // WriteLog("TableTraceRoute: " + OwnerName() + " checking track " + + // pTrack->NameGet()); if ((pEvent = CheckTrackEvent(fLastDir, pTrack)) != NULL) // jeśli jest semafor na tym torze { // trzeba sprawdzić tabelkę, bo dodawanie drugi raz tego samego przystanku nie @@ -419,10 +517,35 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) if (TableNotFound(pEvent)) // jeśli nie ma if (TableAddNew()) { - if (sSpeedTable[iLast].Set(pEvent, - fCurrentDistance)) // dodanie odczytu sygnału + WriteLog("TableTraceRoute: new event found " + pEvent->asName + " by " + + OwnerName()); + if (sSpeedTable[iLast].Set( + pEvent, fCurrentDistance, + OrderCurrentGet())) // dodanie odczytu sygnału + { fDistance = fCurrentDistance; // jeśli sygnał stop, to nie ma - // potrzeby dalej skanować + // potrzeby dalej skanować + sSemNextStop = &sSpeedTable[iLast]; + if (!sSemNext) + sSemNext = &sSpeedTable[iLast]; + WriteLog("Signal stop. Next Semaphor ", false); + if (sSemNextStop) + WriteLog(sSemNextStop->GetName()); + else + WriteLog("none"); + } + else + { + if (sSpeedTable[iLast].IsProperSemaphor(OrderCurrentGet()) && + sSemNext == NULL) + sSemNext = + &sSpeedTable[iLast]; // sprawdzamy czy pierwszy na drodze + WriteLog("Signal forward. Next Semaphor ", false); + if (sSemNext) + WriteLog(sSemNext->GetName()); + else + WriteLog("none"); + } } } // event dodajemy najpierw, żeby móc sprawdzić, czy tor został dodany po // odczytaniu prędkości następnego @@ -447,10 +570,10 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) 15) << 28; // ostatnie 4 bity pola flag sSpeedTable[iLast].iFlags &= - ~4; // usunięcie flagi kierunku, bo może być błędna + ~spReverse; // usunięcie flagi kierunku, bo może być błędna if (sSpeedTable[iLast].iFlags < 0) sSpeedTable[iLast].iFlags |= - 4; // ustawienie flagi kierunku na podstawie wybranego segmentu + spReverse; // ustawienie flagi kierunku na podstawie wybranego segmentu if (int(fLastDir) * sSpeedTable[iLast].iFlags < 0) fLastDir = -fLastDir; if (AIControllFlag) // dla AI na razie losujemy kierunek na kolejnym @@ -466,6 +589,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) sSpeedTable[iLast].Set(pTrack, fCurrentDistance, fLastDir < 0 ? 0x85 : 0x81); // dodanie odcinka do tabelki + // 0x85 = spEnabled, spReverse, SpCurve } } fCurrentDistance += @@ -565,27 +689,44 @@ void TController::TableCheck(double fDistance) double len = 0.0; // odległość będziemy zliczać narastająco for (int i = iFirst; i != iLast; i = (i + 1) % iSpeedTableSize) { // aktualizacja rekordów z wyjątkiem ostatniego - if (sSpeedTable[i].iFlags & 1) // jeśli pozycja istotna + if (sSpeedTable[i].iFlags & spEnabled) // jeśli pozycja istotna { if (sSpeedTable[i].Update(&pos, &dir, len)) { - iLast = i; // wykryta zmiana zwrotnicy - konieczne ponowne przeskanowanie - // dalszej części - break; // nie kontynuujemy pętli, trzeba doskanować ciąg dalszy + WriteLog("TableCheck: Switch change. Delete next entries. (" + + sSpeedTable[i].trTrack->NameGet() + ")"); + int k = (iLast + 1) % iSpeedTableSize; // skanujemy razem z ostatnią pozycją + for (int j = (i+1) % iSpeedTableSize; j != k; j = (j + 1) % iSpeedTableSize) + { // kasowanie wszystkich rekordów za zmienioną zwrotnicą + WriteLog("TableCheck: Delete from table: " + sSpeedTable[j].GetName()); + sSpeedTable[j].iFlags = 0; + if (&sSpeedTable[j] == sSemNext) + sSemNext = NULL; // przy kasowaniu tabelki zrzucamy także semafor + if (&sSpeedTable[j] == sSemNextStop) + sSemNextStop = NULL; // przy kasowaniu tabelki zrzucamy także semafor + } + WriteLog("TableCheck: Delete entries OK."); + WriteLog("TableCheck: New last element: " + sSpeedTable[i].GetName()); + iLast = i; // pokazujemy gdzie jest ostatni kawałek + break; // nie kontynuujemy pętli, trzeba doskanować ciąg dalszy } - if (sSpeedTable[i].iFlags & 2) // jeśli odcinek + if (sSpeedTable[i].iFlags & spTrack) // jeśli odcinek { if (sSpeedTable[i].fDist < -fLength) // a skład wyjechał całą długością poza { // degradacja pozycji - sSpeedTable[i].iFlags &= ~1; // nie liczy się + // WriteLog( "TableCheck: Track is behind. Delete from table: " + sSpeedTable[i].trTrack->NameGet()); + sSpeedTable[i].iFlags &= ~spEnabled; // nie liczy się } else if ((sSpeedTable[i].iFlags & 0xF0000028) == - 0x20) // jest z tyłu (najechany) i nie jest zwrotnicą ani skrzyżowaniem - if (sSpeedTable[i].fVelNext < 0) // a nie ma ograniczenia prędkości - sSpeedTable[i].iFlags = - 0; // to nie ma go po co trzymać (odtykacz usunie ze środka) + spElapsed) // jest z tyłu (najechany) i nie jest zwrotnicą ani skrzyżowaniem + if (sSpeedTable[i].fVelNext < 0) // a nie ma ograniczenia prędkości + { + sSpeedTable[i].iFlags = + 0; // to nie ma go po co trzymać (odtykacz usunie ze środka) + // WriteLog("TableCheck: Track without speed. Delete from table: " + sSpeedTable[i].trTrack->NameGet()); + } } - else if (sSpeedTable[i].iFlags & 0x100) // jeśli event + else if (sSpeedTable[i].iFlags & spEvent) // jeśli event { if (sSpeedTable[i].fDist < (sSpeedTable[i].evEvent->Type == tp_PutValues ? -fLength : @@ -594,9 +735,10 @@ void TController::TableCheck(double fDistance) sSpeedTable[i].fDist < -fLength) { // pociąg staje zawsze, a samochód tylko jeśli nie przejedzie całą // długością (może być zaskoczony zmianą) - sSpeedTable[i].iFlags &= ~1; // degradacja pozycji dla samochodu; + // WriteLog("TableCheck: Event is behind. Delete from table: " + sSpeedTable[i].evEvent->asName); + sSpeedTable[i].iFlags &= ~1; // degradacja pozycji dla samochodu; // semafory usuwane tylko przy sprawdzaniu, - // bo wysyłają komendy + // bo wysyłają komendy } } // if (sSpeedTable[i].fDist<-20.0*fLength) //jeśli to coś jest 20 razy dalej niż @@ -620,6 +762,7 @@ void TController::TableCheck(double fDistance) } } sSpeedTable[iLast].Update(&pos, &dir, len); // aktualizacja ostatniego + // WriteLog("TableCheck: Upate last track. Dist=" + AnsiString(sSpeedTable[iLast].fDist)); if (sSpeedTable[iLast].fDist < fDistance) TableTraceRoute(fDistance, pVehicles[1]); // doskanowanie dalszego odcinka } @@ -634,18 +777,19 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN double a; // przyspieszenie double v; // prędkość double d; // droga + double d_to_next_sem = 10000.0; //ustaiwamy na pewno dalej niż widzi AI TCommandType go = cm_Unknown; eSignNext = NULL; int i, k = iLast - iFirst + 1; if (k < 0) k += iSpeedTableSize; // ilość pozycji do przeanalizowania - iDrivigFlags &= - ~(moveTrackEnd | moveSwitchFound); // te flagi są ustawiane tutaj, w razie potrzeby + iDrivigFlags &= ~(moveTrackEnd | moveSwitchFound | moveSemaphorFound | + moveSpeedLimitFound); // te flagi są ustawiane tutaj, w razie potrzeby for (i = iFirst; k > 0; --k, i = (i + 1) % iSpeedTableSize) { // sprawdzenie rekordów od (iFirst) do (iLast), o ile są istotne - if (sSpeedTable[i].iFlags & 1) // badanie istotności + if (sSpeedTable[i].iFlags & spEnabled) // badanie istotności { // o ile dana pozycja tabelki jest istotna - if (sSpeedTable[i].iFlags & 0x400) + if (sSpeedTable[i].iFlags & spPassengerStopPoint) { // jeśli przystanek, trzeba obsłużyć wg rozkładu if (sSpeedTable[i].evEvent->CommandGet() != asNextStop) { // jeśli nazwa nie jest zgodna @@ -699,7 +843,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN sSpeedTable[i].fDist + fLength <= Max0R(sSpeedTable[i].evEvent->ValueGet(2), fMaxProximityDist + fLength) : - true) + sSpeedTable[i].fDist < d_to_next_sem) // Ra 2F1I: odległość plus długość pociągu musi być mniejsza od długości // peronu, chyba że pociąg jest dłuższy, to wtedy minimalna // jeśli długość peronu ((sSpeedTable[i].evEvent->ValueGet(2)) nie podana, @@ -842,9 +986,11 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN AnsiString(GlobalTime->mm) + " next " + asNextStop); // informacja #endif - if (int(floor(sSpeedTable[i].evEvent->ValueGet(1))) & 1) - iDrivigFlags |= moveStopHere; // nie podjeżdżać do semafora, - // jeśli droga nie jest wolna + if (int(floor(sSpeedTable[i].evEvent->ValueGet(1))) & 1) + iDrivigFlags |= moveStopHere; // nie podjeżdżać do semafora, + // jeśli droga nie jest wolna + else + iDrivigFlags &= ~moveStopHere; //po czasie jedź dalej iDrivigFlags |= moveStopCloser; // do następnego W4 podjechać // blisko (z dociąganiem) iDrivigFlags &= ~moveStartHorn; // bez trąbienia przed odjazdem @@ -898,26 +1044,54 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN } // koniec obsługi W4 v = sSpeedTable[i].fVelNext; // odczyt prędkości do zmiennej pomocniczej if (sSpeedTable[i].iFlags & - 8) // zwrotnice są usuwane z tabelki dopiero po zjechaniu z nich + spSwitch) // zwrotnice są usuwane z tabelki dopiero po zjechaniu z nich iDrivigFlags |= moveSwitchFound; // rozjazd z przodu/pod ogranicza np. sens skanowania wstecz - else if (sSpeedTable[i].iFlags & 0x100) // W4 może się deaktywować + else if (sSpeedTable[i].iFlags & spEvent) // W4 może się deaktywować { // jeżeli event, może być potrzeba wysłania komendy, aby ruszył - if (sSpeedTable[i].iFlags & 0x2000) + // sprawdzanie eventów pasywnych miniętych + if (sSpeedTable[i].fDist < 0.0 && sSemNext == &sSpeedTable[i]) + { + WriteLog("TableUpdate: semaphor " + sSemNext->GetName() + " passed by " + OwnerName()); + sSemNext = NULL; // jeśli minęliśmy semafor od ograniczenia to go kasujemy ze + // zmiennej sprawdzającej dla skanowania w przód + } + if (sSpeedTable[i].fDist < 0.0 && sSemNextStop == &sSpeedTable[i]) + { + WriteLog("TableUpdate: semaphor " + sSemNextStop->GetName() + " passed by " + OwnerName()); + sSemNextStop = NULL; // jeśli minęliśmy semafor od ograniczenia to go kasujemy ze + // zmiennej sprawdzającej dla skanowania w przód + } + if (sSpeedTable[i].fDist > 0.0 && + sSpeedTable[i].IsProperSemaphor(OrderCurrentGet())) + { + if (!sSemNext) + { + sSemNext = &sSpeedTable[i]; // jeśli jest mienięty poprzedni + // semafor a wcześniej + // byl nowy to go dorzucamy do zmiennej, żeby cały + // czas widział najbliższy + WriteLog("TableUpdate: Next semaphor: " + sSemNext->GetName() + " by " + OwnerName()); + } + if (!sSemNextStop || (sSemNextStop && sSemNextStop->fVelNext != 0 && + sSpeedTable[i].fVelNext == 0)) + sSemNextStop = &sSpeedTable[i]; + } + if (sSpeedTable[i].iFlags & spOutsideStation) { // jeśli W5, to reakcja zależna od trybu jazdy if (OrderCurrentGet() & Obey_train) { // w trybie pociągowym: można przyspieszyć do wskazanej prędkości (po // zjechaniu z rozjazdów) v = -1.0; // ignorować? - if (sSpeedTable[i].fDist < 0.0) // jeśli wskaźnik został minięty +//TODO trzeba zmienić przypisywanie VelSignal na VelSignalLast + if (sSpeedTable[i].fDist < 0.0) // jeśli wskaźnik został minięty { - VelSignal = v; //!!! ustawienie, gdy przejechany jest lepsze niż wcale, - // ale to jeszcze nie to + VelSignalLast = v; //ustawienie prędkości na -1 // iStationStart=TrainParams->StationIndex; //zaktualizować // wyświetlanie rozkładu } else if (!(iDrivigFlags & moveSwitchFound)) // jeśli rozjazdy już minięte - VelSignal = v; //!!! to też koniec ograniczenia + VelSignalLast = v; //!!! to też koniec ograniczenia } else { // w trybie manewrowym: skanować od niego wstecz, stanąć po wyjechaniu za @@ -929,7 +1103,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN // koniec toru) } } - else if (sSpeedTable[i].iFlags & 0x800) + else if (sSpeedTable[i].iFlags & spStopOnSBL) { // jeśli S1 na SBL if (mvOccupied->Vel < 2.0) // stanąć nie musi, ale zwolnić przynajmniej if (sSpeedTable[i].fDist < fMaxProximityDist) // jest w maksymalnym zasięgu @@ -944,25 +1118,86 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN // pociągu z przodu! } if (eSignSkip != sSpeedTable[i].evEvent) // jeśli ten SBL nie jest do pominięcia - v = sSpeedTable[i].evEvent->ValueGet(1); // to ma 0 odczytywać + // TODO sprawdzić do której zmiennej jest przypisywane v i zmienić to tutaj + v = sSpeedTable[i].evEvent->ValueGet(1); // to ma 0 odczytywać + } + else if (sSpeedTable[i].IsProperSemaphor(OrderCurrentGet())) + { // to semaphor + if (sSpeedTable[i].fDist < 0) + VelSignalLast = sSpeedTable[i].fVelNext; //minięty daje prędkość obowiązującą + else + { + iDrivigFlags |= moveSemaphorFound; //jeśli z przodu to dajemy falgę, że jest + d_to_next_sem = Min0R(sSpeedTable[i].fDist, d_to_next_sem); + } + } + else if (sSpeedTable[i].iFlags & spRoadVel) + { // to W6 + if (sSpeedTable[i].fDist < 0) + VelRoad = sSpeedTable[i].fVelNext; + } + else if (sSpeedTable[i].iFlags & spSectionVel) + { // to W27 + if (sSpeedTable[i].fDist < 0) // teraz trzeba sprawdzić inne warunki + { + if (sSpeedTable[i].fSectionVelocityDist == 0.0) + { + WriteLog("TableUpdate: Event is behind. SVD = 0: " + sSpeedTable[i].evEvent->asName); + sSpeedTable[i].iFlags = 0; // jeśli punktowy to kasujemy i nie dajemy ograniczenia na stałe + } + else if (sSpeedTable[i].fSectionVelocityDist < 0.0) + { // ograniczenie obowiązujące do następnego + if (sSpeedTable[i].fVelNext == Global::Min0RSpeed(sSpeedTable[i].fVelNext, VelLimitLast) && + sSpeedTable[i].fVelNext != VelLimitLast) + { // jeśli ograniczenie jest mniejsze niż obecne to obowiązuje od zaraz + VelLimitLast = sSpeedTable[i].fVelNext; + } + else if (sSpeedTable[i].fDist < -fLength) + { // jeśli większe to musi wyjechać za poprzednie + VelLimitLast = sSpeedTable[i].fVelNext; + WriteLog("TableUpdate: Event is behind. SVD < 0: " + sSpeedTable[i].evEvent->asName); + sSpeedTable[i].iFlags = 0; // wyjechaliśmy poza poprzednie, można skasować + } + } + else + { // jeśli większe to ograniczenie ma swoją długość + if (sSpeedTable[i].fVelNext == Global::Min0RSpeed(sSpeedTable[i].fVelNext, VelLimitLast) && + sSpeedTable[i].fVelNext != VelLimitLast) + { // jeśli ograniczenie jest mniejsze niż obecne to obowiązuje od zaraz + VelLimitLast = sSpeedTable[i].fVelNext; + } + else if (sSpeedTable[i].fDist < -fLength && sSpeedTable[i].fVelNext != VelLimitLast) + { // jeśli większe to musi wyjechać za poprzednie + VelLimitLast = sSpeedTable[i].fVelNext; + } + else if (sSpeedTable[i].fDist < -fLength - sSpeedTable[i].fSectionVelocityDist) + { // + VelLimitLast = -1.0; + WriteLog("TableUpdate: Event is behind. SVD > 0: " + sSpeedTable[i].evEvent->asName); + sSpeedTable[i].iFlags = 0; // wyjechaliśmy poza poprzednie, można skasować + } + } + } } + + //sprawdzenie eventów pasywnych przed nami if ((mvOccupied->CategoryFlag & 1) ? sSpeedTable[i].fDist > pVehicles[0]->fTrackBlock - 20.0 : false) // jak sygnał jest dalej niż zawalidroga v = 0.0; // to może być podany dla tamtego: jechać tak, jakby tam stop był else { // zawalidrogi nie ma (albo pojazd jest samochodem), sprawdzić sygnał - if (sSpeedTable[i].iFlags & 0x200) // jeśli Tm - w zasadzie to sprawdzić + if (sSpeedTable[i].iFlags & spShuntSemaphor) // jeśli Tm - w zasadzie to sprawdzić // komendę! { // jeśli podana prędkość manewrowa if ((OrderCurrentGet() & Obey_train) ? v == 0.0 : false) { // jeśli tryb pociągowy a tarcze ma ShuntVelocity 0 0 v = -1; // ignorować, chyba że prędkość stanie się niezerowa - if (sSpeedTable[i].iFlags & 0x20) // a jak przejechana + if (sSpeedTable[i].iFlags & spElapsed) // a jak przejechana sSpeedTable[i].iFlags = 0; // to można usunąć, bo podstawowy automat // usuwa tylko niezerowe } - else if (go <= cm_Ready) // jeśli jeszcze nie ma komendy + else if (go == cm_Unknown) // jeśli jeszcze nie ma komendy if (v != 0.0) // komenda jest tylko gdy ma jechać, bo stoi na podstawie // tabelki { // jeśli nie było komendy wcześniej - pierwsza się liczy - ustawianie @@ -983,9 +1218,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN } } } - else // if (sSpeedTable[i].iFlags&0x100) //jeśli semafor !!! Komendę trzeba - // sprawdzić !!!! - if (go <= cm_Ready) // jeśli nie było komendy wcześniej - pierwsza się liczy + else if (!(sSpeedTable[i].iFlags & spSectionVel)) //jeśli jakiś event pasywny ale nie ograniczenie + if (go == cm_Unknown) // jeśli nie było komendy wcześniej - pierwsza się liczy // - ustawianie VelSignal if (v < 0.0 ? true : v >= 1.0) // bo wartość 0.1 służy do hamowania tylko { @@ -995,12 +1229,13 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN // VelSignal=v; //nie do końca tak, to jest druga prędkość; -1 nie // wpisywać... if (VelSignal == 0.0) - VelSignal = v; // aby stojący ruszył + VelSignal = -1.0; // aby stojący ruszył if (sSpeedTable[i].fDist < 0.0) // jeśli przejechany { - VelSignal = v; //!!! ustawienie, gdy przejechany jest lepsze niż + if (v != 0 ? VelSignal = -1.0 : VelSignal = 0.0) + ; // ustawienie, gdy przejechany jest lepsze niż // wcale, ale to jeszcze nie to - if (sSpeedTable[i].iFlags & 0x100) // jeśli semafor + if (sSpeedTable[i].iFlags & spEvent) // jeśli event if ((sSpeedTable[i].evEvent != eSignSkip) ? true : (sSpeedTable[i].fVelNext != 0.0)) // ale inny niż ten, @@ -1010,6 +1245,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN iDrivigFlags &= ~moveVisibility; // sygnał zezwalający na // jazdę wyłącza jazdę na // widoczność (S1 na SBL) + + // usunąć jeśli nie jest ograniczeniem prędkości sSpeedTable[i].iFlags = 0; // to można usunąć (nie mogą być usuwane w skanowaniu) } @@ -1030,13 +1267,16 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN } // jeśli event if (v >= 0.0) { // pozycje z prędkością -1 można spokojnie pomijać - d = sSpeedTable[i].fDist; - if ((sSpeedTable[i].iFlags & 0x20) ? + d = sSpeedTable[i].fDist; + if ((sSpeedTable[i].iFlags & spElapsed) ? false : d > 0.0) // sygnał lub ograniczenie z przodu (+32=przejechane) { // 2014-02: jeśli stoi, a ma do przejechania kawałek, to niech jedzie if ((mvOccupied->Vel == 0.0) ? - ((sSpeedTable[i].iFlags & 0x501) == 0x501) && (d > fMaxProximityDist) : + ((sSpeedTable[i].iFlags & + (spEnabled | spEvent | spPassengerStopPoint)) == + (spEnabled | spEvent | spPassengerStopPoint)) && + (d > fMaxProximityDist) : false) a = (iDrivigFlags & moveStopCloser) ? fAcc : 0.0; // ma podjechać bliżej - // czy na pewno w tym @@ -1050,7 +1290,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN fVelDes = v; // ograniczenie aktualnej prędkości } } - else if (sSpeedTable[i].iFlags & 2) // jeśli tor + else if (sSpeedTable[i].iFlags & spTrack) // jeśli tor { // tor ogranicza prędkość, dopóki cały skład nie przejedzie, // d=fLength+d; //zamiana na długość liczoną do przodu if (v >= 1.0) // EU06 się zawieszało po dojechaniu na koniec toru postojowego @@ -1065,7 +1305,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN else // event trzyma tylko jeśli VelNext=0, nawet po przejechaniu (nie powinno // dotyczyć samochodów?) a = (v == 0.0 ? -1.0 : fAcc); // ruszanie albo hamowanie - if (a < fAcc) + if (a < fAcc && v == Min0R(v, fNext)) { // mniejsze przyspieszenie to mniejsza możliwość rozpędzenia się albo konieczność // hamowania // jeśli droga wolna, to może być a>1.0 i się tu nie załapuje @@ -1083,7 +1323,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN } // if (v>=0.0) if (fNext >= 0.0) { // jeśli ograniczenie - if ((sSpeedTable[i].iFlags & 0x101) == 0x101) // tylko sygnał przypisujemy + if ((sSpeedTable[i].iFlags & (spEnabled | spEvent)) == + (spEnabled | spEvent)) // tylko sygnał przypisujemy if (!eSignNext) // jeśli jeszcze nic nie zapisane tam eSignNext = sSpeedTable[i].evEvent; // dla informacji if (fNext == 0.0) @@ -1091,25 +1332,45 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN } } // if (sSpeedTable[i].iFlags&1) } // for + + if (VelSignalLast >= 0.0 && !(iDrivigFlags & (moveSemaphorFound | moveSwitchFound)) && + (OrderCurrentGet() & Obey_train)) + VelSignalLast = -1.0; // jeśli mieliśmy ograniczenie z semafora i nie ma przed nami + + if (VelSignalLast >= 0.0) //analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego + fVelDes = Min0R(fVelDes, VelSignalLast); + if (VelLimitLast >= 0.0) + fVelDes = Min0R(fVelDes, VelLimitLast); + if (VelRoad >= 0.0) + fVelDes = Min0R(fVelDes, VelRoad); + // nastepnego semafora albo zwrotnicy to uznajemy, że mijamy W5 + FirstSemaphorDist = d_to_next_sem; // przepisanie znalezionej wartosci do zmiennej return go; }; void TController::TablePurger() { // odtykacz: usuwa mniej istotne pozycje ze środka tabelki, aby uniknąć zatkania //(np. brak ograniczenia pomiędzy zwrotnicami, usunięte sygnały, minięte odcinki łuku) - int i, j, k = iLast - iFirst; // może być 15 albo 16 pozycji, ostatniej nie ma co sprawdzać + WriteLog("TablePurger: Czyszczenie tableki."); + int i, j, k = iLast - iFirst; // może być 15 albo 16 pozycji, ostatniej nie ma co sprawdzać if (k < 0) k += iSpeedTableSize; // ilość pozycji do przeanalizowania for (i = iFirst; k > 0; --k, i = (i + 1) % iSpeedTableSize) { // sprawdzenie rekordów od (iFirst) do (iLast), o ile są istotne - if ((sSpeedTable[i].iFlags & 1) ? + if ((sSpeedTable[i].iFlags & spEnabled) ? (sSpeedTable[i].fVelNext < 0) && ((sSpeedTable[i].iFlags & 0xAB) == 0xA3) : true) { // jeśli jest to minięty (0x20) tor (0x03) do liczenia cięciw (0x80), a nie zwrotnica // (0x08) - for (; k > 0; --k, i = (i + 1) % iSpeedTableSize) - sSpeedTable[i] = sSpeedTable[(i + 1) % iSpeedTableSize]; // skopiowanie - // WriteLog("Odtykacz usuwa pozycję"); + for (; k > 0; --k, i = (i + 1) % iSpeedTableSize) + { + sSpeedTable[i] = sSpeedTable[(i + 1) % iSpeedTableSize]; // skopiowanie + if (&sSpeedTable[(i + 1) % iSpeedTableSize] == sSemNext) + sSemNext = &sSpeedTable[i]; // przeniesienie znacznika o semaforze + if (&sSpeedTable[(i + 1) % iSpeedTableSize] == sSemNextStop) + sSemNextStop = &sSpeedTable[i]; // przeniesienie znacznika o semaforze + } + WriteLog("Odtykacz usuwa pozycję"); iLast = (iLast - 1 + iSpeedTableSize) % iSpeedTableSize; // cofnięcie z zawinięciem return; } @@ -1122,6 +1383,10 @@ void TController::TablePurger() for (j = -1, i = iFirst; k > 0; --k) { // przepisywanie rekordów iFirst..iLast na 0..k t[++j] = sSpeedTable[i]; + if (&sSpeedTable[i] == sSemNext) + sSemNext = &t[j]; // przeniesienie znacznika o semaforze + if (&sSpeedTable[i] == sSemNextStop) + sSemNextStop = &t[j]; // przeniesienie znacznika o semaforze i = (i + 1) % iSpeedTableSize; // kolejna pozycja mogą być zawinięta } iFirst = 0; // teraz będzie od zera @@ -1129,7 +1394,7 @@ void TController::TablePurger() delete[] sSpeedTable; // to już nie potrzebne sSpeedTable = t; // bo jest nowe iSpeedTableSize += 16; - // WriteLog("Tabelka powiększona do "+AnsiString(iSpeedTableSize)+" pozycji"); + WriteLog("Tabelka powiększona do "+AnsiString(iSpeedTableSize)+" pozycji"); }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- @@ -1150,12 +1415,16 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, HelpMeFlag = false; // fProximityDist=1; //nie używane ActualProximityDist = 1; + FirstSemaphorDist = 10000.0; vCommandLocation.x = 0; vCommandLocation.y = 0; vCommandLocation.z = 0; VelSignal = 0.0; // normalnie na początku ma stać, no chyba że jedzie VelLimit = -1.0; // brak ograniczenia prędkości VelNext = 120.0; + VelLimitLast = -1.0; // ostatnie ograniczenie bez ograniczenia + VelSignalLast = -1.0; // ostatni semafor też bez ograniczenia + VelRoad = -1.0; // prędkość drogowa bez ograniczenia AIControllFlag = AI; pVehicle = NewControll; ControllingSet(); // utworzenie połączenia do sterowanego pojazdu @@ -1226,6 +1495,8 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, fLength = 0.0; fMass = 0.0; //[kg] eSignNext = NULL; // sygnał zmieniający prędkość, do pokazania na [F2] + sSemNext = NULL; // pierwszy semafor w przebiegu + sSemNextStop = NULL; // pierwszy semafor z sygnałem stój fShuntVelocity = 40; // domyślna prędkość manewrowa fStopTime = 0.0; // czas postoju przed dalszą jazdą (np. na przystanku) iDrivigFlags = moveStopPoint; // podjedź do W4 możliwie blisko @@ -2090,7 +2361,10 @@ bool TController::IncBrake() switch (mvOccupied->BrakeSystem) { case Individual: - OK = mvOccupied->IncLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); + if (mvOccupied->LocalBrake == ManualBrake) + OK = mvOccupied->IncManualBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); + else + OK = mvOccupied->IncLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); break; case Pneumatic: if ((mvOccupied->Couplers[0].Connected == NULL) && @@ -2133,7 +2407,11 @@ bool TController::IncBrake() mvOccupied->BrakeReleaser(0); break; case ElectroPneumatic: - if (mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos(bh_EPB)) + if (mvOccupied->EngineType == ElectricInductionMotor) + { + OK = mvOccupied->IncLocalBrakeLevel(1); + } + else if (mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos(bh_EPB)) { mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPB)); if (mvOccupied->Handle->GetPos(bh_EPR) - mvOccupied->Handle->GetPos(bh_EPN) < 0.1) @@ -2159,7 +2437,10 @@ bool TController::DecBrake() switch (mvOccupied->BrakeSystem) { case Individual: - OK = mvOccupied->DecLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); + if (mvOccupied->LocalBrake == ManualBrake) + OK = mvOccupied->DecManualBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); + else + OK = mvOccupied->DecLocalBrakeLevel(1 + floor(0.5 + fabs(AccDesired))); break; case Pneumatic: if (mvOccupied->BrakeCtrlPos > 0) @@ -2170,7 +2451,11 @@ bool TController::DecBrake() Need_BrakeRelease = true; break; case ElectroPneumatic: - if (mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos(bh_EPR)) + if (mvOccupied->EngineType == ElectricInductionMotor) + { + OK = mvOccupied->DecLocalBrakeLevel(1); + } + else if (mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos(bh_EPR)) { mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPR)); if (mvOccupied->Handle->GetPos(bh_EPR) - mvOccupied->Handle->GetPos(bh_EPN) < 0.1) @@ -2274,7 +2559,15 @@ bool TController::IncSpeed() OK = mvControlling->IncScndCtrl(1); } break; - case WheelsDriven: + case ElectricInductionMotor: + if (!mvControlling->FuseFlag) + if (Ready || (iDrivigFlags & movePress) || (mvOccupied->ShuntMode)) //{(BrakePress<=0.01*MaxBrakePress)} + { + OK = mvControlling->IncMainCtrl(1); + } + break; + break; + case WheelsDriven: if (!mvControlling->CabNo) mvControlling->CabActivisation(); if (sin(mvControlling->eAngle) > 0) @@ -2324,7 +2617,8 @@ bool TController::DecSpeed(bool force) break; case Dumb: case DieselElectric: - OK = mvControlling->DecScndCtrl(2); + case ElectricInductionMotor: + OK = mvControlling->DecScndCtrl(2); if (!OK) OK = mvControlling->DecMainCtrl(2 + (mvControlling->MainCtrlPos / 2)); break; @@ -2487,7 +2781,8 @@ void TController::SpeedSet() break; case Dumb: case DieselElectric: - break; + case ElectricInductionMotor: + break; // WheelsDriven : // begin // OK:=False; @@ -3191,15 +3486,13 @@ bool TController::UpdateSituation(double dt) if (fMass > 1000000.0) fBrakeDist *= 2.0; // korekta dla ciężkich, bo przeżynają - da to coś? if (mvOccupied->BrakeDelayFlag == bdelay_G) - fBrakeDist = - fBrakeDist + - 2 * - mvOccupied - ->Vel; // dla nastawienia G koniecznie należy wydłużyć drogę na czas reakcji + fBrakeDist = fBrakeDist + 2 * mvOccupied->Vel; // dla nastawienia G + // koniecznie należy wydłużyć drogę na czas reakcji // double scanmax=(mvOccupied->Vel>0.0)?3*fDriverDist+fBrakeDist:10.0*fDriverDist; double scanmax = (mvOccupied->Vel > 5.0) ? 400 + fBrakeDist : - 50.0 * fDriverDist; // 1000m dla stojących pociągów; Ra 2015-01: przy + 30.0 * fDriverDist; // 1500m dla stojących pociągów; Ra 2015-01: przy + //double scanmax = Max0R(400 + fBrakeDist, 1500); // dłuższej drodze skanowania AI jeździ spokojniej // 2. Sprawdzić, czy tabelka pokrywa założony odcinek (nie musi, jeśli jest STOP). // 3. Sprawdzić, czy trajektoria ruchu przechodzi przez zwrotnice - jeśli tak, to sprawdzić, @@ -3559,7 +3852,7 @@ bool TController::UpdateSituation(double dt) case Change_direction | Connect: // zmiana kierunku podczas podłączania if (OrderList[OrderPos] != Obey_train) // spokojne manewry { - VelSignal = Min0R(VelSignal, 40); // jeśli manewry, to ograniczamy prędkość + VelSignal = Global::Min0RSpeed(VelSignal, 40); // jeśli manewry, to ograniczamy prędkość if (AIControllFlag) { // to poniżej tylko dla AI if (iVehicleCount >= 0) // jeśli jest co odczepić @@ -3693,7 +3986,7 @@ bool TController::UpdateSituation(double dt) // następnie ograniczana if (TrainParams) // jeśli ma rozkład if (TrainParams->TTVmax > 0.0) // i ograniczenie w rozkładzie - VelDesired = Min0R(VelDesired, + VelDesired = Global::Min0RSpeed(VelDesired, TrainParams->TTVmax); // to nie przekraczać rozkladowej SetDriverPsyche(); // ustawia AccPreferred (potrzebne tu?) // Ra: odczyt (ActualProximityDist), (VelNext) i (AccPreferred) z tabelki prędkosci @@ -3720,7 +4013,7 @@ bool TController::UpdateSituation(double dt) if (VelNext == 0.0) break; // ale jak coś z przodu zamyka, to ma stać if (iDrivigFlags & moveStopCloser) - VelSignal = VelDesired; // niech jedzie, jak W4 puściło - nie, ma czekać na + VelSignal = -1.0; // niech jedzie, jak W4 puściło - nie, ma czekać na // sygnał z sygnalizatora! case cm_SetVelocity: // od wersji 357 semafor nie budzi wyłączonej lokomotywy if (!(OrderList[OrderPos] & @@ -3761,7 +4054,7 @@ bool TController::UpdateSituation(double dt) // ma taboru do podłączenia // Ra 2F1H: z tym (fTrackBlock) to nie jest najlepszy pomysł, bo lepiej by // było porównać z odległością od sygnalizatora z przodu - if ((OrderList[OrderPos] | Connect) ? pVehicles[0]->fTrackBlock > 2000 : + if ((OrderList[OrderPos] & Connect) ? (pVehicles[0]->fTrackBlock > 2000 || pVehicles[0]->fTrackBlock > FirstSemaphorDist) : true) if ((comm = BackwardScan()) != cm_Unknown) // jeśli w drugą można jechać { // należy sprawdzać odległość od znalezionego sygnalizatora, @@ -3901,29 +4194,30 @@ bool TController::UpdateSituation(double dt) VelDesired = 0.0; // jak ma czekać, to nie ma jazdy // else if (VelSignal<0) // VelDesired=fVelMax; //ile fabryka dala (Ra: uwzględione wagony) - else if (VelSignal >= 0) // VelSignal>0 jest ograniczeniem prędkości (z semafora) - VelDesired = Min0R(VelDesired, VelSignal); - if (mvOccupied->RunningTrack.Velmax >= + else if (VelSignal >= 0) // jeśli skład był zatrzymany na początku i teraz już może jechać + VelDesired = Global::Min0RSpeed(VelDesired, VelSignal); + + if (mvOccupied->RunningTrack.Velmax >= 0) // ograniczenie prędkości z trajektorii ruchu VelDesired = - Min0R(VelDesired, + Global::Min0RSpeed(VelDesired, mvOccupied->RunningTrack.Velmax); // uwaga na ograniczenia szlakowej! if (VelforDriver >= 0) // tu jest zero przy zmianie kierunku jazdy - VelDesired = Min0R(VelDesired, VelforDriver); // Ra: tu może być 40, jeśli + VelDesired = Global::Min0RSpeed(VelDesired, VelforDriver); // Ra: tu może być 40, jeśli // mechanik nie ma znajomości // szlaaku, albo kierowca jeździ // 70 if (TrainParams) if (TrainParams->CheckTrainLatency() < 5.0) if (TrainParams->TTVmax > 0.0) - VelDesired = Min0R( + VelDesired = Global::Min0RSpeed( VelDesired, TrainParams ->TTVmax); // jesli nie spozniony to nie przekraczać rozkladowej if (VelDesired > 0.0) - if (VelNext > 0.0) + if ((sSemNext && sSemNext->fVelNext != 0.0) || (iDrivigFlags & moveStopHere)==0) { // jeśli można jechać, to odpalić dźwięk kierownika oraz zamknąć drzwi w - // składzie + // składzie, jeśli nie mamy czekać na sygnał też trzeba odpalić if (iDrivigFlags & moveGuardSignal) { // komunikat od kierownika tu, bo musi być wolna droga i odczekany czas // stania @@ -4094,19 +4388,19 @@ bool TController::UpdateSituation(double dt) // if (iDrivigFlags&moveStopHere) //to nie dotyczy podczepiania // if ((VelNext>0.0)||(ActualProximityDist>fMaxProximityDist*1.2)) if (VelNext > 0.0) - AccDesired = AccPreferred; // można jechać - else // jeśli daleko jechać nie można - if (ActualProximityDist > - fMaxProximityDist) // ale ma kawałek do sygnalizatora - { // if ((iDrivigFlags&moveStopHere)?false:AccPreferred>0) - if (AccPreferred > 0) - AccDesired = AccPreferred; // dociagnij do semafora; - else - VelDesired = 0.0; //,AccDesired=-fabs(fAccGravity); //stoj (hamuj z siłą - // równą składowej stycznej grawitacji) - } - else - VelDesired = 0.0; // VelNext=0 i stoi bliżej niż fMaxProximityDist + AccDesired = AccPreferred; // można jechać + else // jeśli daleko jechać nie można + if (ActualProximityDist > + fMaxProximityDist) // ale ma kawałek do sygnalizatora + { // if ((iDrivigFlags&moveStopHere)?false:AccPreferred>0) + if (AccPreferred > 0) + AccDesired = AccPreferred; // dociagnij do semafora; + else + VelDesired = 0.0; //,AccDesired=-fabs(fAccGravity); //stoj (hamuj z siłą + // równą składowej stycznej grawitacji) + } + else + VelDesired = 0.0; // VelNext=0 i stoi bliżej niż fMaxProximityDist } else // gdy jedzie wolniej niż potrzeba, albo nie ma przeszkód na drodze AccDesired = (VelDesired != 0.0 ? AccPreferred : -0.01); // normalna jazda @@ -4564,12 +4858,12 @@ void TController::OrdersDump() } }; -TOrders TController::OrderCurrentGet() +inline TOrders TController::OrderCurrentGet() { return OrderList[OrderPos]; } -TOrders TController::OrderNextGet() +inline TOrders TController::OrderNextGet() { return OrderList[OrderPos + 1]; } @@ -4700,7 +4994,7 @@ bool TController::BackwardTrackBusy(TTrack *Track) return false; // wolny }; -TEvent *__fastcall TController::CheckTrackEventBackward(double fDirection, TTrack *Track) +TEvent * TController::CheckTrackEventBackward(double fDirection, TTrack *Track) { // sprawdzanie eventu w torze, czy jest sygnałowym - skanowanie do tyłu TEvent *e = (fDirection > 0) ? Track->evEvent2 : Track->evEvent1; if (e) @@ -4710,7 +5004,7 @@ TEvent *__fastcall TController::CheckTrackEventBackward(double fDirection, TTrac return NULL; }; -TTrack *__fastcall TController::BackwardTraceRoute(double &fDistance, double &fDirection, +TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TEvent *&Event) { // szukanie sygnalizatora w kierunku przeciwnym jazdy (eventu odczytu komórki pamięci) TTrack *pTrackChVel = Track; // tor ze zmianą prędkości @@ -5061,29 +5355,29 @@ void TController::DirectionForward(bool forward) }; AnsiString TController::Relation() -{ +{ // zwraca relację pociągu return TrainParams->ShowRelation(); -}; // zwraca relację pociągu +}; AnsiString TController::TrainName() -{ +{ // zwraca numer pociągu return TrainParams->TrainName; -}; // zwraca relację pociągu +}; int TController::StationCount() -{ +{ // zwraca ilość stacji (miejsc zatrzymania) return TrainParams->StationCount; -}; // zwraca ilość stacji (miejsc zatrzymania) +}; int TController::StationIndex() -{ +{ // zwraca indeks aktualnej stacji (miejsca zatrzymania) return TrainParams->StationIndex; -}; // zwraca indeks aktualnej stacji (miejsca zatrzymania) +}; bool TController::IsStop() -{ +{ // informuje, czy jest zatrzymanie na najbliższej stacji return TrainParams->IsStop(); -}; // informuje, czy jest zatrzymanie na najbliższej stacji +}; void TController::MoveTo(TDynamicObject *to) { // przesunięcie AI do innego pojazdu (przy zmianie kabiny) diff --git a/Driver.h b/Driver.h index c72116d1f..1c902da0e 100644 --- a/Driver.h +++ b/Driver.h @@ -50,7 +50,11 @@ enum TMovementStatus moveGuardSignal = 0x8000, // sygnał od kierownika (minął czas postoju) moveVisibility = 0x10000, // jazda na widoczność po przejechaniu S1 na SBL moveDoorOpened = 0x20000, // drzwi zostały otwarte - doliczyć czas na zamknięcie - movePushPull = 0x40000 // zmiana czoła przez zmianę kabiny - nie odczepiać przy zmianie kierunku + movePushPull = 0x40000, // zmiana czoła przez zmianę kabiny - nie odczepiać przy zmianie kierunku + moveSemaphorFound = 0x80000, // na drodze skanowania został znaleziony semafor + moveSemaphorWasElapsed = 0x100000, // minięty został semafor + moveTrainInsideStation = 0x200000, // pociąg między semaforem a rozjazdami lub następnym semaforem + moveSpeedLimitFound = 0x400000 // pociąg w ograniczeniu z podaną jego długością }; enum TStopReason @@ -92,17 +96,41 @@ enum TAction actTrial // próba hamulca (na postoju) }; +enum TSpeedPosFlag +{ // wartości dla iFlag w TSpeedPos + spEnabled = 0x1, // pozycja brana pod uwagę + spTrack = 0x2, // to jest tor + spReverse = 0x4, // odwrotnie + spSwitch = 0x8, // to zwrotnica + spSwitchStatus = 0x10, // stan zwrotnicy + spElapsed = 0x20, // pozycja minięta przez pojazd + spEnd = 0x40, // koniec + spCurve = 0x80, // łuk + spEvent = 0x100, // event + spShuntSemaphor = 0x200, // tarcza manewrowa + spPassengerStopPoint = 0x400, // przystanek osobowy (wskaźnik W4) + spStopOnSBL = 0x800, // zatrzymanie na SBL + spCommandSent = 0x1000, // komenda wysłana + spOutsideStation = 0x2000, // wskaźnik końca manewrów + spSemaphor = 0x4000, // semafor pociągowy + spRoadVel = 0x8000, // zadanie prędkości drogowej + spSectionVel = 0x20000, // odcinek z ograniczeniem + spProximityVelocity = 0x40000, // odcinek z ograniczeniem i podaną jego długościa + spEndOfTable = 0x10000 // zatkanie tabelki +}; + class TSpeedPos { // pozycja tabeli prędkości dla AI public: double fDist; // aktualna odległość (ujemna gdy minięte) double fVelNext; // prędkość obowiązująca od tego miejsca + double fSectionVelocityDist; //długość ograniczenia prędkości // double fAcc; - int iFlags; + int iFlags; //flagi typu wpisu do tabelki // 1=istotny,2=tor,4=odwrotnie,8-zwrotnica (może się zmienić),16-stan // zwrotnicy,32-minięty,64=koniec,128=łuk // 0x100=event,0x200=manewrowa,0x400=przystanek,0x800=SBL,0x1000=wysłana komenda,0x2000=W5 - // 0x10000=zatkanie + // 0x4000=semafor,0x10000=zatkanie vector3 vPos; // współrzędne XYZ do liczenia odległości struct { @@ -114,9 +142,11 @@ class TSpeedPos public: void Clear(); bool Update(vector3 *p, vector3 *dir, double &len); - bool Set(TEvent *e, double d); + bool Set(TEvent *e, double d, TOrders order = Wait_for_orders); void Set(TTrack *t, double d, int f); AnsiString TableText(); + AnsiString GetName(); + bool IsProperSemaphor(TOrders order = Wait_for_orders); }; //---------------------------------------------------------------------------- @@ -140,6 +170,8 @@ class TController double fLastVel; // prędkość na poprzednio sprawdzonym torze TTrack *tLast; // ostatni analizowany tor TEvent *eSignSkip; // można pominąć ten SBL po zatrzymaniu + TSpeedPos *sSemNext; // następny semafor na drodze zależny od trybu jazdy + TSpeedPos *sSemNextStop; // następny semafor na drodze zależny od trybu jazdy i na stój private: // parametry aktualnego składu double fLength; // długość składu (do wyciągania z ograniczeń) double fMass; // całkowita masa do liczenia stycznej składowej grawitacji @@ -176,6 +208,10 @@ class TController TAction eAction; // aktualny stan bool HelpMeFlag; // wystawiane True jesli cos niedobrego sie dzieje public: + inline TAction GetAction() + { + return eAction; + } bool AIControllFlag; // rzeczywisty/wirtualny maszynista int iRouteWanted; // oczekiwany kierunek jazdy (0-stop,1-lewo,2-prawo,3-prosto) np. odpala // migacz lub czeka na stan zwrotnicy @@ -199,17 +235,22 @@ class TController double VelDesired; // predkość, z jaką ma jechać, wynikająca z analizy tableki; <=VelSignal double fAccDesiredAv; // uśrednione przyspieszenie z kolejnych przebłysków świadomości, żeby // ograniczyć migotanie - private: + public: double VelforDriver; // prędkość, używana przy zmianie kierunku (ograniczenie przy nieznajmości // szlaku?) - double VelSignal; // predkość zadawana przez semafor (funkcją SetVelocity()) + double VelSignal; // ograniczenie prędkości z kompilacji znaków i sygnałów double VelLimit; // predkość zadawana przez event jednokierunkowego ograniczenia prędkości + public: + double VelSignalLast; // prędkość zadana na ostatnim semaforze + double VelLimitLast; // prędkość zadana przez ograniczenie + double VelRoad; // aktualna prędkość drogowa (ze znaku W27) // (PutValues albo komendą) public: double VelNext; // prędkość, jaka ma być po przejechaniu długości ProximityDist private: - // double fProximityDist; //odleglosc podawana w SetProximityVelocity(); >0:przeliczać do + double fProximityDist; //odleglosc podawana w SetProximityVelocity(); >0:przeliczać do // punktu, <0:podana wartość + double FirstSemaphorDist; // odległość do pierwszego znalezionego semafora public: double ActualProximityDist; // odległość brana pod uwagę przy wyliczaniu prędkości i przyspieszenia @@ -268,7 +309,7 @@ class TController void ControllingSet(); // znajduje człon do sterowania void AutoRewident(); // ustawia hamulce w składzie public: - Mtable::TTrainParameters *__fastcall Timetable() + Mtable::TTrainParameters * Timetable() { return TrainParams; }; @@ -288,8 +329,8 @@ class TController void JumpToFirstOrder(); void OrderPush(TOrders NewOrder); void OrderNext(TOrders NewOrder); - TOrders OrderCurrentGet(); - TOrders OrderNextGet(); + inline TOrders OrderCurrentGet(); + inline TOrders OrderNextGet(); bool CheckVehicles(TOrders user = Wait_for_orders); private: @@ -314,12 +355,12 @@ class TController double Distance(vector3 &p1, vector3 &n, vector3 &p2); private: // Ra: metody obsługujące skanowanie toru - TEvent *__fastcall CheckTrackEvent(double fDirection, TTrack *Track); + TEvent * CheckTrackEvent(double fDirection, TTrack *Track); bool TableCheckEvent(TEvent *e); bool TableAddNew(); bool TableNotFound(TEvent *e); void TableClear(); - TEvent *__fastcall TableCheckTrackEvent(double fDirection, TTrack *Track); + TEvent * TableCheckTrackEvent(double fDirection, TTrack *Track); void TableTraceRoute(double fDistance, TDynamicObject *pVehicle = NULL); void TableCheck(double fDistance); TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc); @@ -327,8 +368,8 @@ class TController private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu bool BackwardTrackBusy(TTrack *Track); - TEvent *__fastcall CheckTrackEventBackward(double fDirection, TTrack *Track); - TTrack *__fastcall BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, + TEvent * CheckTrackEventBackward(double fDirection, TTrack *Track); + TTrack * BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TEvent *&Event); void SetProximityVelocity(double dist, double vel, const vector3 *pos); TCommandType BackwardScan(); diff --git a/DynObj.cpp b/DynObj.cpp index 32f55c71b..b9128d9c0 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -53,7 +53,8 @@ void TAnimPant::AKP_4E() vPos = vector3(0, 0, 0); // przypisanie domyśnych współczynników do pantografów fLenL1 = 1.22; // 1.176289 w modelach fLenU1 = 1.755; // 1.724482197 w modelach - fHoriz = 0.535; // 0.54555075 przesunięcie ślizgu w długości pojazdu względem osi obrotu dolnego + fHoriz = 0.535; // 0.54555075 przesunięcie ślizgu w długości pojazdu względem + // osi obrotu dolnego // ramienia fHeight = 0.07; // wysokość ślizgu ponad oś obrotu fWidth = 0.635; // połowa szerokości ślizgu, 0.635 dla AKP-1 i AKP-4E @@ -76,11 +77,14 @@ void TAnimPant::AKP_4E() }; //--------------------------------------------------------------------------- int TAnim::TypeSet(int i, int fl) -{ // ustawienie typu animacji i zależnej od niego ilości animowanych submodeli +{ // ustawienie typu animacji i zależnej od + // niego ilości animowanych submodeli fMaxDist = -1.0; // normalnie nie pokazywać switch (i) - { // maska 0x000F: ile używa wskaźników na submodele (0 gdy jeden, wtedy bez tablicy) - // maska 0x00F0: 0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki + { // maska 0x000F: ile używa wskaźników na submodele (0 gdy jeden, + // wtedy bez tablicy) + // maska 0x00F0: + // 0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki // maska 0xFF00: ile używa liczb float dla współczynników i stanu case 0: iFlags = 0x000; @@ -135,7 +139,7 @@ void TAnim::Parovoz(){ // animowanie tłoka i rozrządu parowozu }; //--------------------------------------------------------------------------- -TDynamicObject *__fastcall TDynamicObject::FirstFind(int &coupler_nr) +TDynamicObject * TDynamicObject::FirstFind(int &coupler_nr, int cf) { // szukanie skrajnego połączonego pojazdu w pociagu // od strony sprzegu (coupler_nr) obiektu (start) TDynamicObject *temp = this; @@ -143,8 +147,8 @@ TDynamicObject *__fastcall TDynamicObject::FirstFind(int &coupler_nr) { if (!temp) return NULL; // Ra: zabezpieczenie przed ewentaulnymi błędami sprzęgów - if (temp->MoverParameters->Couplers[coupler_nr].CouplingFlag == 0) - return temp; // nic nie ma już dalej podłączone + if ((temp->MoverParameters->Couplers[coupler_nr].CouplingFlag & cf) != cf) + return temp; // nic nie ma już dalej podłączone sprzęgiem cf if (coupler_nr == 0) { // jeżeli szukamy od sprzęgu 0 if (temp->PrevConnected) // jeśli mamy coś z przodu @@ -173,7 +177,8 @@ TDynamicObject *__fastcall TDynamicObject::FirstFind(int &coupler_nr) //--------------------------------------------------------------------------- float TDynamicObject::GetEPP() -{ // szukanie skrajnego połączonego pojazdu w pociagu +{ // szukanie skrajnego połączonego pojazdu w + // pociagu // od strony sprzegu (coupler_nr) obiektu (start) TDynamicObject *temp = this; int coupler_nr = 0; @@ -250,11 +255,11 @@ float TDynamicObject::GetEPP() }; //--------------------------------------------------------------------------- -TDynamicObject *__fastcall TDynamicObject::GetFirstDynamic(int cpl_type) +TDynamicObject * TDynamicObject::GetFirstDynamic(int cpl_type, int cf) { // Szukanie skrajnego połączonego pojazdu w pociagu // od strony sprzegu (cpl_type) obiektu szukajacego // Ra: wystarczy jedna funkcja do szukania w obu kierunkach - return FirstFind(cpl_type); // używa referencji + return FirstFind(cpl_type, cf); // używa referencji }; /* @@ -272,14 +277,16 @@ TDynamicObject* TDynamicObject::GetFirstCabDynamic(int cpl_type) return NULL; if (coupler_nr==0) {//jeżeli szukamy od sprzęgu 0 - if (temp->PrevConnectedNo==0) //jeśli pojazd od strony sprzęgu 0 jest odwrócony + if (temp->PrevConnectedNo==0) //jeśli pojazd od strony sprzęgu 0 jest +odwrócony coupler_nr=1-coupler_nr; //to zmieniamy kierunek sprzęgu if (temp->PrevConnected) temp=temp->PrevConnected; //ten jest od strony 0 } else { - if (temp->NextConnectedNo==1) //jeśli pojazd od strony sprzęgu 1 jest odwrócony + if (temp->NextConnectedNo==1) //jeśli pojazd od strony sprzęgu 1 jest +odwrócony coupler_nr=1-coupler_nr; //to zmieniamy kierunek sprzęgu if (temp->NextConnected) temp=temp->NextConnected; //ten pojazd jest od strony 1 @@ -406,17 +413,18 @@ void TDynamicObject::UpdateDoorTranslate(TAnim *pAnim) { if (pAnim->iNumber & 1) pAnim->smAnimated->SetTranslate( - vector3(0, 0, Max0R(dDoorMoveR * pAnim->fSpeed, dDoorMoveR))); + vector3(0, 0, Min0R(dDoorMoveR * pAnim->fSpeed, dDoorMoveR))); else pAnim->smAnimated->SetTranslate( - vector3(0, 0, Max0R(dDoorMoveL * pAnim->fSpeed, dDoorMoveL))); + vector3(0, 0, Min0R(dDoorMoveL * pAnim->fSpeed, dDoorMoveL))); } }; void TDynamicObject::UpdateDoorRotate(TAnim *pAnim) { // animacja drzwi - obrót if (pAnim->smAnimated) - { // if (MoverParameters->DoorOpenMethod==2) //obrotowe albo dwójłomne (trzeba kombinowac + { // if (MoverParameters->DoorOpenMethod==2) //obrotowe + // albo dwójłomne (trzeba kombinowac // submodelami i ShiftL=90,R=180) if (pAnim->iNumber & 1) pAnim->smAnimated->SetRotate(float3(1, 0, 0), dDoorMoveR); @@ -428,7 +436,8 @@ void TDynamicObject::UpdateDoorRotate(TAnim *pAnim) void TDynamicObject::UpdateDoorFold(TAnim *pAnim) { // animacja drzwi - obrót if (pAnim->smAnimated) - { // if (MoverParameters->DoorOpenMethod==2) //obrotowe albo dwójłomne (trzeba kombinowac + { // if (MoverParameters->DoorOpenMethod==2) //obrotowe + // albo dwójłomne (trzeba kombinowac // submodelami i ShiftL=90,R=180) if (pAnim->iNumber & 1) { @@ -476,6 +485,23 @@ void TDynamicObject::UpdatePant(TAnim *pAnim) pAnim->smElement[4]->SetRotate(float3(-1, 0, 0), b); //ślizg }; +void TDynamicObject::UpdateDoorPlug(TAnim *pAnim) +{ // animacja drzwi - odskokprzesuw + if (pAnim->smAnimated) + { + if (pAnim->iNumber & 1) + pAnim->smAnimated->SetTranslate( + vector3(Min0R(dDoorMoveR * 2, MoverParameters->DoorMaxPlugShift), 0, + Max0R(0, Min0R(dDoorMoveR * pAnim->fSpeed, dDoorMoveR) - + MoverParameters->DoorMaxPlugShift * 0.5f))); + else + pAnim->smAnimated->SetTranslate( + vector3(Min0R(dDoorMoveL * 2, MoverParameters->DoorMaxPlugShift), 0, + Max0R(0, Min0R(dDoorMoveL * pAnim->fSpeed, dDoorMoveL) - + MoverParameters->DoorMaxPlugShift * 0.5f))); + } +}; + void TDynamicObject::UpdateLeverDouble(TAnim *pAnim) { // animacja gałki zależna od double pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fSpeed * *pAnim->fDoubleBase); @@ -489,15 +515,19 @@ void TDynamicObject::UpdateLeverInt(TAnim *pAnim) pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fSpeed * *pAnim->iIntBase); }; void TDynamicObject::UpdateLeverEnum(TAnim *pAnim) -{ // ustawienie kąta na wartość wskazaną przez int z tablicy fParam +{ // ustawienie kąta na + // wartość wskazaną przez + // int z tablicy fParam // pAnim->fParam[0]; - dodać lepkość pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fParam[*pAnim->iIntBase]); }; // ABu 29.01.05 przeklejone z render i renderalpha: ********************* void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist) -{ // ABu290105: pozbierane i uporzadkowane powtarzajace sie rzeczy z Render i RenderAlpha - // dodatkowy warunek, if (ObjSqrDist<...) zeby niepotrzebnie nie zmianiec w obiektach, +{ // ABu290105: pozbierane i uporzadkowane powtarzajace + // sie rzeczy z Render i RenderAlpha + // dodatkowy warunek, if (ObjSqrDist<...) zeby niepotrzebnie nie zmianiec w + // obiektach, // ktorych i tak nie widac // NBMX wrzesien, MC listopad: zuniwersalnione btnOn = false; // czy przywrócić stan domyślny po renderowaniu @@ -530,7 +560,8 @@ void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist) // ABu011104: liczenie obrotow wozkow ABuBogies(); // Mczapkie-100402: rysowanie lub nie - sprzegow - // ABu-240105: Dodatkowy warunek: if (...).Render, zeby rysowal tylko jeden + // ABu-240105: Dodatkowy warunek: if (...).Render, zeby rysowal tylko + // jeden // z polaczonych sprzegow if ((TestFlag(MoverParameters->Couplers[0].CouplingFlag, ctrain_coupler)) && (MoverParameters->Couplers[0].Render)) @@ -547,7 +578,8 @@ void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist) } // else btCoupler2.TurnOff(); //******************************************************************************** - // przewody powietrzne j.w., ABu: decyzja czy rysowac tylko na podstawie 'render' - juz + // przewody powietrzne j.w., ABu: decyzja czy rysowac tylko na podstawie + // 'render' - juz // nie // przewody powietrzne, yB: decyzja na podstawie polaczen w t3d if (Global::bnewAirCouplers) @@ -661,7 +693,8 @@ void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist) //*********************************************************************************/ else // po staremu ABu'oewmu { - // przewody powietrzne j.w., ABu: decyzja czy rysowac tylko na podstawie 'render' + // przewody powietrzne j.w., ABu: decyzja czy rysowac tylko na podstawie + // 'render' if (TestFlag(MoverParameters->Couplers[0].CouplingFlag, ctrain_pneumatic)) { if (MoverParameters->Couplers[0].Render) @@ -690,7 +723,8 @@ void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist) // btCPneumatic2r.TurnOff(); //} - // przewody powietrzne j.w., ABu: decyzja czy rysowac tylko na podstawie 'render' + // przewody powietrzne j.w., ABu: decyzja czy rysowac tylko na podstawie + // 'render' // //yB - zasilajace if (TestFlag(MoverParameters->Couplers[0].CouplingFlag, ctrain_scndpneumatic)) { @@ -720,7 +754,8 @@ void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist) // btPneumatic2r.TurnOff(); //} } - //*************************************************************/// koniec wezykow + //*************************************************************/// koniec + // wezykow // uginanie zderzakow for (int i = 0; i < 2; i++) { @@ -840,9 +875,9 @@ void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist) else { // jak jest tylko jeden, to do drugiej kabiny go obracamy smMechanik0->iVisible = (MoverParameters->ActiveCab != 0); - smMechanik0->SetRotate(float3(0, 0, 1), MoverParameters->ActiveCab >= 0 ? - 0 : - 180); // obrót względem osi Z + smMechanik0->SetRotate( + float3(0, 0, 1), + MoverParameters->ActiveCab >= 0 ? 0 : 180); // obrót względem osi Z } if (smMechanik1) // mechanik od strony sprzęgu 1 smMechanik1->iVisible = MoverParameters->ActiveCab < 0; @@ -852,7 +887,8 @@ void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist) // if (ObjSqrDist<80000) ABuModelRoll(); //przechyłki od 400m } if (MoverParameters->Battery) - { // sygnały czoła pociagu //Ra: wyświetlamy bez ograniczeń odległości, by były widoczne z + { // sygnały czoła pociagu //Ra: wyświetlamy bez + // ograniczeń odległości, by były widoczne z // daleka if (TestFlag(iLights[0], 1)) { @@ -895,14 +931,16 @@ void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist) // ABu 29.01.05 koniec przeklejenia ************************************* double ABuAcos(const vector3 &calc_temp) -{ // Odpowiednik funkcji Arccos, bo cos mi tam nie dzialalo. +{ // Odpowiednik funkcji Arccos, bo cos + // mi tam nie dzialalo. return atan2(-calc_temp.x, calc_temp.z); // Ra: tak prościej } -TDynamicObject *__fastcall TDynamicObject::ABuFindNearestObject(TTrack *Track, +TDynamicObject * TDynamicObject::ABuFindNearestObject(TTrack *Track, TDynamicObject *MyPointer, int &CouplNr) -{ // zwraca wskaznik do obiektu znajdujacego sie na torze (Track), którego sprzęg jest najblizszy +{ // zwraca wskaznik do obiektu znajdujacego sie na torze + // (Track), którego sprzęg jest najblizszy // kamerze // służy np. do łączenia i rozpinania sprzęgów // WE: Track - tor, na ktorym odbywa sie poszukiwanie @@ -929,7 +967,8 @@ TDynamicObject *__fastcall TDynamicObject::ABuFindNearestObject(TTrack *Track, else // jeśli (CouplNr) inne niz -2, szukamy sprzęgu { // wektor [kamera-sprzeg0], potem [kamera-sprzeg1] // Powinno byc wyliczone, ale nie zaszkodzi drugi raz: - //(bo co, jesli nie wykonuje sie obrotow wozkow?) - Ra: ale zawsze są liczone + //(bo co, jesli nie wykonuje sie obrotow wozkow?) - Ra: ale zawsze są + // liczone // współrzędne sprzęgów // Track->Dynamics[i]->modelRot.z=ABuAcos(Track->Dynamics[i]->Axle0.pPosition-Track->Dynamics[i]->Axle1.pPosition); // poz=Track->Dynamics[i]->vPosition; //pozycja środka pojazdu @@ -961,9 +1000,10 @@ TDynamicObject *__fastcall TDynamicObject::ABuFindNearestObject(TTrack *Track, return NULL; } -TDynamicObject *__fastcall TDynamicObject::ABuScanNearestObject(TTrack *Track, double ScanDir, +TDynamicObject * TDynamicObject::ABuScanNearestObject(TTrack *Track, double ScanDir, double ScanDist, int &CouplNr) -{ // skanowanie toru w poszukiwaniu obiektu najblizszego kamerze +{ // skanowanie toru w poszukiwaniu obiektu najblizszego + // kamerze // double MyScanDir=ScanDir; //Moja orientacja na torze. //Ra: nie używane if (ABuGetDirection() < 0) ScanDir = -ScanDir; @@ -1018,18 +1058,21 @@ TDynamicObject *__fastcall TDynamicObject::ABuScanNearestObject(TTrack *Track, d // ABu 01.11.04 poczatek wyliczania przechylow pudla ********************** void TDynamicObject::ABuModelRoll() -{ // ustawienie przechyłki pojazdu i jego zawartości +{ // ustawienie przechyłki pojazdu i jego + // zawartości // Ra: przechyłkę załatwiamy na etapie przesuwania modelu } // ABu 06.05.04 poczatek wyliczania obrotow wozkow ********************** void TDynamicObject::ABuBogies() -{ // Obracanie wozkow na zakretach. Na razie uwzględnia tylko zakręty, +{ // Obracanie wozkow na zakretach. Na razie + // uwzględnia tylko zakręty, // bez zadnych gorek i innych przeszkod. if ((smBogie[0] != NULL) && (smBogie[1] != NULL)) { - // modelRot.z=ABuAcos(Axle0.pPosition-Axle1.pPosition); //kąt obrotu pojazdu [rad] + // modelRot.z=ABuAcos(Axle0.pPosition-Axle1.pPosition); //kąt obrotu pojazdu + // [rad] // bogieRot[0].z=ABuAcos(Axle0.pPosition-Axle3.pPosition); bogieRot[0].z = Axle0.vAngles.z; bogieRot[0] = RadToDeg(modelRot - bogieRot[0]); // mnożenie wektora przez stałą @@ -1044,7 +1087,8 @@ void TDynamicObject::ABuBogies() // ABu 16.03.03 sledzenie toru przed obiektem: ************************** void TDynamicObject::ABuCheckMyTrack() -{ // Funkcja przypisujaca obiekt prawidlowej tablicy Dynamics, +{ // Funkcja przypisujaca obiekt + // prawidlowej tablicy Dynamics, // bo gdzies jest jakis blad i wszystkie obiekty z danego // pociagu na poczatku stawiane sa na jednym torze i wpisywane // do jednej tablicy. Wykonuje sie tylko raz - po to 'ABuChecked' @@ -1059,7 +1103,7 @@ void TDynamicObject::ABuCheckMyTrack() } // Ra: w poniższej funkcji jest problem ze sprzęgami -TDynamicObject *__fastcall TDynamicObject::ABuFindObject(TTrack *Track, int ScanDir, +TDynamicObject * TDynamicObject::ABuFindObject(TTrack *Track, int ScanDir, Byte &CouplFound, double &dist) { // Zwraca wskaźnik najbliższego obiektu znajdującego się // na torze w określonym kierunku, ale tylko wtedy, kiedy @@ -1067,8 +1111,10 @@ TDynamicObject *__fastcall TDynamicObject::ABuFindObject(TTrack *Track, int Scan // WE: Track - tor, na ktorym odbywa sie poszukiwanie, // MyPointer - wskaznik do obiektu szukajacego. //Ra: zamieniłem na "this" - // ScanDir - kierunek szukania na torze (+1:w stronę Point2, -1:w stronę Point1) - // MyScanDir - kierunek szukania obiektu szukajacego (na jego torze); Ra: nie potrzebne + // ScanDir - kierunek szukania na torze (+1:w stronę Point2, -1:w stronę + // Point1) + // MyScanDir - kierunek szukania obiektu szukajacego (na jego torze); Ra: + // nie potrzebne // MyCouplFound - nr sprzegu obiektu szukajacego; Ra: nie potrzebne // WY: wskaznik do znalezionego obiektu. @@ -1077,8 +1123,8 @@ TDynamicObject *__fastcall TDynamicObject::ABuFindObject(TTrack *Track, int Scan { // sens szukania na tym torze jest tylko, gdy są na nim pojazdy double ObjTranslation; // pozycja najblizszego obiektu na torze double MyTranslation; // pozycja szukającego na torze - double MinDist = - Track->Length(); // najmniejsza znaleziona odleglość (zaczynamy od długości toru) + double MinDist = Track->Length(); // najmniejsza znaleziona odleglość + // (zaczynamy od długości toru) double TestDist; // robocza odległość od kolejnych pojazdów na danym odcinku int iMinDist = -1; // indeks wykrytego obiektu // if (Track->iNumDynamics>1) @@ -1099,12 +1145,14 @@ TDynamicObject *__fastcall TDynamicObject::ABuFindObject(TTrack *Track, int Scan TestDist = (Track->Dynamics[i]->RaTranslationGet()) - MyTranslation; // odległogłość tamtego od szukającego if ((TestDist > 0) && (TestDist <= MinDist)) - { // gdy jest po właściwej stronie i bliżej niż jakiś wcześniejszy + { // gdy jest po właściwej stronie i bliżej + // niż jakiś wcześniejszy CouplFound = (Track->Dynamics[i]->RaDirectionGet() > 0) ? 1 : 0; // to, bo (ScanDir>=0) if (Track->iCategoryFlag & 254) // trajektoria innego typu niż tor kolejowy - { // dla torów nie ma sensu tego sprawdzać, rzadko co jedzie po jednej + { // dla torów nie ma sensu tego sprawdzać, rzadko co jedzie po + // jednej // szynie i się mija // Ra: mijanie samochodów wcale nie jest proste // Przesuniecie wzgledne pojazdow. Wyznaczane, zeby sprawdzic, @@ -1112,18 +1160,21 @@ TDynamicObject *__fastcall TDynamicObject::ABuFindObject(TTrack *Track, int Scan // w/m siebie tak, ze nie zachodza na siebie i wtedy sie mijaja). double RelOffsetH; // wzajemna odległość poprzeczna if (CouplFound) // my na tym torze byśmy byli w kierunku Point2 - // dla CouplFound=1 są zwroty zgodne - istotna różnica przesunięć + // dla CouplFound=1 są zwroty zgodne - istotna różnica + // przesunięć RelOffsetH = (MoverParameters->OffsetTrackH - Track->Dynamics[i]->MoverParameters->OffsetTrackH); else - // dla CouplFound=0 są zwroty przeciwne - przesunięcia sumują się + // dla CouplFound=0 są zwroty przeciwne - przesunięcia sumują + // się RelOffsetH = (MoverParameters->OffsetTrackH + Track->Dynamics[i]->MoverParameters->OffsetTrackH); if (RelOffsetH < 0) RelOffsetH = -RelOffsetH; if (RelOffsetH + RelOffsetH > MoverParameters->Dim.W + Track->Dynamics[i]->MoverParameters->Dim.W) - continue; // odległość większa od połowy sumy szerokości - kolizji + continue; // odległość większa od połowy sumy szerokości - + // kolizji // nie będzie // jeśli zahaczenie jest niewielkie, a jest miejsce na poboczu, to // zjechać na pobocze @@ -1140,17 +1191,17 @@ TDynamicObject *__fastcall TDynamicObject::ABuFindObject(TTrack *Track, int Scan { if (Track->Dynamics[i] != this) { - TestDist = - MyTranslation - - (Track->Dynamics[i] - ->RaTranslationGet()); //???-przesunięcie wózka względem Point1 toru + TestDist = MyTranslation - + (Track->Dynamics[i]->RaTranslationGet()); //???-przesunięcie wózka + // względem Point1 toru if ((TestDist > 0) && (TestDist < MinDist)) { CouplFound = (Track->Dynamics[i]->RaDirectionGet() > 0) ? 0 : 1; // odwrotnie, bo (ScanDir<0) if (Track->iCategoryFlag & 254) // trajektoria innego typu niż tor kolejowy - { // dla torów nie ma sensu tego sprawdzać, rzadko co jedzie po jednej + { // dla torów nie ma sensu tego sprawdzać, rzadko co jedzie po + // jednej // szynie i się mija // Ra: mijanie samochodów wcale nie jest proste // Przesunięcie względne pojazdów. Wyznaczane, żeby sprawdzić, @@ -1158,18 +1209,21 @@ TDynamicObject *__fastcall TDynamicObject::ABuFindObject(TTrack *Track, int Scan // w/m siebie tak, że nie zachodzą na siebie i wtedy sie mijają). double RelOffsetH; // wzajemna odległość poprzeczna if (CouplFound) // my na tym torze byśmy byli w kierunku Point1 - // dla CouplFound=1 są zwroty zgodne - istotna różnica przesunięć + // dla CouplFound=1 są zwroty zgodne - istotna różnica + // przesunięć RelOffsetH = (MoverParameters->OffsetTrackH - Track->Dynamics[i]->MoverParameters->OffsetTrackH); else - // dla CouplFound=0 są zwroty przeciwne - przesunięcia sumują się + // dla CouplFound=0 są zwroty przeciwne - przesunięcia sumują + // się RelOffsetH = (MoverParameters->OffsetTrackH + Track->Dynamics[i]->MoverParameters->OffsetTrackH); if (RelOffsetH < 0) RelOffsetH = -RelOffsetH; if (RelOffsetH + RelOffsetH > MoverParameters->Dim.W + Track->Dynamics[i]->MoverParameters->Dim.W) - continue; // odległość większa od połowy sumy szerokości - kolizji + continue; // odległość większa od połowy sumy szerokości - + // kolizji // nie będzie } iMinDist = i; // potencjalna kolizja @@ -1178,16 +1232,20 @@ TDynamicObject *__fastcall TDynamicObject::ABuFindObject(TTrack *Track, int Scan } } } - dist += MinDist; // doliczenie odległości przeszkody albo długości odcinka do przeskanowanej + dist += MinDist; // doliczenie odległości przeszkody albo długości odcinka + // do przeskanowanej // odległości return (iMinDist >= 0) ? Track->Dynamics[iMinDist] : NULL; } - dist += Track->Length(); // doliczenie długości odcinka do przeskanowanej odległości + dist += Track->Length(); // doliczenie długości odcinka do przeskanowanej + // odległości return NULL; // nie ma pojazdów na torze, to jest NULL } int TDynamicObject::DettachStatus(int dir) -{ // sprawdzenie odległości sprzęgów rzeczywistych od strony (dir): 0=przód,1=tył +{ // sprawdzenie odległości sprzęgów + // rzeczywistych od strony (dir): + // 0=przód,1=tył // Ra: dziwne, że ta funkcja nie jest używana if (!MoverParameters->Couplers[dir].CouplingFlag) return 0; // jeśli nic nie podłączone, to jest OK @@ -1195,10 +1253,12 @@ int TDynamicObject::DettachStatus(int dir) } int TDynamicObject::Dettach(int dir) -{ // rozłączenie sprzęgów rzeczywistych od strony (dir): 0=przód,1=tył +{ // rozłączenie sprzęgów rzeczywistych od + // strony (dir): 0=przód,1=tył // zwraca maskę bitową aktualnych sprzegów (0 jeśli rozłączony) if (ctOwner) - { // jeśli pojazd ma przypisany obiekt nadzorujący skład, to póki są wskaźniki + { // jeśli pojazd ma przypisany obiekt nadzorujący skład, to póki + // są wskaźniki TDynamicObject *d = this; while (d) { @@ -1219,7 +1279,8 @@ int TDynamicObject::Dettach(int dir) } void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir) -{ // funkcja rozłączajaca podłączone sprzęgi, jeśli odległość przekracza (MinDist) +{ // funkcja rozłączajaca podłączone sprzęgi, + // jeśli odległość przekracza (MinDist) // MinDist - dystans minimalny, dla ktorego mozna rozłączać if (MyScanDir > 0) { @@ -1230,7 +1291,8 @@ void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir) { if ((PrevConnectedNo ? PrevConnected->NextConnected : PrevConnected->PrevConnected) == this) - { // Ra: nie rozłączamy znalezionego, jeżeli nie do nas podłączony (może jechać w + { // Ra: nie rozłączamy znalezionego, jeżeli nie do nas + // podłączony (może jechać w // innym kierunku) PrevConnected->MoverParameters->Couplers[PrevConnectedNo].Connected = NULL; if (PrevConnectedNo == 0) @@ -1260,7 +1322,8 @@ void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir) { if ((NextConnectedNo ? NextConnected->NextConnected : NextConnected->PrevConnected) == this) - { // Ra: nie rozłączamy znalezionego, jeżeli nie do nas podłączony (może jechać w + { // Ra: nie rozłączamy znalezionego, jeżeli nie do nas + // podłączony (może jechać w // innym kierunku) NextConnected->MoverParameters->Couplers[NextConnectedNo].Connected = NULL; if (NextConnectedNo == 0) @@ -1284,23 +1347,25 @@ void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir) void TDynamicObject::ABuScanObjects(int ScanDir, double ScanDist) { // skanowanie toru w poszukiwaniu kolidujących pojazdów - // ScanDir - określa kierunek poszukiwania zależnie od zwrotu prędkości pojazdu + // ScanDir - określa kierunek poszukiwania zależnie od zwrotu prędkości + // pojazdu // ScanDir=1 - od strony Coupler0, ScanDir=-1 - od strony Coupler1 - int MyScanDir = - ScanDir; // zapamiętanie kierunku poszukiwań na torze początkowym, względem sprzęgów + int MyScanDir = ScanDir; // zapamiętanie kierunku poszukiwań na torze + // początkowym, względem sprzęgów TTrackFollower *FirstAxle = (MyScanDir > 0 ? &Axle0 : &Axle1); // można by to trzymać w trainset - TTrack *Track = - FirstAxle->GetTrack(); // tor na którym "stoi" skrajny wózek (może być inny niż tor pojazdu) + TTrack *Track = FirstAxle->GetTrack(); // tor na którym "stoi" skrajny wózek + // (może być inny niż tor pojazdu) if (FirstAxle->GetDirection() < 0) // czy oś jest ustawiona w stronę Point1? - ScanDir = -ScanDir; // jeśli tak, to kierunek szukania będzie przeciwny (teraz względem + ScanDir = -ScanDir; // jeśli tak, to kierunek szukania będzie przeciwny + // (teraz względem // toru) Byte MyCouplFound; // numer sprzęgu do podłączenia w obiekcie szukajacym MyCouplFound = (MyScanDir < 0) ? 1 : 0; Byte CouplFound; // numer sprzęgu w znalezionym obiekcie (znaleziony wypełni) TDynamicObject *FoundedObj; // znaleziony obiekt double ActDist = 0; // przeskanowana odleglość; odległość do zawalidrogi - FoundedObj = - ABuFindObject(Track, ScanDir, CouplFound, ActDist); // zaczynamy szukać na tym samym torze + FoundedObj = ABuFindObject(Track, ScanDir, CouplFound, + ActDist); // zaczynamy szukać na tym samym torze /* if (FoundedObj) //jak coś znajdzie, to śledzimy @@ -1358,7 +1423,8 @@ void TDynamicObject::ABuScanObjects(int ScanDir, double ScanDist) } if (Track) { // jesli jest kolejny odcinek toru - // CurrDist=Track->Length(); //doliczenie tego toru do przejrzanego dystandu + // CurrDist=Track->Length(); //doliczenie tego toru do przejrzanego + // dystandu FoundedObj = ABuFindObject(Track, ScanDir, CouplFound, ActDist); // przejrzenie pojazdów tego toru if (FoundedObj) @@ -1380,10 +1446,12 @@ void TDynamicObject::ABuScanObjects(int ScanDir, double ScanDist) CouplersDettach(1.0, MyScanDir); // odłączamy, jeśli dalej niż metr // i łączenie sprzęgiem wirtualnym if (FoundedObj) - { // siebie można bezpiecznie podłączyć jednostronnie do znalezionego + { // siebie można bezpiecznie podłączyć jednostronnie do + // znalezionego MoverParameters->Attach(MyCouplFound, CouplFound, FoundedObj->MoverParameters, ctrain_virtual); - // MoverParameters->Couplers[MyCouplFound].Render=false; //wirtualnego nie renderujemy + // MoverParameters->Couplers[MyCouplFound].Render=false; //wirtualnego nie + // renderujemy if (MyCouplFound == 0) { PrevConnected = FoundedObj; // pojazd od strony sprzęgu 0 @@ -1395,7 +1463,8 @@ void TDynamicObject::ABuScanObjects(int ScanDir, double ScanDist) NextConnectedNo = CouplFound; } if (FoundedObj->MoverParameters->Couplers[CouplFound].CouplingFlag == ctrain_virtual) - { // Ra: wpinamy się wirtualnym tylko jeśli znaleziony ma wirtualny sprzęg + { // Ra: wpinamy się wirtualnym tylko jeśli znaleziony + // ma wirtualny sprzęg FoundedObj->MoverParameters->Attach(CouplFound, MyCouplFound, this->MoverParameters, ctrain_virtual); if (CouplFound == 0) // jeśli widoczny sprzęg 0 znalezionego @@ -1423,7 +1492,8 @@ void TDynamicObject::ABuScanObjects(int ScanDir, double ScanDist) FoundedObj->NextConnectedNo = MyCouplFound; } } - // Ra: jeśli dwa samochody się mijają na odcinku przed zawrotką, to odległość między nimi + // Ra: jeśli dwa samochody się mijają na odcinku przed zawrotką, to + // odległość między nimi // nie może być liczona w linii prostej! fTrackBlock = MoverParameters->Couplers[MyCouplFound] .CoupleDist; // odległość do najbliższego pojazdu w linii prostej @@ -1431,7 +1501,8 @@ void TDynamicObject::ABuScanObjects(int ScanDir, double ScanDist) if (ActDist > MoverParameters->Dim.L + FoundedObj->MoverParameters->Dim .L) // przeskanowana odległość większa od długości pojazdów - // else if (ActDistiLights; // wskaźnik na stan własnych świateł (zmienimy dla rozrządczych EZT) + iLights = MoverParameters->iLights; // wskaźnik na stan własnych świateł + // (zmienimy dla rozrządczych EZT) // McZapkie: TypeName musi byc nazwą CHK/MMD pojazdu if (!MoverParameters->LoadChkFile(asBaseDir)) { // jak wczytanie CHK się nie uda, to błąd @@ -1635,19 +1716,21 @@ double TDynamicObject::Init( } bool driveractive = (fVel != 0.0); // jeśli prędkość niezerowa, to aktywujemy ruch if (!MoverParameters->CheckLocomotiveParameters( - driveractive, (fVel > 0 ? 1 : -1) * Cab * - (iDirection ? 1 : -1))) // jak jedzie lub obsadzony to gotowy do drogi + driveractive, + (fVel > 0 ? 1 : -1) * Cab * + (iDirection ? 1 : -1))) // jak jedzie lub obsadzony to gotowy do drogi { Error("Parameters mismatch: dynamic object " + asName + " from\n" + BaseDir + "\\" + Type_Name); return 0.0; // zerowa długość to brak pojazdu } MoverParameters->BrakeLevelSet( - MoverParameters - ->BrakeCtrlPos); // poprawienie hamulca po ewentualnym przestawieniu przez Pascal + MoverParameters->BrakeCtrlPos); // poprawienie hamulca po ewentualnym + // przestawieniu przez Pascal // dodatkowe parametry yB - MoreParams += "."; // wykonuje o jedną iterację za mało, więc trzeba mu dodać kropkę na koniec + MoreParams += "."; // wykonuje o jedną iterację za mało, więc trzeba mu dodać + // kropkę na koniec int kropka = MoreParams.Pos("."); // znajdź kropke AnsiString ActPar; // na parametry while (kropka > 0) // jesli sa kropki jeszcze @@ -1698,7 +1781,8 @@ double TDynamicObject::Init( } if (ActPar.Pos("Q") > 0) // oprozniony { - // MoverParameters->Hamulec->ForceEmptiness(); //TODO: sprawdzic, dlaczego + // MoverParameters->Hamulec->ForceEmptiness(); //TODO: sprawdzic, + // dlaczego // pojawia sie blad przy uzyciu tej linijki w lokomotywie MoverParameters->BrakeReleaser(1); // odluznij automatycznie MoverParameters->Pipe->CreatePress(0.0); @@ -1785,17 +1869,20 @@ double TDynamicObject::Init( if (Track->fTrackWidth < 3.5) // jeśli droga wąska MoverParameters->OffsetTrackH = 0.0; // to stawiamy na środku, niezależnie od stanu // ruchu - else if (driveractive) // od 3.5m do 8.0m jedzie po środku pasa, dla szerszych w odległości + else if (driveractive) // od 3.5m do 8.0m jedzie po środku pasa, dla + // szerszych w odległości // 1.5m MoverParameters->OffsetTrackH = Track->fTrackWidth <= 8.0 ? -Track->fTrackWidth * 0.25 : -1.5; - else // jak stoi, to kołem na poboczu i pobieramy szerokość razem z poboczem, ale nie z + else // jak stoi, to kołem na poboczu i pobieramy szerokość razem z + // poboczem, ale nie z // chodnikiem MoverParameters->OffsetTrackH = -0.5 * (Track->WidthTotal() - MoverParameters->Dim.W) + 0.05; iHornWarning = 0; // nie będzie trąbienia po podaniu zezwolenia na jazdę if (fDist < 0.0) //-0.5*MoverParameters->Dim.L) //jeśli jest przesunięcie do tyłu - if (!Track->CurrentPrev()) // a nie ma tam odcinka i trzeba by coś wygenerować + if (!Track->CurrentPrev()) // a nie ma tam odcinka i trzeba by coś + // wygenerować fDist = -fDist; // to traktujemy, jakby przesunięcie było w drugą stronę } // w wagonie tez niech jedzie @@ -1811,10 +1898,12 @@ double TDynamicObject::Init( else // w przeciwnym razie trzeba włączyć pokazywanie kabiny bDisplayCab = true; } - // McZapkie-151102: rozkład jazdy czytany z pliku *.txt z katalogu w którym jest sceneria + // McZapkie-151102: rozkład jazdy czytany z pliku *.txt z katalogu w którym + // jest sceneria if (DriverType.Pos("1") || DriverType.Pos("2")) { // McZapkie-110303: mechanik i rozklad tylko gdy jest obsada - // MoverParameters->ActiveCab=MoverParameters->CabNo; //ustalenie aktywnej kabiny + // MoverParameters->ActiveCab=MoverParameters->CabNo; //ustalenie aktywnej + // kabiny // (rozrząd) Mechanik = new TController(Controller, this, Aggressive); if (TrainName.IsEmpty()) // jeśli nie w składzie @@ -1829,7 +1918,8 @@ double TDynamicObject::Init( } else if (DriverType == "p") { // obserwator w charakterze pasażera - // Ra: to jest niebezpieczne, bo w razie co będzie pomagał hamulcem bezpieczeństwa + // Ra: to jest niebezpieczne, bo w razie co będzie pomagał hamulcem + // bezpieczeństwa Mechanik = new TController(Controller, this, Easyman, false); } } @@ -1909,19 +1999,22 @@ double TDynamicObject::Init( if (fAxleDist > MoverParameters->Dim.L - 0.2) // nie mogą być za daleko fAxleDist = MoverParameters->Dim.L - 0.2; // bo będzie "walenie w mur" double fAxleDistHalf = fAxleDist * 0.5; - // WriteLog("Dynamic "+Type_Name+" of length "+MoverParameters->Dim.L+" at "+AnsiString(fDist)); + // WriteLog("Dynamic "+Type_Name+" of length "+MoverParameters->Dim.L+" at + // "+AnsiString(fDist)); // if (Cab) //jeśli ma obsadę - zgodność wstecz, jeśli tor startowy ma Event0 // if (Track->Event0) //jeśli tor ma Event0 - // if (fDist>=0.0) //jeśli jeśli w starych sceneriach początek składu byłby wysunięty na ten + // if (fDist>=0.0) //jeśli jeśli w starych sceneriach początek składu byłby + // wysunięty na ten // tor // if (fDist<=0.5*MoverParameters->Dim.L+0.2) //ale nie jest wysunięty // fDist+=0.5*MoverParameters->Dim.L+0.2; //wysunąć go na ten tor // przesuwanie pojazdu tak, aby jego początek był we wskazanym miejcu - fDist -= 0.5 * - MoverParameters->Dim - .L; // dodajemy pół długości pojazdu, bo ustawiamy jego środek (zliczanie na minus) + fDist -= 0.5 * MoverParameters->Dim.L; // dodajemy pół długości pojazdu, bo + // ustawiamy jego środek (zliczanie na + // minus) switch (iNumAxles) - { // Ra: pojazdy wstawiane są na tor początkowy, a potem przesuwane + { // Ra: pojazdy wstawiane są na tor początkowy, a potem + // przesuwane case 2: // ustawianie osi na torze Axle0.Init(Track, this, iDirection ? 1 : -1); Axle0.Move((iDirection ? fDist : -fDist) + fAxleDistHalf, false); @@ -1946,9 +2039,11 @@ double TDynamicObject::Init( // Axle3.Move((iDirection?fDist:-fDist)+(fAxleDistHalf-MoverParameters->ADist*0.5),false); break; } - Move(0.0001); // potrzebne do wyliczenia aktualnej pozycji; nie może być zero, bo nie przeliczy + Move(0.0001); // potrzebne do wyliczenia aktualnej pozycji; nie może być zero, + // bo nie przeliczy // pozycji - // teraz jeszcze trzeba przypisać pojazdy do nowego toru, bo przesuwanie początkowe osi nie + // teraz jeszcze trzeba przypisać pojazdy do nowego toru, bo przesuwanie + // początkowe osi nie // zrobiło tego ABuCheckMyTrack(); // zmiana toru na ten, co oś Axle0 (oś z przodu) TLocation loc; // Ra: ustawienie pozycji do obliczania sprzęgów @@ -1992,16 +2087,21 @@ void TDynamicObject::FastMove(double fDistance) } void TDynamicObject::Move(double fDistance) -{ // przesuwanie pojazdu po trajektorii polega na przesuwaniu poszczególnych osi - // Ra: wartość prędkości 2km/h ma ograniczyć aktywację eventów w przypadku drgań +{ // przesuwanie pojazdu po + // trajektorii polega na + // przesuwaniu poszczególnych osi + // Ra: wartość prędkości 2km/h ma ograniczyć aktywację eventów w przypadku + // drgań if (Axle0.GetTrack() == Axle1.GetTrack()) // przed przesunięciem - { // powiązanie pojazdu z osią można zmienić tylko wtedy, gdy skrajne osie są na tym samym torze + { // powiązanie pojazdu z osią można zmienić tylko wtedy, gdy skrajne osie są + // na tym samym torze if (MoverParameters->Vel > 2) //|[km/h]| nie ma sensu zmiana osi, jesli pojazd drga na postoju iAxleFirst = (MoverParameters->V >= 0.0) ? 1 : 0; //[m/s] ?1:0 - aktywna druga oś w kierunku jazdy - // aktualnie eventy aktywuje druga oś, żeby AI nie wyłączało sobie semafora za szybko + // aktualnie eventy aktywuje druga oś, żeby AI nie wyłączało sobie semafora + // za szybko } if (fDistance > 0.0) { // gdy ruch w stronę sprzęgu 0, doliczyć korektę do osi 1 @@ -2022,20 +2122,23 @@ void TDynamicObject::Move(double fDistance) { // liczenie pozycji pojazdu tutaj, bo jest używane w wielu miejscach vPosition = 0.5 * (Axle1.pPosition + Axle0.pPosition); //środek między skrajnymi osiami vFront = Axle0.pPosition - Axle1.pPosition; // wektor pomiędzy skrajnymi osiami - // Ra 2F1J: to nie jest stabilne (powoduje rzucanie taborem) i wymaga dopracowania + // Ra 2F1J: to nie jest stabilne (powoduje rzucanie taborem) i wymaga + // dopracowania fAdjustment = vFront.Length() - fAxleDist; // na łuku będzie ujemny - // if (fabs(fAdjustment)>0.02) //jeśli jest zbyt dużo, to rozłożyć na kilka przeliczeń + // if (fabs(fAdjustment)>0.02) //jeśli jest zbyt dużo, to rozłożyć na kilka + // przeliczeń // (wygasza drgania?) - //{//parę centymetrów trzeba by już skorygować; te błędy mogą się też generować na ostrych + //{//parę centymetrów trzeba by już skorygować; te błędy mogą się też + // generować na ostrych //łukach // fAdjustment*=0.5; //w jednym kroku korygowany jest ułamek błędu //} // else // fAdjustment=0.0; vFront = Normalize(vFront); // kierunek ustawienia pojazdu (wektor jednostkowy) - vLeft = Normalize(CrossProduct( - vWorldUp, - vFront)); // wektor poziomy w lewo, normalizacja potrzebna z powodu pochylenia (vFront) + vLeft = Normalize(CrossProduct(vWorldUp, vFront)); // wektor poziomy w lewo, + // normalizacja potrzebna z powodu + // pochylenia (vFront) vUp = CrossProduct(vFront, vLeft); // wektor w górę, będzie jednostkowy modelRot.z = atan2(-vFront.x, vFront.z); // kąt obrotu pojazdu [rad]; z ABuBogies() double a = ((Axle1.GetRoll() + Axle0.GetRoll())); // suma przechyłek @@ -2051,11 +2154,12 @@ void TDynamicObject::Move(double fDistance) vLeft = Normalize(CrossProduct(vUp, vFront)); // wektor w lewo // vUp=CrossProduct(vFront,vLeft); //wektor w górę } - mMatrix.Identity(); // to też można by od razu policzyć, ale potrzebne jest do wyświetlania + mMatrix.Identity(); // to też można by od razu policzyć, ale potrzebne jest + // do wyświetlania mMatrix.BasisChange(vLeft, vUp, vFront); // przesuwanie jest jednak rzadziej niż // renderowanie - mMatrix = - Inverse(mMatrix); // wyliczenie macierzy dla pojazdu (potrzebna tylko do wyświetlania?) + mMatrix = Inverse(mMatrix); // wyliczenie macierzy dla pojazdu (potrzebna + // tylko do wyświetlania?) // if (MoverParameters->CategoryFlag&2) { // przesunięcia są używane po wyrzuceniu pociągu z toru vPosition.x += MoverParameters->OffsetTrackH * vLeft.x; // dodanie przesunięcia w bok @@ -2083,7 +2187,8 @@ void TDynamicObject::Move(double fDistance) // e_bridge... fShade = 0.0; // standardowe oświetlenie else - { // jeżeli te tory mają niestandardowy stopień zacienienia (e_canyon, e_tunnel) + { // jeżeli te tory mają niestandardowy stopień zacienienia + // (e_canyon, e_tunnel) if (t0->eEnvironment == t1->eEnvironment) { switch (t0->eEnvironment) @@ -2103,7 +2208,8 @@ void TDynamicObject::Move(double fDistance) d = t0->fTrackLength - d; // od drugiej strony liczona długość d /= fAxleDist; // rozsataw osi procentowe znajdowanie się na torze switch (t0->eEnvironment) - { // typ zmiany oświetlenia - zakładam, że drugi tor ma e_flat + { // typ zmiany oświetlenia - zakładam, że + // drugi tor ma e_flat case e_canyon: fShade = (d * 0.65) + (1.0 - d); break; // zacienienie w kanionie @@ -2112,7 +2218,8 @@ void TDynamicObject::Move(double fDistance) break; // zacienienie w tunelu } switch (t1->eEnvironment) - { // typ zmiany oświetlenia - zakładam, że pierwszy tor ma e_flat + { // typ zmiany oświetlenia - zakładam, że + // pierwszy tor ma e_flat case e_canyon: fShade = d + (1.0 - d) * 0.65; break; // zacienienie w kanionie @@ -2127,15 +2234,19 @@ void TDynamicObject::Move(double fDistance) }; void TDynamicObject::AttachPrev(TDynamicObject *Object, int iType) -{ // Ra: doczepia Object na końcu składu (nazwa funkcji może być myląca) +{ // Ra: doczepia Object na końcu + // składu (nazwa funkcji może być + // myląca) // Ra: używane tylko przy wczytywaniu scenerii /* - //Ra: po wstawieniu pojazdu do scenerii nie miał on ustawionej pozycji, teraz już ma + //Ra: po wstawieniu pojazdu do scenerii nie miał on ustawionej pozycji, teraz + już ma TLocation loc; loc.X=-vPosition.x; loc.Y=vPosition.z; loc.Z=vPosition.y; - MoverParameters->Loc=loc; //Ra: do obliczania sprzęgów, na starcie nie są przesunięte + MoverParameters->Loc=loc; //Ra: do obliczania sprzęgów, na starcie nie są + przesunięte loc.X=-Object->vPosition.x; loc.Y=Object->vPosition.z; loc.Z=Object->vPosition.y; @@ -2168,8 +2279,9 @@ void TDynamicObject::AttachPrev(TDynamicObject *Object, int iType) Object->NextConnected = this; // on ma nas z tyłu Object->NextConnectedNo = iDirection; } - if (MoverParameters->TrainType & - dt_EZT) // w przypadku łączenia członów, światła w rozrządczym zależą od stanu w silnikowym + if (MoverParameters->TrainType & dt_EZT) // w przypadku łączenia członów, + // światła w rozrządczym zależą od + // stanu w silnikowym if (MoverParameters->Couplers[iDirection].AllowedFlag & ctrain_depot) // gdy sprzęgi łączone warsztatowo (powiedzmy) if ((MoverParameters->Power < 1.0) && @@ -2210,7 +2322,8 @@ void TDynamicObject::LoadUpdate() mdLoad = TModelsManager::GetModel(asLoadName.c_str()); // nowy ładunek Global::asCurrentTexturePath = AnsiString(szTexturePath); // z powrotem defaultowa sciezka do tekstur - // Ra: w MMD można by zapisać położenie modelu ładunku (np. węgiel) w zależności od + // Ra: w MMD można by zapisać położenie modelu ładunku (np. węgiel) w + // zależności od // załadowania } else if (MoverParameters->Load == 0) @@ -2326,9 +2439,11 @@ bool TDynamicObject::Update(double dt, double dt1) return false; // a normalnie powinny mieć bEnabled==false // Ra: przeniosłem - no już lepiej tu, niż w wyświetlaniu! - // if ((MoverParameters->ConverterFlag==false) && (MoverParameters->TrainType!=dt_ET22)) + // if ((MoverParameters->ConverterFlag==false) && + // (MoverParameters->TrainType!=dt_ET22)) // Ra: to nie może tu być, bo wyłącza sprężarkę w rozrządczym EZT! - // if ((MoverParameters->ConverterFlag==false)&&(MoverParameters->CompressorPower!=0)) + // if + // ((MoverParameters->ConverterFlag==false)&&(MoverParameters->CompressorPower!=0)) // MoverParameters->CompressorFlag=false; // if (MoverParameters->CompressorPower==2) // MoverParameters->CompressorAllow=MoverParameters->ConverterFlag; @@ -2338,12 +2453,16 @@ bool TDynamicObject::Update(double dt, double dt1) (MoverParameters->Power > 1.0)) // aby rozrządczy nie opuszczał silnikowemu if ((MechInside) || (MoverParameters->TrainType == dt_EZT)) { - // if ((!MoverParameters->PantCompFlag)&&(MoverParameters->CompressedVolume>=2.8)) + // if + // ((!MoverParameters->PantCompFlag)&&(MoverParameters->CompressedVolume>=2.8)) // MoverParameters->PantVolume=MoverParameters->CompressedVolume; if (MoverParameters->PantPress < (MoverParameters->TrainType == dt_EZT ? 2.4 : 3.5)) - { // 3.5 wg http://www.transportszynowy.pl/eu06-07pneumat.php - //"Wyłączniki ciśnieniowe odbieraków prądu wyłączają sterowanie wyłącznika szybkiego - // oraz uniemożliwiają podniesienie odbieraków prądu, gdy w instalacji rozrządu + { // 3.5 wg + // http://www.transportszynowy.pl/eu06-07pneumat.php + //"Wyłączniki ciśnieniowe odbieraków prądu wyłączają sterowanie + // wyłącznika szybkiego + // oraz uniemożliwiają podniesienie odbieraków prądu, gdy w instalacji + // rozrządu // ciśnienie spadnie poniżej wartości 3,5 bara." // Ra 2013-12: Niebugocław mówi, że w EZT podnoszą się przy 2.5 // if (!MoverParameters->PantCompFlag) @@ -2369,24 +2488,29 @@ bool TDynamicObject::Update(double dt, double dt1) // TTrackShape ts; // ts.R=MyTrack->fRadius; // if (ABuGetDirection()<0) ts.R=-ts.R; - // ts.R=MyTrack->fRadius; //ujemne promienie są już zamienione przy wczytywaniu + // ts.R=MyTrack->fRadius; //ujemne promienie są już zamienione przy + // wczytywaniu if (Axle0.vAngles.z != Axle1.vAngles.z) - { // wyliczenie promienia z obrotów osi - modyfikację zgłosił youBy + { // wyliczenie promienia z obrotów + // osi - modyfikację zgłosił youBy ts.R = Axle0.vAngles.z - Axle1.vAngles.z; // różnica może dawać stałą ±M_2PI if (ts.R > M_PI) ts.R -= M_2PI else if (ts.R < -M_PI) ts.R += M_2PI; // normalizacja // ts.R=fabs(0.5*MoverParameters->BDist/sin(ts.R*0.5)); ts.R = -0.5 * MoverParameters->BDist / sin(ts.R * 0.5); if ((ts.R > 15000.0) || (ts.R < -15000.0)) - ts.R = 0.0; // szkoda czasu na zbyt duże promienie, 4km to promień nie wymagający + ts.R = 0.0; // szkoda czasu na zbyt duże promienie, 4km to promień nie + // wymagający // przechyłki } else ts.R = 0.0; // ts.R=ComputeRadius(Axle1.pPosition,Axle2.pPosition,Axle3.pPosition,Axle0.pPosition); - // Ra: składową pochylenia wzdłużnego mamy policzoną w jednostkowym wektorze vFront + // Ra: składową pochylenia wzdłużnego mamy policzoną w jednostkowym wektorze + // vFront ts.Len = 1.0; // Max0R(MoverParameters->BDist,MoverParameters->ADist); - ts.dHtrack = -vFront.y; // Axle1.pPosition.y-Axle0.pPosition.y; //wektor między skrajnymi osiami + ts.dHtrack = -vFront.y; // Axle1.pPosition.y-Axle0.pPosition.y; //wektor + // między skrajnymi osiami // (!!!odwrotny) ts.dHrail = (Axle1.GetRoll() + Axle0.GetRoll()) * 0.5; //średnia przechyłka pudła // TTrackParam tp; @@ -2406,7 +2530,8 @@ bool TDynamicObject::Update(double dt, double dt1) MoverParameters->InsideConsist = false; } // napiecie sieci trakcyjnej - // Ra 15-01: przeliczenie poboru prądu powinno być robione wcześniej, żeby na tym etapie były + // Ra 15-01: przeliczenie poboru prądu powinno być robione wcześniej, żeby na + // tym etapie były // znane napięcia // TTractionParam tmpTraction; // tmpTraction.TractionVoltage=0; @@ -2419,8 +2544,9 @@ bool TDynamicObject::Update(double dt, double dt1) { v = MoverParameters->PantFrontVolt; if (v == 0.0) - if (MoverParameters->TrainType & - (dt_EZT | dt_ET40 | dt_ET41 | dt_ET42)) // dwuczłony mogą mieć sprzęg WN + if ((MoverParameters->TrainType & (dt_EZT | dt_ET40 | dt_ET41 | dt_ET42)) && + MoverParameters->EngineType != + ElectricInductionMotor) // dwuczłony mogą mieć sprzęg WN v = MoverParameters->GetTrainsetVoltage(); // ostatnia szansa } if (v != 0.0) @@ -2439,20 +2565,24 @@ bool TDynamicObject::Update(double dt, double dt1) {//wspomagacz usuwania problemów z siecią if (!Global::iPause) {//Ra: tymczasowa teleportacja do miejsca, gdzie brakuje prądu - Global::SetCameraPosition(vPosition+vector3(0,0,5)); //nowa pozycja dla + Global::SetCameraPosition(vPosition+vector3(0,0,5)); //nowa + pozycja dla generowania obiektów Global::pCamera->Init(vPosition+vector3(0,0,5),Global::pFreeCameraInitAngle[0]); //przestawienie } - Global:l::pGround->Silence(Global::pCamera->Pos); //wyciszenie wszystkiego + Global:l::pGround->Silence(Global::pCamera->Pos); //wyciszenie + wszystkiego z poprzedniej pozycji - Globa:iPause|=1; //tymczasowe zapauzowanie, gdy problem z siecią + Globa:iPause|=1; //tymczasowe zapauzowanie, gdy problem z + siecią } */ NoVoltTime = NoVoltTime + dt; if (NoVoltTime > 0.2) // jeśli brak zasilania dłużej niż 0.2 sekundy (25km/h pod // izolatorem daje 0.15s) - { // Ra 2F1H: prowizorka, trzeba przechować napięcie, żeby nie wywalało WS pod + { // Ra 2F1H: prowizorka, trzeba przechować napięcie, żeby nie wywalało + // WS pod // izolatorem if (MoverParameters->Vel > 0.5) // jeśli jedzie if (MoverParameters->PantFrontUp || @@ -2461,8 +2591,11 @@ bool TDynamicObject::Update(double dt, double dt1) // inaczej // if (NoVoltTime>0.02) //tu można ograniczyć czas rozłączenia // if (DebugModeFlag) //logowanie nie zawsze - if (MoverParameters->Mains) + if ((MoverParameters->Mains) && + ((MoverParameters->EngineType != ElectricInductionMotor) + || (MoverParameters->GetTrainsetVoltage() < 0.1f))) { // Ra 15-01: logować tylko, jeśli WS załączony + // yB 16-03: i nie jest to asynchron zasilany z daleka // if (MoverParameters->PantFrontUp&&pants) // Ra 15-01: bezwzględne współrzędne pantografu nie są dostępne, // więc lepiej się tego nie zaloguje @@ -2480,14 +2613,16 @@ bool TDynamicObject::Update(double dt, double dt1) // "+FloatToStrF(vPosition.z,ffFixed,7,2)+", time // "+FloatToStrF(NoVoltTime,ffFixed,7,2)); } - // Ra 2F1H: nie było sensu wpisywać tu zera po upływie czasu, bo zmienna była + // Ra 2F1H: nie było sensu wpisywać tu zera po upływie czasu, bo + // zmienna była // tymczasowa, a napięcie zerowane od razu tmpTraction.TractionVoltage = 0; // Ra 2013-12: po co tak? // pControlled->MainSwitch(false); //może tak? } } } - // else //Ra: nie no, trzeba podnieść pantografy, jak nie będzie drutu, to będą miały prąd + // else //Ra: nie no, trzeba podnieść pantografy, jak nie będzie drutu, to + // będą miały prąd // po osiągnięciu 1.4m // tmpTraction.TractionVoltage=0.95*MoverParameters->EnginePowerSource.MaxVoltage; } @@ -2498,27 +2633,114 @@ bool TDynamicObject::Update(double dt, double dt1) tmpTraction.TractionResistivity = 0.3; // McZapkie: predkosc w torze przekazac do TrackParam - // McZapkie: Vel ma wymiar [km/h] (absolutny), V ma wymiar [m/s], taka przyjalem notacje + // McZapkie: Vel ma wymiar [km/h] (absolutny), V ma wymiar [m/s], taka + // przyjalem notacje tp.Velmax = MyTrack->VelocityGet(); if (Mechanik) { // Ra 2F3F: do Driver.cpp to przenieść? MoverParameters->EqvtPipePress = GetEPP(); // srednie cisnienie w PG if ((Mechanik->Primary()) && - (MoverParameters->EngineType == - ElectricInductionMotor)) // jesli glowny i z asynchronami, to niech steruje + (MoverParameters->EngineType == ElectricInductionMotor)) // jesli glowny i z + // asynchronami, to + // niech steruje { // hamulcem lacznie dla calego pociagu/ezt - // 1. ustal wymagana sile hamowania calego pociagu + bool kier = (DirectionGet() * MoverParameters->ActiveCab > 0); + float FED = 0; + float np = 0; + float masa = 0; + float FrED = 0; + float masamax = 0; + float FmaxPN = 0; + float FfulED = 0; + float FmaxED = 0; + float Fzad = 0; + float FzadED = 0; + float FzadPN = 0; + float Frj = 0; + float amax = 0; + float osie = 0; + // 1. ustal wymagana sile hamowania calego pociagu // - opoznienie moze byc ustalane na podstawie charakterystyki // - opoznienie moze byc ustalane na podstawie mas i cisnien granicznych // // 2. ustal mozliwa do realizacji sile hamowania ED // - w szczegolnosci powinien brac pod uwage rozne sily hamowania - float FED = 0; - // for(TDynamicObject *p=GetFirstDynamic(4);p;p->NextC(4)) - // FED+=p->MoverParameters->eimv[eimv_Fmax]; - // 3. ustaw pojazdom sile hamowania ED + for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p; + (kier ? p = p->NextC(4) : p = p->PrevC(4))) + { + np++; + masamax += p->MoverParameters->MBPM + + (p->MoverParameters->MBPM > 1 ? 0 : p->MoverParameters->Mass) + + p->MoverParameters->Mred; + float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] - + p->MoverParameters->BrakeCylSpring) * + p->MoverParameters->BrakeCylMult[0] - + p->MoverParameters->BrakeSlckAdj) * + p->MoverParameters->BrakeCylNo * p->MoverParameters->BrakeRigEff; + FmaxPN += Nmax * p->MoverParameters->Hamulec->GetFC( + Nmax / (p->MoverParameters->NAxles * p->MoverParameters->NBpA), + p->MoverParameters->Vmax) * + 1000; // sila hamowania pn + FmaxED += ((p->MoverParameters->Mains) && (p->MoverParameters->ActiveDir != 0) && + (p->MoverParameters->eimc[eimc_p_Fh] * p->MoverParameters->NPoweredAxles > + 0) ? + p->MoverParameters->eimc[eimc_p_Fh] * 1000 : + 0); // chwilowy max ED -> do rozdzialu sil + FED -= Min0R(p->MoverParameters->eimv[eimv_Fmax], 0) * + 1000; // chwilowy max ED -> do rozdzialu sil + FfulED = Min0R(p->MoverParameters->eimv[eimv_Fful], 0) * + 1000; // chwilowy max ED -> do rozdzialu sil + FrED -= Min0R(p->MoverParameters->eimv[eimv_Fr], 0) * + 1000; // chwilowo realizowane ED -> do pneumatyki + Frj += Max0R(p->MoverParameters->eimv[eimv_Fr], 0) * + 1000;// chwilowo realizowany napęd -> do utrzymującego + masa += p->MoverParameters->TotalMass; + osie += p->MoverParameters->NAxles; + } + amax = FmaxPN / masamax; + if ((MoverParameters->Vel < 0.5) && (MoverParameters->BrakePress > 0.2) || + (dDoorMoveL > 0.001) || (dDoorMoveR > 0.001)) + { + MoverParameters->ShuntMode = true; + } + if (MoverParameters->ShuntMode) + { + MoverParameters->ShuntModeAllow = (dDoorMoveL < 0.001) && (dDoorMoveR < 0.001) && + (MoverParameters->LocalBrakeRatio() < 0.01); + } + if ((MoverParameters->Vel > 1) && (dDoorMoveL < 0.001) && (dDoorMoveR < 0.001)) + { + MoverParameters->ShuntMode = false; + MoverParameters->ShuntModeAllow = (MoverParameters->BrakePress > 0.2) && + (MoverParameters->LocalBrakeRatio() < 0.01); + } + Fzad = amax * MoverParameters->LocalBrakeRatio() * masa; + if ((MoverParameters->ScndS) && + (MoverParameters->Vel > MoverParameters->eimc[eimc_p_Vh1]) && (FmaxED > 0)) + { + Fzad = Min0R(MoverParameters->LocalBrakeRatio() * FmaxED, FfulED); + } + if (((MoverParameters->ShuntMode) && (Frj < 0.0015 * masa)) || + (MoverParameters->V * MoverParameters->DirAbsolute < -0.2)) + { + Fzad = Max0R(MoverParameters->StopBrakeDecc * masa, Fzad); + } + + if (MoverParameters->BrakeHandle == MHZ_EN57?MoverParameters->BrakeOpModeFlag & bom_MED:MoverParameters->EpFuse) + FzadED = Min0R(Fzad, FmaxED); + else + FzadED = 0; + FzadPN = Fzad - FrED; + //np = 0; + bool* PrzekrF = new bool[np]; + float nPrzekrF = 0; + bool test = true; + float* FzED = new float[np]; + float* FzEP = new float[np]; + float* FmaxEP = new float[np]; + // 3. ustaw pojazdom sile hamowania ED // - proporcjonalnie do mozliwosci // 4. ustal potrzebne dohamowanie pneumatyczne @@ -2526,8 +2748,142 @@ bool TDynamicObject::Update(double dt, double dt1) // 5. w razie potrzeby wlacz hamulec utrzymujacy // - gdy zahamowany ma ponizej 2 km/h // 6. ustaw pojazdom sile hamowania ep - // - proporcjonalnie do masy, do liczby osi, rowne cisnienia - jak bedzie, tak bedzie - // dobrze + // - proporcjonalnie do masy, do liczby osi, rowne cisnienia - jak + // bedzie, tak bedzie dobrze + float Fpoj = 0; // MoverParameters->ActiveCab < 0 + ////ALGORYTM 2 - KAZDEMU PO ROWNO, ale nie wiecej niz eped * masa + // 1. najpierw daj kazdemu tyle samo + int i = 0; + for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p; + (kier > 0 ? p = p->NextC(4) : p = p->PrevC(4))) + { + float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] - + p->MoverParameters->BrakeCylSpring) * + p->MoverParameters->BrakeCylMult[0] - + p->MoverParameters->BrakeSlckAdj) * + p->MoverParameters->BrakeCylNo * p->MoverParameters->BrakeRigEff; + FmaxEP[i] = Nmax * + p->MoverParameters->Hamulec->GetFC( + Nmax / (p->MoverParameters->NAxles * p->MoverParameters->NBpA), + p->MoverParameters->Vmax) * + 1000; // sila hamowania pn + + PrzekrF[i] = false; + FzED[i] = (FmaxED > 0 ? FzadED / FmaxED : 0); + p->MoverParameters->AnPos = + (MoverParameters->ScndS ? MoverParameters->LocalBrakeRatio() : FzED[i]); + FzEP[i] = FzadPN * p->MoverParameters->NAxles / osie; + i++; + p->MoverParameters->ShuntMode = MoverParameters->ShuntMode; + p->MoverParameters->ShuntModeAllow = MoverParameters->ShuntModeAllow; + } + while (test) + { + test = false; + i = 0; + float przek = 0; + for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p; + (kier > 0 ? p = p->NextC(4) : p = p->PrevC(4))) + { + if ((FzEP[i] > 0.01) && + (FzEP[i] > + p->MoverParameters->TotalMass * p->MoverParameters->eimc[eimc_p_eped] + + Min0R(p->MoverParameters->eimv[eimv_Fr], 0) * 1000) && + (!PrzekrF[i])) + { + float przek1 = -Min0R(p->MoverParameters->eimv[eimv_Fr], 0) * 1000 + + FzEP[i] - + p->MoverParameters->TotalMass * + p->MoverParameters->eimc[eimc_p_eped] * 0.999; + PrzekrF[i] = true; + test = true; + nPrzekrF++; + przek1 = Min0R(przek1, FzEP[i]); + FzEP[i] -= przek1; + if (FzEP[i] < 0) + FzEP[i] = 0; + przek += przek1; + } + i++; + } + i = 0; + przek = przek / (np - nPrzekrF); + for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p; + (kier > 0 ? p = p->NextC(4) : p = p->PrevC(4))) + { + if (!PrzekrF[i]) + { + FzEP[i] += przek; + } + i++; + } + } + i = 0; + for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p; + (kier > 0 ? p = p->NextC(4) : p = p->PrevC(4))) + { + float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] - + p->MoverParameters->BrakeCylSpring) * + p->MoverParameters->BrakeCylMult[0] - + p->MoverParameters->BrakeSlckAdj) * + p->MoverParameters->BrakeCylNo * p->MoverParameters->BrakeRigEff; + float FmaxPoj = Nmax * + p->MoverParameters->Hamulec->GetFC( + Nmax / (p->MoverParameters->NAxles * p->MoverParameters->NBpA), + p->MoverParameters->Vel) * + 1000; // sila hamowania pn + p->MoverParameters->LocalBrakePosA = (p->MoverParameters->SlippingWheels ? 0 : FzEP[i] / FmaxPoj); + if (p->MoverParameters->LocalBrakePosA>0.009) + if (p->MoverParameters->P2FTrans * p->MoverParameters->BrakeCylMult[0] * + p->MoverParameters->MaxBrakePress[0] != 0) + { + float x = (p->MoverParameters->BrakeSlckAdj / p->MoverParameters->BrakeCylMult[0] + + p->MoverParameters->BrakeCylSpring) / (p->MoverParameters->P2FTrans * + p->MoverParameters->MaxBrakePress[0]); + p->MoverParameters->LocalBrakePosA = x + (1 - x) * p->MoverParameters->LocalBrakePosA; + } + else + p->MoverParameters->LocalBrakePosA = p->MoverParameters->LocalBrakePosA; + else + p->MoverParameters->LocalBrakePosA = 0; + i++; + } + /* ////ALGORYTM 1 - KAZDEMU PO ROWNO + for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0); p; + (iDirection > 0 ? p = p->NextC(4) : p = p->PrevC(4))) + { + + float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] - + p->MoverParameters->BrakeCylSpring) * + p->MoverParameters->BrakeCylMult[0] - + p->MoverParameters->BrakeSlckAdj) * + p->MoverParameters->BrakeCylNo * p->MoverParameters->BrakeRigEff; + float FmaxPoj = Nmax * + p->MoverParameters->Hamulec->GetFC( + Nmax / (p->MoverParameters->NAxles * p->MoverParameters->NBpA), + p->MoverParameters->Vel) * + 1000; // sila hamowania pn + // Fpoj=(FED>0?-FzadED*p->MoverParameters->eimv[eimv_Fmax]*1000/FED:0); + // p->MoverParameters->AnPos=(p->MoverParameters->eimc[eimc_p_Fh]>1?0.001f*Fpoj/(p->MoverParameters->eimc[eimc_p_Fh]):0); + p->MoverParameters->AnPos = (FmaxED > 0 ? FzadED / FmaxED : 0); + // Fpoj = FzadPN * Min0R(p->MoverParameters->TotalMass / masa, 1); + // p->MoverParameters->LocalBrakePosA = + // (p->MoverParameters->SlippingWheels ? 0 : Min0R(Max0R(Fpoj / FmaxPoj, 0), 1)); + p->MoverParameters->LocalBrakePosA = (p->MoverParameters->SlippingWheels ? 0 : FzadPN / FmaxPN); + } */ + + MED[0][0] = masa*0.001; + MED[0][1] = amax; + MED[0][2] = Fzad*0.001; + MED[0][3] = FmaxPN*0.001; + MED[0][4] = FmaxED*0.001; + MED[0][5] = FrED*0.001; + MED[0][6] = FzadPN*0.001; + MED[0][7] = nPrzekrF; + + delete[] PrzekrF; + delete[] FzED; + delete[] FzEP; } // yB: cos (AI) tu jest nie kompatybilne z czyms (hamulce) @@ -2546,14 +2902,16 @@ bool TDynamicObject::Update(double dt, double dt1) if ((!MoverParameters->Battery) && (Controller == Humandriver) && (MoverParameters->EngineType != DieselEngine) && (MoverParameters->EngineType != WheelsDriven)) - { // jeśli bateria wyłączona, a nie diesel ani drezyna reczna + { // jeśli bateria wyłączona, a nie diesel ani drezyna + // reczna if (MoverParameters->MainSwitch(false)) // wyłączyć zasilanie MoverParameters->EventFlag = true; } if (MoverParameters->TrainType == dt_ET42) { // powinny być wszystkie dwuczłony oraz EZT /* - //Ra: to jest bez sensu, bo wyłącza WS przy przechodzeniu przez "wewnętrzne" kabiny (z + //Ra: to jest bez sensu, bo wyłącza WS przy przechodzeniu przez + "wewnętrzne" kabiny (z powodu ActiveCab) //trzeba to zrobić inaczej, np. dla członu A sprawdzać, czy jest B //albo sprawdzać w momencie załączania WS i zmiany w sprzęgach @@ -2608,7 +2966,8 @@ bool TDynamicObject::Update(double dt, double dt1) else if (MyTrack->eEnvironment == e_bridge) { vol *= 1.2; - // freq=0.99; //MC: stukot w zaleznosci od tego gdzie + // freq=0.99; //MC: stukot w zaleznosci od + // tego gdzie // jest tor } if (MyTrack->fSoundDistance != dRailLength) @@ -2682,13 +3041,15 @@ bool TDynamicObject::Update(double dt, double dt1) // fragment z EXE Kursa /* if (MoverParameters->TrainType==dt_ET42) { - if ((MoverParameters->DynamicBrakeType=dbrake_switch) && ((MoverParameters->BrakePress > + if ((MoverParameters->DynamicBrakeType=dbrake_switch) && + ((MoverParameters->BrakePress > 0.2) || ( MoverParameters->PipePress < 0.36 ))) { MoverParameters->StLinFlag=true; } else - if ((MoverParameters->DynamicBrakeType=dbrake_switch) && (MoverParameters->BrakePress < + if ((MoverParameters->DynamicBrakeType=dbrake_switch) && + (MoverParameters->BrakePress < 0.1)) { MoverParameters->StLinFlag=false; @@ -2696,7 +3057,8 @@ bool TDynamicObject::Update(double dt, double dt1) } } */ if ((MoverParameters->TrainType == dt_ET40) || (MoverParameters->TrainType == dt_EP05)) - { // dla ET40 i EU05 automatyczne cofanie nastawnika - i tak nie będzie to działać dobrze... + { // dla ET40 i EU05 automatyczne cofanie nastawnika - i tak + // nie będzie to działać dobrze... /* if ((MoverParameters->MainCtrlPos>MoverParameters->MainCtrlActualPos)&&(abs(MoverParameters->Im)>MoverParameters->IminHi)) { @@ -2728,23 +3090,25 @@ bool TDynamicObject::Update(double dt, double dt1) if (dWheelAngle[2] > 360.0) dWheelAngle[2] -= 360.0; } - if (pants) // pantograf może być w wagonie kuchennym albo pojeździe rewizyjnym (np. SR61) + if (pants) // pantograf może być w wagonie kuchennym albo pojeździe rewizyjnym + // (np. SR61) { // przeliczanie kątów dla pantografów double k; // tymczasowy kąt double PantDiff; TAnimPant *p; // wskaźnik do obiektu danych pantografu - double fCurrent = - (MoverParameters->DynamicBrakeFlag && MoverParameters->ResistorsFlag ? - 0 : - fabs(MoverParameters->Itot)) + - MoverParameters - ->TotalCurrent; // prąd pobierany przez pojazd - bez sensu z tym (TotalCurrent) - // fCurrent+=fabs(MoverParameters->Voltage)*1e-6; //prąd płynący przez woltomierz, + double fCurrent = (MoverParameters->DynamicBrakeFlag && MoverParameters->ResistorsFlag ? + 0 : + MoverParameters->Itot) + + MoverParameters->TotalCurrent; // prąd pobierany przez pojazd - bez + // sensu z tym (TotalCurrent) + // TotalCurrent to bedzie prad nietrakcyjny (niezwiazany z napedem) + // fCurrent+=fabs(MoverParameters->Voltage)*1e-6; //prąd płynący przez + // woltomierz, // rozładowuje kondensator orgromowy 4µF double fPantCurrent = fCurrent; // normalnie cały prąd przez jeden pantograf if (pants) - if (iAnimType[ANIM_PANTS] > - 1) // a jeśli są dwa pantografy //Ra 1014-11: proteza, trzeba zrobić sensowniej + if (iAnimType[ANIM_PANTS] > 1) // a jeśli są dwa pantografy //Ra 1014-11: + // proteza, trzeba zrobić sensowniej if (pants[0].fParamPants->hvPowerWire && pants[1].fParamPants->hvPowerWire) // i oba podłączone do drutów fPantCurrent = fCurrent * 0.5; // to dzielimy prąd równo na oba (trochę bez @@ -2783,7 +3147,8 @@ bool TDynamicObject::Update(double dt, double dt1) if ((MoverParameters->PantFrontVolt == 0.0) && (MoverParameters->PantRearVolt == 0.0)) sPantUp.Play(vol, 0, MechInside, vPosition); - if (p->hvPowerWire) // TODO: wyliczyć trzeba prąd przypadający na pantograf i + if (p->hvPowerWire) // TODO: wyliczyć trzeba prąd przypadający na + // pantograf i // wstawić do GetVoltage() { MoverParameters->PantFrontVolt = @@ -2807,7 +3172,8 @@ bool TDynamicObject::Update(double dt, double dt1) if ((MoverParameters->PantRearVolt == 0.0) && (MoverParameters->PantFrontVolt == 0.0)) sPantUp.Play(vol, 0, MechInside, vPosition); - if (p->hvPowerWire) // TODO: wyliczyć trzeba prąd przypadający na pantograf i + if (p->hvPowerWire) // TODO: wyliczyć trzeba prąd przypadający na + // pantograf i // wstawić do GetVoltage() { MoverParameters->PantRearVolt = @@ -2822,9 +3188,11 @@ bool TDynamicObject::Update(double dt, double dt1) break; } // pozostałe na razie nie obsługiwane if (MoverParameters->PantPress > - (MoverParameters->TrainType == dt_EZT ? - 2.5 : - 3.3)) // Ra 2013-12: Niebugocław mówi, że w EZT podnoszą się przy 2.5 + (MoverParameters->TrainType == dt_EZT ? 2.5 : 3.3)) // Ra 2013-12: + // Niebugocław + // mówi, że w EZT + // podnoszą się + // przy 2.5 pantspeedfactor = 0.015 * (MoverParameters->PantPress) * dt1; // z EXE Kursa //Ra: wysokość zależy od ciśnienia !!! else @@ -2836,21 +3204,26 @@ bool TDynamicObject::Update(double dt, double dt1) MoverParameters->PantFrontUp) // jeśli ma być podniesiony { if (PantDiff > 0.001) // jeśli nie dolega do drutu - { // jeśli poprzednia wysokość jest mniejsza niż pożądana, zwiększyć kąt dolnego + { // jeśli poprzednia wysokość jest mniejsza niż pożądana, zwiększyć kąt + // dolnego // ramienia zgodnie z ciśnieniem if (pantspeedfactor > 0.55 * PantDiff) // 0.55 to około pochodna kąta po wysokości k += 0.55 * PantDiff; // ograniczenie "skoku" w danej klatce else k += pantspeedfactor; // dolne ramię - // jeśli przekroczono kąt graniczny, zablokować pantograf (wymaga interwencji + // jeśli przekroczono kąt graniczny, zablokować pantograf (wymaga + // interwencji // pociągu sieciowego) } else if (PantDiff < -0.001) - { // drut się obniżył albo pantograf podniesiony za wysoko + { // drut się obniżył albo pantograf + // podniesiony za wysoko // jeśli wysokość jest zbyt duża, wyznaczyć zmniejszenie kąta - // jeśli zmniejszenie kąta jest zbyt duże, przejść do trybu łamania pantografu - // if (PantFrontDiff<-0.05) //skok w dół o 5cm daje złąmanie pantografu + // jeśli zmniejszenie kąta jest zbyt duże, przejść do trybu łamania + // pantografu + // if (PantFrontDiff<-0.05) //skok w dół o 5cm daje złąmanie + // pantografu k += 0.4 * PantDiff; // mniej niż pochodna kąta po wysokości } // jeśli wysokość jest dobra, nic więcej nie liczyć } @@ -2888,7 +3261,8 @@ bool TDynamicObject::Update(double dt, double dt1) MoverParameters->PantRearSP = true; } if (MoverParameters->EnginePowerSource.SourceType == CurrentCollector) - { // Winger 240404 - wylaczanie sprezarki i przetwornicy przy braku napiecia + { // Winger 240404 - wylaczanie sprezarki i + // przetwornicy przy braku napiecia if (tmpTraction.TractionVoltage == 0) { // to coś wyłączało dźwięk silnika w ST43! MoverParameters->ConverterFlag = false; @@ -2901,7 +3275,8 @@ bool TDynamicObject::Update(double dt, double dt1) if (MoverParameters->EnginePowerSource.PowerType == SteamPower) // if (smPatykird1[0]) { // Ra: animacja rozrządu parowozu, na razie nieoptymalizowane - /* //Ra: tymczasowo wyłączone ze względu na porządkowanie animacji pantografów + /* //Ra: tymczasowo wyłączone ze względu na porządkowanie animacji + pantografów double fi,dx,c2,ka,kc; double sin_fi,cos_fi; double L1=1.6688888888888889; @@ -2913,10 +3288,12 @@ bool TDynamicObject::Update(double dt, double dt1) //ruch tłoków oraz korbowodów for (int i=0;i<=1;++i) {//obie strony w ten sam sposób - fi=DegToRad(dWheelAngle[1]+(i?pant2x:pant1x)); //kąt obrotu koła dla tłoka 1 + fi=DegToRad(dWheelAngle[1]+(i?pant2x:pant1x)); //kąt obrotu koła dla + tłoka 1 sin_fi=sin(fi); cos_fi=cos(fi); - dx=panty*cos_fi+sqrt(panth*panth-panty*panty*sin_fi*sin_fi)-panth; //nieoptymalne + dx=panty*cos_fi+sqrt(panth*panth-panty*panty*sin_fi*sin_fi)-panth; + //nieoptymalne if (smPatykird1[i]) //na razie zabezpieczenie smPatykird1[i]->SetTranslate(float3(dx,0,0)); ka=-asin(panty/panth)*sin_fi; @@ -2924,7 +3301,8 @@ bool TDynamicObject::Update(double dt, double dt1) smPatykirg1[i]->SetRotateXYZ(vector3(RadToDeg(ka),0,0)); //smPatykirg1[0]->SetRotate(float3(0,1,0),RadToDeg(fi)); //obracamy //ruch drążka mimośrodkowego oraz jarzma - //korzystałem z pliku PDF "mm.pdf" (opis czworoboku korbowo-wahaczowego): + //korzystałem z pliku PDF "mm.pdf" (opis czworoboku + korbowo-wahaczowego): //"MECHANIKA MASZYN. Szkic wykładu i laboratorium komputerowego." //Prof. dr hab. inż. Jerzy Zajączkowski, 2007, Politechnika Łódzka //L1 - wysokość (w pionie) osi jarzma ponad osią koła @@ -2938,11 +3316,14 @@ bool TDynamicObject::Update(double dt, double dt1) //G1=(Lr*Lr+L1*L1+L2*L2+Kc*Lc-L*L-2.0*Lc*L2*cos(fi)+2.0*Lc*L1*sin(fi))/(Lr*Lr); //G2=2.0*(L2-Lc*cos(fi))/Lr; //G3=2.0*(L1-Lc*sin(fi))/Lr; - fi=DegToRad(dWheelAngle[1]+(i?pant2x:pant1x)-96.77416667); //kąt obrotu koła dla + fi=DegToRad(dWheelAngle[1]+(i?pant2x:pant1x)-96.77416667); //kąt + obrotu koła dla tłoka 1 - //1) dla dWheelAngle[1]=0° korba jest w dół, a mimośród w stronę jarzma, czyli + //1) dla dWheelAngle[1]=0° korba jest w dół, a mimośród w stronę + jarzma, czyli fi=-7° - //2) dla dWheelAngle[1]=90° korba jest do tyłu, a mimośród w dół, czyli fi=83° + //2) dla dWheelAngle[1]=90° korba jest do tyłu, a mimośród w dół, + czyli fi=83° sin_fi=sin(fi); cos_fi=cos(fi); G1=(1.0+L1*L1+L2*L2+Lc*Lc-L*L-2.0*Lc*L2*cos_fi+2.0*Lc*L1*sin_fi); @@ -2951,17 +3332,23 @@ bool TDynamicObject::Update(double dt, double dt1) G2_2=G2*G2; G3=2.0*(L1-Lc*sin_fi); G3_2=G3*G3; - sin_ksi=(G1*G2-G3*_fm_sqrt(G2_2+G3_2-G1_2))/(G2_2+G3_2); //x1 (minus delta) + sin_ksi=(G1*G2-G3*_fm_sqrt(G2_2+G3_2-G1_2))/(G2_2+G3_2); //x1 (minus + delta) ksi=asin(sin_ksi); //kąt jarzma if (smPatykirg2[i]) - smPatykirg2[i]->SetRotateXYZ(vector3(RadToDeg(ksi),0,0)); //obrócenie jarzma + smPatykirg2[i]->SetRotateXYZ(vector3(RadToDeg(ksi),0,0)); //obrócenie + jarzma //1) ksi=-23°, gam= //2) ksi=10°, gam= - //gam=acos((L2-sin_ksi-Lc*cos_fi)/L); //kąt od poziomu, liczony względem poziomu - //gam=asin((L1-cos_ksi-Lc*sin_fi)/L); //kąt od poziomu, liczony względem pionu - gam=atan2((L1-cos(ksi)+Lc*sin_fi),(L2-sin_ksi+Lc*cos_fi)); //kąt od poziomu + //gam=acos((L2-sin_ksi-Lc*cos_fi)/L); //kąt od poziomu, liczony + względem poziomu + //gam=asin((L1-cos_ksi-Lc*sin_fi)/L); //kąt od poziomu, liczony + względem pionu + gam=atan2((L1-cos(ksi)+Lc*sin_fi),(L2-sin_ksi+Lc*cos_fi)); //kąt od + poziomu if (smPatykird2[i]) //na razie zabezpieczenie - smPatykird2[i]->SetRotateXYZ(vector3(RadToDeg(-gam-ksi),0,0)); //obrócenie drążka + smPatykird2[i]->SetRotateXYZ(vector3(RadToDeg(-gam-ksi),0,0)); + //obrócenie drążka mimośrodowego } */ @@ -2986,13 +3373,17 @@ bool TDynamicObject::Update(double dt, double dt1) } // ABu-160303 sledzenie toru przed obiektem: ******************************* - // Z obserwacji: v>0 -> Coupler 0; v<0 ->coupler1 (Ra: prędkość jest związana z pojazdem) - // Rozroznienie jest tutaj, zeby niepotrzebnie nie skakac do funkcji. Nie jest uzaleznione + // Z obserwacji: v>0 -> Coupler 0; v<0 ->coupler1 (Ra: prędkość jest związana + // z pojazdem) + // Rozroznienie jest tutaj, zeby niepotrzebnie nie skakac do funkcji. Nie jest + // uzaleznione // od obecnosci AI, zeby uwzglednic np. jadace bez lokomotywy wagony. - // Ra: można by przenieść na poziom obiektu reprezentującego skład, aby nie sprawdzać środkowych + // Ra: można by przenieść na poziom obiektu reprezentującego skład, aby nie + // sprawdzać środkowych if (CouplCounter > 25) // licznik, aby nie robić za każdym razem { // poszukiwanie czegoś do zderzenia się - fTrackBlock = 10000.0; // na razie nie ma przeszkód (na wypadek nie uruchomienia skanowania) + fTrackBlock = 10000.0; // na razie nie ma przeszkód (na wypadek nie + // uruchomienia skanowania) // jeśli nie ma zwrotnicy po drodze, to tylko przeliczyć odległość? if (MoverParameters->V > 0.03) //[m/s] jeśli jedzie do przodu (w kierunku Coupler 0) { @@ -3016,7 +3407,8 @@ bool TDynamicObject::Update(double dt, double dt1) ++CouplCounter; // jazda sprzyja poszukiwaniu połączenia else { - CouplCounter = 25; // a bezruch nie, ale trzeba zaktualizować odległość, bo zawalidroga może + CouplCounter = 25; // a bezruch nie, ale trzeba zaktualizować odległość, bo + // zawalidroga może // sobie pojechać } if (MoverParameters->DerailReason > 0) @@ -3089,7 +3481,8 @@ bool TDynamicObject::FastUpdate(double dt) //}; void TDynamicObject::TurnOff() -{ // wyłączenie rysowania submodeli zmiennych dla egemplarza pojazdu +{ // wyłączenie rysowania submodeli zmiennych dla + // egemplarza pojazdu btnOn = false; btCoupler1.TurnOff(); btCoupler2.TurnOff(); @@ -3134,7 +3527,8 @@ void TDynamicObject::Render() if (ObjSqrDist < 500) // jak jest blisko - do 70m modelrotate = 0.01; // mały kąt, żeby nie znikało else - { // Global::pCameraRotation to kąt bewzględny w świecie (zero - na północ) + { // Global::pCameraRotation to kąt bewzględny w świecie (zero - na + // północ) tempangle = (vPosition - Global::pCameraPosition); // wektor od kamery modelrotate = ABuAcos(tempangle); // określenie kąta // if (modelrotate>M_PI) modelrotate-=(2*M_PI); @@ -3164,7 +3558,8 @@ void TDynamicObject::Render() // ActualTrack= GetTrack(); //McZapkie-240702 #if RENDER_CONE - { // Ra: testowe renderowanie pozycji wózków w postaci ostrosłupów, wymaga GLUT32.DLL + { // Ra: testowe renderowanie pozycji wózków w postaci ostrosłupów, wymaga + // GLUT32.DLL double dir = RadToDeg(atan2(vLeft.z, vLeft.x)); Axle0.Render(0); Axle1.Render(1); // bogieRot[0] @@ -3178,11 +3573,13 @@ void TDynamicObject::Render() if (this == Global::pUserDynamic) { // specjalne ustawienie, aby nie trzęsło if (Global::bSmudge) - { // jak jest widoczna smuga, to pojazd renderować po wyrenderowaniu smugi + { // jak jest widoczna smuga, to pojazd renderować po + // wyrenderowaniu smugi glPopMatrix(); // a to trzeba zebrać przed wyjściem return; } - // if (Global::pWorld->) //tu trzeba by ustawić animacje na modelu zewnętrznym + // if (Global::pWorld->) //tu trzeba by ustawić animacje na modelu + // zewnętrznym glLoadIdentity(); // zacząć od macierzy jedynkowej Global::pCamera->SetCabMatrix(vPosition); // specjalne ustawienie kamery } @@ -3234,7 +3631,8 @@ void TDynamicObject::Render() // Ra: dlaczego jest zablokowana w przezroczystych? if (mdKabina) // jeśli ma model kabiny if ((mdKabina != mdModel) && bDisplayCab && FreeFlyModeFlag) - { // rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana + { // rendering kabiny gdy jest oddzielnym modelem i + // ma byc wyswietlana // ABu: tylko w trybie FreeFly, zwykly tryb w world.cpp // Ra: świetła są ustawione dla zewnętrza danego pojazdu // oswietlenie kabiny @@ -3293,7 +3691,9 @@ void TDynamicObject::Render() }; void TDynamicObject::RenderSounds() -{ // przeliczanie dźwięków, bo będzie słychać bez wyświetlania sektora z pojazdem +{ // przeliczanie dźwięków, bo będzie + // słychać bez wyświetlania sektora z + // pojazdem // McZapkie-010302: ulepszony dzwiek silnika double freq; double vol = 0; @@ -3304,10 +3704,11 @@ void TDynamicObject::RenderSounds() if (MoverParameters->Power > 0) { - if ((rsSilnik.AM != 0) && - ((MoverParameters->Mains) || - (MoverParameters->EngineType == - DieselEngine))) // McZapkie-280503: zeby dla dumb dzialal silnik na jalowych obrotach + if ((rsSilnik.AM != 0) && ((MoverParameters->Mains) || (MoverParameters->EngineType == + DieselEngine))) // McZapkie-280503: + // zeby dla dumb + // dzialal silnik na + // jalowych obrotach { if ((fabs(MoverParameters->enrot) > 0.01) || (MoverParameters->EngineType == Dumb)) //&& (MoverParameters->EnginePower>0.1)) @@ -3369,7 +3770,8 @@ void TDynamicObject::RenderSounds() } if ((MoverParameters->DynamicBrakeFlag) && (MoverParameters->EnginePower > 0.1) && (MoverParameters->EngineType == - ElectricSeriesMotor)) // Szociu - 29012012 - jeżeli uruchomiony jest hamulec + ElectricSeriesMotor)) // Szociu - 29012012 - jeżeli uruchomiony + // jest hamulec // elektrodynamiczny, odtwarzany jest dźwięk silnika vol += 0.8; @@ -3449,7 +3851,8 @@ void TDynamicObject::RenderSounds() else rscurve.Stop(); - // McZapkie-280302 - pisk mocno zacisnietych hamulcow - trzeba jeszcze zabezpieczyc przed + // McZapkie-280302 - pisk mocno zacisnietych hamulcow - trzeba jeszcze + // zabezpieczyc przed // brakiem deklaracji w mmedia.dta if (rsPisk.AM != 0) { @@ -3462,10 +3865,23 @@ void TDynamicObject::RenderSounds() else rsPisk.Stop(); } - - // if ((MoverParameters->ConverterFlag==false) && (MoverParameters->TrainType!=dt_ET22)) - // if ((MoverParameters->ConverterFlag==false)&&(MoverParameters->CompressorPower!=0)) - // MoverParameters->CompressorFlag=false; //Ra: wywalić to stąd, tu tylko dla wyświetlanych! + + if (MoverParameters->SandDose) // Dzwiek piasecznicy + sSand.TurnOn(MechInside, GetPosition()); + else + sSand.TurnOff(MechInside, GetPosition()); + sSand.Update(MechInside, GetPosition()); + if (MoverParameters->Hamulec->GetStatus() & b_rls) // Dzwiek odluzniacza + sReleaser.TurnOn(MechInside, GetPosition()); + else + sReleaser.TurnOff(MechInside, GetPosition()); + sReleaser.Update(MechInside, GetPosition()); + // if ((MoverParameters->ConverterFlag==false) && + // (MoverParameters->TrainType!=dt_ET22)) + // if + // ((MoverParameters->ConverterFlag==false)&&(MoverParameters->CompressorPower!=0)) + // MoverParameters->CompressorFlag=false; //Ra: wywalić to stąd, tu tylko dla + // wyświetlanych! // Ra: no to już wiemy, dlaczego pociągi jeżdżą lepiej, gdy się na nie patrzy! // if (MoverParameters->CompressorPower==2) // MoverParameters->CompressorAllow=MoverParameters->ConverterFlag; @@ -3487,8 +3903,8 @@ void TDynamicObject::RenderSounds() // youBy - przenioslem, bo diesel tez moze miec turbo if ((MoverParameters->MainCtrlPos) >= - (MoverParameters - ->TurboTest)) // hunter-250312: dlaczego zakomentowane? Ra: bo nie działało dobrze + (MoverParameters->TurboTest)) // hunter-250312: dlaczego zakomentowane? + // Ra: bo nie działało dobrze { // udawanie turbo: (6.66*(eng_vol-0.85)) if (eng_turbo > 6.66 * (enginevolume - 0.8) + 0.2 * dt) @@ -3736,7 +4152,7 @@ void TDynamicObject::RenderAlpha() mdKabina->RenderAlpha(ObjSqrDist,0); //smierdzi - // mdModel->RenderAlpha(SquareMagnitude(Global::pCameraPosition-pos),0); + // mdModel->RenderAlpha(SquareMagnitude(Global::pCameraPosition-pos),0); glLightfv(GL_LIGHT0,GL_AMBIENT,Global::ambientDayLight); glLightfv(GL_LIGHT0,GL_DIFFUSE,Global::diffuseDayLight); @@ -3809,7 +4225,9 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, asModel = asModel.SubString(1, asModel.Length() - 1); } if ((i = asModel.Pos(",")) > 0) - { // Ra 2015-01: może szukać przecinka w nazwie modelu, a po przecinku była by liczba + { // Ra 2015-01: może szukać przecinka w + // nazwie modelu, a po przecinku była by + // liczba // tekstur? if (i < asModel.Length()) iMultiTex = asModel[i + 1] - '0'; @@ -3818,8 +4236,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, else if (iMultiTex > 1) iMultiTex = 1; // na razie ustawiamy na 1 } - asModel = BaseDir + - asModel; // McZapkie 2002-07-20: dynamics maja swoje modele w dynamics/basedir + asModel = BaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje + // modele w dynamics/basedir Global::asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/... mdModel = TModelsManager::GetModel(asModel.c_str(), true); if (ReplacableSkin != AnsiString("none")) @@ -3924,19 +4342,23 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, iAlpha = 0x31310031; // tekstura -1 z kanałem alfa - nie renderować w cyklu // nieprzezroczystych else - iAlpha = 0x30300030; // wszystkie tekstury nieprzezroczyste - nie renderować w + iAlpha = 0x30300030; // wszystkie tekstury nieprzezroczyste - nie + // renderować w // cyklu przezroczystych if (ReplacableSkinID[2]) if (TTexturesManager::GetAlpha(ReplacableSkinID[2])) - iAlpha |= 0x02020002; // tekstura -2 z kanałem alfa - nie renderować w cyklu + iAlpha |= 0x02020002; // tekstura -2 z kanałem alfa - nie renderować + // w cyklu // nieprzezroczystych if (ReplacableSkinID[3]) if (TTexturesManager::GetAlpha(ReplacableSkinID[3])) - iAlpha |= 0x04040004; // tekstura -3 z kanałem alfa - nie renderować w cyklu + iAlpha |= 0x04040004; // tekstura -3 z kanałem alfa - nie renderować + // w cyklu // nieprzezroczystych if (ReplacableSkinID[4]) if (TTexturesManager::GetAlpha(ReplacableSkinID[4])) - iAlpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować w cyklu + iAlpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować + // w cyklu // nieprzezroczystych } // Winger 040304 - ladowanie przedsionkow dla EZT @@ -3950,7 +4372,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, // if (MoverParameters->LoadAccepted!=AnsiString("")); // && // MoverParameters->LoadType!=AnsiString("passengers")) if (MoverParameters->EnginePowerSource.SourceType == CurrentCollector) - { // wartość niby "pantstate" - nazwa dla formalności, ważna jest ilość + { // wartość niby "pantstate" - nazwa dla + // formalności, ważna jest ilość if (MoverParameters->Load == 1) MoverParameters->PantFront(true); else if (MoverParameters->Load == 2) @@ -3987,10 +4410,14 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, { str = Parser->GetNextSymbol().LowerCase(); if (str == AnsiString("animations:")) - { // Ra: ustawienie ilości poszczególnych animacji - musi być jako pierwsze, inaczej + { // Ra: ustawienie ilości + // poszczególnych animacji - + // musi być jako pierwsze, + // inaczej // ilości będą domyślne if (!pAnimations) - { // jeśli nie ma jeszcze tabeli animacji, można odczytać nowe ilości + { // jeśli nie ma jeszcze tabeli animacji, można + // odczytać nowe ilości int co = 0, ile; iAnimations = 0; do @@ -3999,7 +4426,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, // animacji // if (co==ANIM_PANTS) // if (!Global::bLoadTraction) - // if (!DebugModeFlag) //w debugmode pantografy mają "niby działać" + // if (!DebugModeFlag) //w debugmode pantografy mają "niby + // działać" // ile=0; //wyłączenie animacji pantografów if (co < ANIM_TYPES) if (ile >= 0) @@ -4016,7 +4444,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, // WriteLog("Total animations: "+AnsiString(iAnimations)); } if (!pAnimations) - { // Ra: tworzenie tabeli animacji, jeśli jeszcze nie było + { // Ra: tworzenie tabeli animacji, jeśli jeszcze nie + // było if (!iAnimations) // jeśli nie podano jawnie, ile ma być animacji iAnimations = 28; // tyle było kiedyś w każdym pojeździe (2 wiązary wypadły) /* //pojazd może mieć pantograf do innych celów niż napęd @@ -4038,8 +4467,9 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, pants = pAnimations + k; // zapamiętanie na potrzeby wyszukania submodeli pAnimations[k].iShift = sm; // przesunięcie do przydzielenia wskaźnika - sm += pAnimations[k++].TypeSet( - j); // ustawienie typu animacji i zliczanie tablicowanych submodeli + sm += pAnimations[k++].TypeSet(j); // ustawienie typu animacji i + // zliczanie tablicowanych + // submodeli } if (sm) // o ile są bardziej złożone animacje { @@ -4053,13 +4483,13 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, if (str == AnsiString("lowpolyinterior:")) // ABu: wnetrze lowpoly { asModel = Parser->GetNextSymbol().LowerCase(); - asModel = - BaseDir + - asModel; // McZapkie-200702 - dynamics maja swoje modele w dynamic/basedir + asModel = BaseDir + asModel; // McZapkie-200702 - dynamics maja swoje + // modele w dynamic/basedir Global::asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/... mdLowPolyInt = TModelsManager::GetModel(asModel.c_str(), true); - // Global::asCurrentTexturePath=AnsiString(szTexturePath); //kiedyś uproszczone + // Global::asCurrentTexturePath=AnsiString(szTexturePath); //kiedyś + // uproszczone // wnętrze mieszało tekstury nieba } if (str == AnsiString("brakemode:")) @@ -4093,8 +4523,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, MoverParameters->WheelDiameter; // nie kręcić w większej odległości pAnimations[i].fMaxDist *= pAnimations[i].fMaxDist * - MoverParameters - ->WheelDiameter; // 50m do kwadratu, a średnica do trzeciej + MoverParameters->WheelDiameter; // 50m do kwadratu, a średnica + // do trzeciej pAnimations[i].fMaxDist *= Global::fDistanceFactor; // współczynnik // przeliczeniowy // jakości ekranu @@ -4111,22 +4541,27 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, m = 0; // numer osi; kolejny znak; ile osi danego typu; która średnica if ((MoverParameters->WheelDiameterL != MoverParameters->WheelDiameter) || (MoverParameters->WheelDiameterT != MoverParameters->WheelDiameter)) - { // obsługa różnych średnic, o ile występują + { // obsługa różnych średnic, o + // ile występują while ((i < iAnimType[ANIM_WHEELS]) && (j <= MoverParameters->AxleArangement.Length())) - { // wersja ze wskaźnikami jest bardziej elastyczna na nietypowe układy + { // wersja ze wskaźnikami jest + // bardziej elastyczna na nietypowe + // układy if ((k >= 'A') && (k <= 'J')) // 10 chyba maksimum? { pAnimations[i++].dWheelAngle = dWheelAngle + 1; // obrót osi napędzających - --k; // następna będzie albo taka sama, albo bierzemy kolejny znak + --k; // następna będzie albo taka sama, albo bierzemy kolejny + // znak m = 2; // następujące toczne będą miały inną średnicę } else if ((k >= '1') && (k <= '9')) { pAnimations[i++].dWheelAngle = dWheelAngle + m; // obrót osi // tocznych - --k; // następna będzie albo taka sama, albo bierzemy kolejny znak + --k; // następna będzie albo taka sama, albo bierzemy kolejny + // znak } else k = MoverParameters->AxleArangement[j++]; // pobranie kolejnego @@ -4145,7 +4580,9 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, // } // } else if (str == AnsiString("animpantprefix:")) - { // Ra: pantografy po nowemu mają literki i numerki + { // Ra: pantografy po + // nowemu mają literki + // i numerki } // Pantografy - Winger 160204 if (str == AnsiString("animpantrd1prefix:")) @@ -4155,7 +4592,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, TSubModel *sm; if (pants) for (int i = 0; i < iAnimType[ANIM_PANTS]; i++) - { // Winger 160204: wyszukiwanie max 2 patykow o nazwie str* + { // Winger 160204: wyszukiwanie max 2 patykow o nazwie + // str* asAnimName = str + AnsiString(i + 1); sm = mdModel->GetFromName(asAnimName.c_str()); pants[i].smElement[0] = sm; // jak NULL, to nie będzie animowany @@ -4163,9 +4601,11 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, { // w EP09 wywalało się tu z powodu NULL sm->WillBeAnimated(); sm->ParentMatrix(&m); // pobranie macierzy transformacji - // m(3)[1]=m[3][1]+0.054; //w górę o wysokość ślizgu (na razie tak) + // m(3)[1]=m[3][1]+0.054; //w górę o wysokość ślizgu (na razie + // tak) if ((mdModel->Flags() & 0x8000) == 0) // jeśli wczytano z T3D - m.InitialRotate(); // może być potrzebny dodatkowy obrót, jeśli + m.InitialRotate(); // może być potrzebny dodatkowy obrót, + // jeśli // wczytano z T3D, tzn. przed wykonaniem // Init() pants[i].fParamPants->vPos.z = @@ -4173,7 +4613,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, pants[i].fParamPants->vPos.y = m[3][1]; // przesunięcie w górę odczytane z modelu if ((sm = pants[i].smElement[0]->ChildGet()) != NULL) - { // jeśli ma potomny, można policzyć długość (odległość potomnego + { // jeśli ma potomny, można policzyć długość + // (odległość potomnego // od osi obrotu) m = float4x4(*sm->GetMatrix()); // wystarczyłby wskaźnik, nie // trzeba kopiować @@ -4195,7 +4636,9 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, pants[i].fParamPants->fAngleL0; // początkowy kąt dolnego // ramienia if ((sm = sm->ChildGet()) != NULL) - { // jeśli dalej jest ślizg, można policzyć długość górnego + { // jeśli dalej jest + // ślizg, można policzyć + // długość górnego // ramienia m = float4x4(*sm->GetMatrix()); // wystarczyłby wskaźnik, // nie trzeba kopiować @@ -4276,7 +4719,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, TSubModel *sm; if (pants) for (int i = 0; i < iAnimType[ANIM_PANTS]; i++) - { // Winger 160204: wyszukiwanie max 2 patykow o nazwie str* + { // Winger 160204: wyszukiwanie max 2 patykow o nazwie + // str* asAnimName = str + AnsiString(i + 1); sm = mdModel->GetFromName(asAnimName.c_str()); pants[i].smElement[1] = sm; // jak NULL, to nie będzie animowany @@ -4284,7 +4728,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, { // w EP09 wywalało się tu z powodu NULL sm->WillBeAnimated(); if (pants[i].fParamPants->vPos.y == 0.0) - { // jeśli pierwsze ramię nie ustawiło tej wartości, próbować drugim + { // jeśli pierwsze ramię nie ustawiło tej wartości, + // próbować drugim //!!!! docelowo zrobić niezależną animację ramion z każdej // strony m = float4x4( @@ -4313,7 +4758,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, str = Parser->GetNextSymbol(); if (pants) for (int i = 0; i < iAnimType[ANIM_PANTS]; i++) - { // Winger 160204: wyszukiwanie max 2 patykow o nazwie str* + { // Winger 160204: wyszukiwanie max 2 patykow o nazwie + // str* asAnimName = str + AnsiString(i + 1); pants[i].smElement[2] = mdModel->GetFromName(asAnimName.c_str()); pants[i].smElement[2]->WillBeAnimated(); @@ -4324,7 +4770,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, str = Parser->GetNextSymbol(); if (pants) for (int i = 0; i < iAnimType[ANIM_PANTS]; i++) - { // Winger 160204: wyszukiwanie max 2 patykow o nazwie str* + { // Winger 160204: wyszukiwanie max 2 patykow o nazwie + // str* asAnimName = str + AnsiString(i + 1); pants[i].smElement[3] = mdModel->GetFromName(asAnimName.c_str()); pants[i].smElement[3]->WillBeAnimated(); @@ -4335,7 +4782,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, str = Parser->GetNextSymbol(); if (pants) for (int i = 0; i < iAnimType[ANIM_PANTS]; i++) - { // Winger 160204: wyszukiwanie max 2 patykow o nazwie str* + { // Winger 160204: wyszukiwanie max 2 patykow o nazwie + // str* asAnimName = str + AnsiString(i + 1); pants[i].smElement[4] = mdModel->GetFromName(asAnimName.c_str()); pants[i].smElement[4]->WillBeAnimated(); @@ -4345,7 +4793,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, } } else if (str == AnsiString("pantfactors:")) - { // Winger 010304: parametry pantografow + { // Winger 010304: + // parametry pantografow double pant1x = Parser->GetNextSymbol().ToDouble(); double pant2x = Parser->GetNextSymbol().ToDouble(); double pant1h = Parser->GetNextSymbol().ToDouble(); // wysokość pierwszego @@ -4361,7 +4810,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, } if (pants) for (int i = 0; i < iAnimType[ANIM_PANTS]; ++i) - { // przepisanie współczynników do pantografów (na razie nie będzie lepiej) + { // przepisanie współczynników do pantografów (na razie + // nie będzie lepiej) pants[i].fParamPants->fAngleL = pants[i].fParamPants->fAngleL0; // początkowy kąt dolnego ramienia pants[i].fParamPants->fAngleU = @@ -4370,9 +4820,12 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, // //wysokość początkowa // pants[i].fParamPants->PantWys=1.176289*sin(pants[i].fParamPants->fAngleL)+1.724482197*sin(pants[i].fParamPants->fAngleU); // //wysokość początkowa - if (pants[i].fParamPants->fHeight == - 0.0) // gdy jest nieprawdopodobna wartość (np. nie znaleziony ślizg) - { // gdy pomiary modelu nie udały się, odczyt podanych parametrów z MMD + if (pants[i].fParamPants->fHeight == 0.0) // gdy jest + // nieprawdopodobna + // wartość (np. nie + // znaleziony ślizg) + { // gdy pomiary modelu nie udały się, odczyt podanych parametrów + // z MMD pants[i].fParamPants->vPos.x = (i & 1) ? pant2x : pant1x; pants[i].fParamPants->fHeight = (i & 1) ? pant2h : @@ -4394,7 +4847,10 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, } } else if (str == AnsiString("animpistonprefix:")) - { // prefiks tłoczysk - na razie używamy modeli pantografów + { // prefiks tłoczysk + // - na razie + // używamy modeli + // pantografów str = Parser->GetNextSymbol(); for (int i = 1; i <= 2; i++) { @@ -4404,7 +4860,9 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, } } else if (str == AnsiString("animconrodprefix:")) - { // prefiks korbowodów - na razie używamy modeli pantografów + { // prefiks korbowodów - na + // razie używamy modeli + // pantografów str = Parser->GetNextSymbol(); for (int i = 1; i <= 2; i++) { @@ -4414,20 +4872,30 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, } } else if (str == AnsiString("pistonfactors:")) - { // Ra: parametry silnika parowego (tłoka) - /* //Ra: tymczasowo wyłączone ze względu na porządkowanie animacji pantografów - pant1x=Parser->GetNextSymbol().ToDouble(); //kąt przesunięcia dla + { // Ra: parametry + // silnika parowego + // (tłoka) + /* //Ra: tymczasowo wyłączone ze względu na porządkowanie animacji + pantografów + pant1x=Parser->GetNextSymbol().ToDouble(); //kąt przesunięcia + dla pierwszego tłoka - pant2x=Parser->GetNextSymbol().ToDouble(); //kąt przesunięcia dla + pant2x=Parser->GetNextSymbol().ToDouble(); //kąt przesunięcia + dla drugiego tłoka panty=Parser->GetNextSymbol().ToDouble(); //długość korby (r) - panth=Parser->GetNextSymbol().ToDouble(); //długoś korbowodu (k) + panth=Parser->GetNextSymbol().ToDouble(); //długoś korbowodu + (k) */ MoverParameters->EnginePowerSource.PowerType = SteamPower; // Ra: po chamsku, ale z CHK nie działa } else if (str == AnsiString("animreturnprefix:")) - { // prefiks drążka mimośrodowego - na razie używamy modeli pantografów + { // prefiks drążka + // mimośrodowego - + // na razie używamy + // modeli + // pantografów str = Parser->GetNextSymbol(); for (int i = 1; i <= 2; i++) { @@ -4451,7 +4919,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, str = Parser->GetNextSymbol(); asAnimName = ""; for (int i = 1; i <= 4; i++) - { // McZapkie-050402: wyszukiwanie max 4 wahaczy o nazwie str* + { // McZapkie-050402: wyszukiwanie max 4 + // wahaczy o nazwie str* asAnimName = str + AnsiString(i); smWahacze[i - 1] = mdModel->GetFromName(asAnimName.c_str()); smWahacze[i - 1]->WillBeAnimated(); @@ -4465,7 +4934,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, str = Parser->GetNextSymbol(); smMechanik0 = mdModel->GetFromName(str.c_str()); if (!smMechanik0) - { // jak nie ma bez numerka, to może jest z numerkiem? + { // jak nie ma bez numerka, to może jest z + // numerkiem? smMechanik0 = mdModel->GetFromName(AnsiString(str + "1").c_str()); smMechanik1 = mdModel->GetFromName(AnsiString(str + "2").c_str()); } @@ -4491,7 +4961,9 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, // optymalizacji // transformu switch (MoverParameters->DoorOpenMethod) - { // od razu zapinamy potrzebny typ animacji + { // od razu zapinamy + // potrzebny typ + // animacji case 1: pAnimations[i + j].yUpdate = UpdateDoorTranslate; break; @@ -4501,14 +4973,18 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, case 3: pAnimations[i + j].yUpdate = UpdateDoorFold; break; // obrót 3 kolejnych submodeli - } + case 4: + pAnimations[i + j].yUpdate = UpdateDoorPlug; + break; + } pAnimations[i + j].iNumber = i; // parzyste działają inaczej niż nieparzyste pAnimations[i + j].fMaxDist = 300 * 300; // drzwi to z daleka widać pAnimations[i + j].fSpeed = random(150); // oryginalny koncept z DoorSpeedFactor pAnimations[i + j].fSpeed = (pAnimations[i + j].fSpeed + 100) / 100; - // Ra: te współczynniki są bez sensu, bo modyfikują wektor przesunięcia + // Ra: te współczynniki są bez sensu, bo modyfikują wektor + // przesunięcia } } } @@ -4535,8 +5011,9 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, str = Parser->GetNextSymbol(); } else if ((str == AnsiString("engine:")) && - (MoverParameters->Power > - 0)) // plik z dzwiekiem silnika, mnozniki i ofsety amp. i czest. + (MoverParameters->Power > 0)) // plik z dzwiekiem silnika, + // mnozniki i ofsety amp. i + // czest. { str = Parser->GetNextSymbol(); rsSilnik.Init(str.c_str(), Parser->GetNextSymbol().ToDouble(), GetPosition().x, @@ -4560,7 +5037,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, else if (((str == AnsiString("ventilator:")) && ((MoverParameters->EngineType == ElectricSeriesMotor) || (MoverParameters->EngineType == - ElectricInductionMotor)))) // plik z dzwiekiem wentylatora, mnozniki i + ElectricInductionMotor)))) // plik z dzwiekiem + // wentylatora, mnozniki i // ofsety amp. i czest. { str = Parser->GetNextSymbol(); @@ -4576,7 +5054,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, } else if ((str == AnsiString("transmission:")) && (MoverParameters->EngineType == - ElectricSeriesMotor)) // plik z dzwiekiem, mnozniki i ofsety amp. i czest. + ElectricSeriesMotor)) // plik z dzwiekiem, mnozniki i ofsety + // amp. i czest. { str = Parser->GetNextSymbol(); rsPrzekladnia.Init(str.c_str(), Parser->GetNextSymbol().ToDouble(), @@ -4586,9 +5065,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, rsPrzekladnia.FM = 0.005; rsPrzekladnia.FA = 1.0; } - else if (str == - AnsiString( - "brake:")) // plik z piskiem hamulca, mnozniki i ofsety amplitudy. + else if (str == AnsiString("brake:")) // plik z piskiem hamulca, + // mnozniki i ofsety amplitudy. { str = Parser->GetNextSymbol(); rsPisk.Init(str.c_str(), Parser->GetNextSymbol().ToDouble(), GetPosition().x, @@ -4598,9 +5076,9 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, rsPisk.FM = 1.0; rsPisk.FA = 0.0; } - else if (str == - AnsiString( - "brakeacc:")) // plik z przyspieszaczem (upust po zlapaniu hamowania) + else if (str == AnsiString("brakeacc:")) // plik z przyspieszaczem + // (upust po zlapaniu + // hamowania) { str = Parser->GetNextSymbol(); // sBrakeAcc.Init(str.c_str(),Parser->GetNextSymbol().ToDouble(),GetPosition().x,GetPosition().y,GetPosition().z,true); @@ -4611,9 +5089,9 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, // sBrakeAcc.FM=1.0; // sBrakeAcc.FA=0.0; } - else if (str == - AnsiString( - "unbrake:")) // plik z piskiem hamulca, mnozniki i ofsety amplitudy. + else if (str == AnsiString("unbrake:")) // plik z piskiem hamulca, + // mnozniki i ofsety + // amplitudy. { str = Parser->GetNextSymbol(); rsUnbrake.Init(str.c_str(), Parser->GetNextSymbol().ToDouble(), GetPosition().x, @@ -4694,7 +5172,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, } else if (str == AnsiString("converter:")) // pliki z przetwornica { - // if (MoverParameters->EngineType==DieselElectric) //będzie modulowany? + // if (MoverParameters->EngineType==DieselElectric) //będzie + // modulowany? sConverter.Load(Parser, GetPosition()); } else if (str == AnsiString("turbo:")) // pliki z turbogeneratorem @@ -4725,7 +5204,15 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, rsDoorClose.FM = 1.0; rsDoorClose.FA = 0.0; } - } + else if (str == AnsiString("sand:")) // pliki z piasecznica + { + sSand.Load(Parser, GetPosition()); + } + else if (str == AnsiString("releaser:")) // pliki z odluzniaczem + { + sReleaser.Load(Parser, GetPosition()); + } + } else if (str == AnsiString("internaldata:")) // dalej nie czytaj { while (!Parser->EndOfFile) @@ -4756,7 +5243,8 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, // ABu 050205 - tego wczesniej nie bylo i uciekala pamiec: delete Parser; if (mdModel) - mdModel->Init(); // obrócenie modelu oraz optymalizacja, również zapisanie binarnego + mdModel->Init(); // obrócenie modelu oraz optymalizacja, również zapisanie + // binarnego if (mdLoad) mdLoad->Init(); if (mdPrzedsionek) @@ -4772,21 +5260,97 @@ void TDynamicObject::LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, void TDynamicObject::RadioStop() { // zatrzymanie pojazdu if (Mechanik) // o ile ktoś go prowadzi - if (MoverParameters->SecuritySystem.RadioStop) // jeśli pojazd ma RadioStop i jest on - // aktywny + if (MoverParameters->SecuritySystem.RadioStop && + MoverParameters->Radio) // jeśli pojazd ma RadioStop i jest on aktywny Mechanik->PutCommand("Emergency_brake", 1.0, 1.0, &vPosition, stopRadio); }; +//--------------------------------------------------------------------------- +void TDynamicObject::Damage(char flag) +{ + if (flag & 1) //różnicówka nie robi nic + { + MoverParameters->MainSwitch(false); + MoverParameters->FuseOff(); + } + else + { + } + + if (flag & 2) //usterka sterowania + { + MoverParameters->StLinFlag = false; + if (MoverParameters->InitialCtrlDelay<100000000) + MoverParameters->InitialCtrlDelay += 100000001; + } + else + { + if (MoverParameters->InitialCtrlDelay>100000000) + MoverParameters->InitialCtrlDelay -= 100000001; + } + + if (flag & 4) //blokada przetwornicy + { + MoverParameters->ConvOvldFlag = true; + } + else + { + } + + if (flag & 8) //blokada sprezarki + { + if (MoverParameters->MinCompressor>0) + MoverParameters->MinCompressor -= 100000001; + if (MoverParameters->MaxCompressor>0) + MoverParameters->MaxCompressor -= 100000001; + } + else + { + if (MoverParameters->MinCompressor<0) + MoverParameters->MinCompressor += 100000001; + if (MoverParameters->MaxCompressor<0) + MoverParameters->MaxCompressor += 100000001; + } + + if (flag & 16) //blokada wału + { + if (MoverParameters->CtrlDelay<100000000) + MoverParameters->CtrlDelay += 100000001; + if (MoverParameters->CtrlDownDelay<100000000) + MoverParameters->CtrlDownDelay += 100000001; + } + else + { + if (MoverParameters->CtrlDelay>100000000) + MoverParameters->CtrlDelay -= 100000001; + if (MoverParameters->CtrlDownDelay>100000000) + MoverParameters->CtrlDownDelay -= 100000001; + } + + if (flag & 32) //hamowanie nagŁe + { + } + else + { + } + + MoverParameters->EngDmgFlag = flag; +}; + void TDynamicObject::RaLightsSet(int head, int rear) -{ // zapalenie świateł z przodu i z tyłu, zależne od kierunku pojazdu +{ // zapalenie świateł z przodu i z + // tyłu, zależne od kierunku + // pojazdu if (!MoverParameters) return; // może tego nie być na początku if (rear == 2 + 32 + 64) - { // jeśli koniec pociągu, to trzeba ustalić, czy jest tam czynna lokomotywa + { // jeśli koniec pociągu, to trzeba ustalić, czy + // jest tam czynna lokomotywa // EN57 może nie mieć końcówek od środka członu if (MoverParameters->Power > 1.0) // jeśli ma moc napędową if (!MoverParameters->ActiveDir) // jeśli nie ma ustawionego kierunku - { // jeśli ma zarówno światła jak i końcówki, ustalić, czy jest w stanie aktywnym + { // jeśli ma zarówno światła jak i końcówki, ustalić, czy jest w stanie + // aktywnym // np. lokomotywa na zimno będzie mieć końcówki a nie światła rear = 64; // tablice blaszane // trzeba to uzależnić od "załączenia baterii" w pojeździe @@ -4819,7 +5383,8 @@ int TDynamicObject::DirectionSet(int d) iDirection = d > 0 ? 1 : 0; // d:1=zgodny,-1=przeciwny; iDirection:1=zgodny,0=przeciwny; CouplCounter = 20; //żeby normalnie skanować kolizje, to musi ruszyć z miejsca if (MyTrack) - { // podczas wczytywania wstawiane jest AI, ale może jeszcze nie być toru + { // podczas wczytywania wstawiane jest AI, ale może jeszcze nie + // być toru // AI ustawi kierunek ponownie po uruchomieniu silnika if (iDirection) // jeśli w kierunku Coupler 0 { @@ -4835,30 +5400,39 @@ int TDynamicObject::DirectionSet(int d) // następnego }; -TDynamicObject *__fastcall TDynamicObject::PrevAny() -{ // wskaźnik na poprzedni, nawet wirtualny +TDynamicObject * TDynamicObject::PrevAny() +{ // wskaźnik na poprzedni, + // nawet wirtualny return iDirection ? PrevConnected : NextConnected; }; -TDynamicObject *__fastcall TDynamicObject::Prev() +TDynamicObject * TDynamicObject::Prev() { if (MoverParameters->Couplers[iDirection ^ 1].CouplingFlag) return iDirection ? PrevConnected : NextConnected; return NULL; // gdy sprzęg wirtualny, to jakby nic nie było }; -TDynamicObject *__fastcall TDynamicObject::Next() +TDynamicObject * TDynamicObject::Next() { if (MoverParameters->Couplers[iDirection].CouplingFlag) return iDirection ? NextConnected : PrevConnected; return NULL; // gdy sprzęg wirtualny, to jakby nic nie było }; -TDynamicObject *__fastcall TDynamicObject::NextC(int C) +TDynamicObject * TDynamicObject::PrevC(int C) +{ + if (MoverParameters->Couplers[iDirection ^ 1].CouplingFlag & C) + return iDirection ? PrevConnected : NextConnected; + return NULL; // gdy sprzęg wirtualny, to jakby nic nie było +}; +TDynamicObject * TDynamicObject::NextC(int C) { if (MoverParameters->Couplers[iDirection].CouplingFlag & C) return iDirection ? NextConnected : PrevConnected; return NULL; // gdy sprzęg inny, to jakby nic nie było }; double TDynamicObject::NextDistance(double d) -{ // ustalenie odległości do następnego pojazdu, potrzebne do wstecznego skanowania +{ // ustalenie odległości do + // następnego pojazdu, potrzebne + // do wstecznego skanowania if (!MoverParameters->Couplers[iDirection].Connected) return d; // jeśli nic nie ma, zwrócenie domyślnej wartości if ((d <= 0.0) || (MoverParameters->Couplers[iDirection].CoupleDist < d)) @@ -4867,8 +5441,9 @@ double TDynamicObject::NextDistance(double d) return d; }; -TDynamicObject *__fastcall TDynamicObject::Neightbour(int &dir) -{ // ustalenie następnego (1) albo poprzedniego (0) w składzie bez względu na prawidłowość +TDynamicObject * TDynamicObject::Neightbour(int &dir) +{ // ustalenie następnego (1) albo poprzedniego (0) w składzie bez + // względu na prawidłowość // iDirection int d = dir; // zapamiętanie kierunku dir = 1 - (dir ? NextConnectedNo : PrevConnectedNo); // nowa wartość @@ -4886,7 +5461,8 @@ void TDynamicObject::CoupleDist() else { // na drodze trzeba uwzględnić wektory ruchu double d0 = MoverParameters->Couplers[0].CoupleDist; - // double d1=MoverParameters->Couplers[1].CoupleDist; //sprzęg z tyłu samochodu można olać, + // double d1=MoverParameters->Couplers[1].CoupleDist; //sprzęg z tyłu + // samochodu można olać, // dopóki nie jeździ na wstecznym vector3 p1, p2; double d, w; // dopuszczalny dystans w poprzek @@ -4894,10 +5470,12 @@ void TDynamicObject::CoupleDist() if (MoverParameters->Couplers[0].Connected) // jeśli cokolwiek podłączone if (MoverParameters->Couplers[0].CouplingFlag == 0) // jeśli wirtualny if (MoverParameters->Couplers[0].CoupleDist < 300.0) // i mniej niż 300m - { // przez MoverParameters->Couplers[0].Connected nie da się dostać do DynObj, stąd + { // przez MoverParameters->Couplers[0].Connected nie da się dostać do + // DynObj, stąd // prowizorka // WriteLog("Collision of - // "+AnsiString(MoverParameters->Couplers[0].CoupleDist)+"m detected by + // "+AnsiString(MoverParameters->Couplers[0].CoupleDist)+"m detected + // by // "+asName+":0."); w = 0.5 * (MoverParameters->Couplers[0].Connected->Dim.W + MoverParameters->Dim.W); // minimalna odległość minięcia @@ -4918,7 +5496,8 @@ void TDynamicObject::CoupleDist() if (MoverParameters->Couplers[1].CoupleDist < 300.0) // i mniej niż 300m { // WriteLog("Collision of - // "+AnsiString(MoverParameters->Couplers[1].CoupleDist)+"m detected by + // "+AnsiString(MoverParameters->Couplers[1].CoupleDist)+"m detected + // by // "+asName+":1."); w = 0.5 * (MoverParameters->Couplers[1].Connected->Dim.W + MoverParameters->Dim.W); // minimalna odległość minięcia @@ -4937,30 +5516,42 @@ void TDynamicObject::CoupleDist() } }; -TDynamicObject *__fastcall TDynamicObject::ControlledFind() -{ // taka proteza: chcę podłączyć kabinę EN57 bezpośrednio z silnikowym, aby nie robić tego przez +TDynamicObject * TDynamicObject::ControlledFind() +{ // taka proteza: + // chcę podłączyć + // kabinę EN57 + // bezpośrednio z + // silnikowym, aby + // nie robić tego + // przez // ukrotnienie // drugi silnikowy i tak musi być ukrotniony, podobnie jak kolejna jednostka - // lepiej by było przesyłać komendy sterowania, co jednak wymaga przebudowy transmisji komend + // lepiej by było przesyłać komendy sterowania, co jednak wymaga przebudowy + // transmisji komend // (LD) - // problem się robi ze światłami, które będą zapalane w silnikowym, ale muszą świecić się w + // problem się robi ze światłami, które będą zapalane w silnikowym, ale muszą + // świecić się w + // rozrządczych + // dla EZT światłą czołowe będą "zapalane w silnikowym", ale widziane z // rozrządczych - // dla EZT światłą czołowe będą "zapalane w silnikowym", ale widziane z rozrządczych // również wczytywanie MMD powinno dotyczyć aktualnego członu // problematyczna może być kwestia wybranej kabiny (w silnikowym...) - // jeśli silnikowy będzie zapięty odwrotnie (tzn. -1), to i tak powinno jeździć dobrze + // jeśli silnikowy będzie zapięty odwrotnie (tzn. -1), to i tak powinno + // jeździć dobrze // również hamowanie wykonuje się zaworem w członie, a nie w silnikowym... TDynamicObject *d = this; // zaczynamy od aktualnego if (d->MoverParameters->TrainType & dt_EZT) // na razie dotyczy to EZT if (d->NextConnected ? d->MoverParameters->Couplers[1].AllowedFlag & ctrain_depot : false) - { // gdy jest człon od sprzęgu 1, a sprzęg łączony warsztatowo (powiedzmy) + { // gdy jest człon od sprzęgu 1, a sprzęg łączony + // warsztatowo (powiedzmy) if ((d->MoverParameters->Power < 1.0) && (d->NextConnected->MoverParameters->Power > 1.0)) // my nie mamy mocy, ale ten drugi ma d = d->NextConnected; // będziemy sterować tym z mocą } else if (d->PrevConnected ? d->MoverParameters->Couplers[0].AllowedFlag & ctrain_depot : false) - { // gdy jest człon od sprzęgu 0, a sprzęg łączony warsztatowo (powiedzmy) + { // gdy jest człon od sprzęgu 0, a sprzęg łączony + // warsztatowo (powiedzmy) if ((d->MoverParameters->Power < 1.0) && (d->PrevConnected->MoverParameters->Power > 1.0)) // my nie mamy mocy, ale ten drugi ma d = d->PrevConnected; // będziemy sterować tym z mocą @@ -4973,9 +5564,10 @@ void TDynamicObject::ParamSet(int what, int into) { // ustawienie lokalnego parametru (what) na stan (into) switch (what & 0xFF00) { - case 0x0100: // to np. są drzwi, bity 0..7 określają numer 1..254 albo maskę dla 8 różnych - if (what & - 1) // na razie mamy lewe oraz prawe, czyli używamy maskę 1=lewe, 2=prawe, 3=wszystkie + case 0x0100: // to np. są drzwi, bity 0..7 określają numer 1..254 albo maskę + // dla 8 różnych + if (what & 1) // na razie mamy lewe oraz prawe, czyli używamy maskę 1=lewe, + // 2=prawe, 3=wszystkie if (MoverParameters->DoorLeftOpened) { // są otwarte if (!into) // jeśli zamykanie @@ -5010,7 +5602,9 @@ void TDynamicObject::ParamSet(int what, int into) }; int TDynamicObject::RouteWish(TTrack *tr) -{ // zapytanie do AI, po którym segmencie (-6..6) jechać na skrzyżowaniu (tr) +{ // zapytanie do AI, po którym + // segmencie (-6..6) jechać na + // skrzyżowaniu (tr) return Mechanik ? Mechanik->CrossRoute(tr) : 0; // wg AI albo prosto }; @@ -5035,10 +5629,14 @@ AnsiString TDynamicObject::TextureTest(AnsiString &name) }; void TDynamicObject::DestinationSet(AnsiString to) -{ // ustawienie stacji docelowej oraz wymiennej tekstury 4, jeśli istnieje plik +{ // ustawienie stacji + // docelowej oraz wymiennej + // tekstury 4, jeśli + // istnieje plik // w zasadzie, to każdy wagon mógłby mieć inną stację docelową // zwłaszcza w towarowych, pod kątem zautomatyzowania maewrów albo pracy górki - // ale to jeszcze potrwa, zanim będzie możliwe, na razie można wpisać stację z rozkładu + // ale to jeszcze potrwa, zanim będzie możliwe, na razie można wpisać stację z + // rozkładu if (abs(iMultiTex) >= 4) return; // jak są 4 tekstury wymienne, to nie zmieniać rozkładem asDestination = to; @@ -5060,11 +5658,14 @@ void TDynamicObject::DestinationSet(AnsiString to) NULL, NULL, x.c_str(), 9); // rozmywania 0,1,4,5 nie nadają się else ReplacableSkinID[4] = 0; // 0 to brak? -1 odpada, bo inaczej się będzie mapować - // Ra 2015-01: żeby zalogować błąd, trzeba by mieć pewność, że model używa tekstury nr 4 + // Ra 2015-01: żeby zalogować błąd, trzeba by mieć pewność, że model używa + // tekstury nr 4 }; void TDynamicObject::OverheadTrack(float o) -{ // ewentualne wymuszanie jazdy bezprądowej z powodu informacji w torze +{ // ewentualne wymuszanie jazdy + // bezprądowej z powodu informacji + // w torze if (ctOwner) // jeśli ma obiekt nadzorujący { // trzeba zaktualizować mapę flag bitowych jazdy bezprądowej if (o < 0.0) diff --git a/DynObj.h b/DynObj.h index 854e1a466..273de04e3 100644 --- a/DynObj.h +++ b/DynObj.h @@ -157,7 +157,7 @@ class TDynamicObject float fAxleDist; // rozstaw wózków albo osi do liczenia proporcji zacienienia vector3 modelRot; // obrot pudła względem świata - do przeanalizowania, czy potrzebne!!! // bool bCameraNear; //blisko kamer są potrzebne dodatkowe obliczenia szczegółów - TDynamicObject *__fastcall ABuFindNearestObject(TTrack *Track, TDynamicObject *MyPointer, + TDynamicObject * ABuFindNearestObject(TTrack *Track, TDynamicObject *MyPointer, int &CouplNr); public: // parametry położenia pojazdu dostępne publicznie @@ -197,7 +197,8 @@ class TDynamicObject void UpdateDoorTranslate(TAnim *pAnim); // animacja drzwi - przesuw void UpdateDoorRotate(TAnim *pAnim); // animacja drzwi - obrót void UpdateDoorFold(TAnim *pAnim); // animacja drzwi - składanie - void UpdatePant(TAnim *pAnim); // animacja pantografu + void UpdateDoorPlug(TAnim *pAnim); // animacja drzwi - odskokowo-przesuwne + void UpdatePant(TAnim *pAnim); // animacja pantografu void UpdateLeverDouble(TAnim *pAnim); // animacja gałki zależna od double void UpdateLeverFloat(TAnim *pAnim); // animacja gałki zależna od float void UpdateLeverInt(TAnim *pAnim); // animacja gałki zależna od int (wartość) @@ -286,6 +287,8 @@ class TDynamicObject TAdvancedSound sSmallCompressor; TAdvancedSound sDepartureSignal; TAdvancedSound sTurbo; + TAdvancedSound sSand; + TAdvancedSound sReleaser; // Winger 010304 // TRealSound rsPanTup; //PSound sPantUp; @@ -325,7 +328,7 @@ class TDynamicObject void ABuScanObjects(int ScanDir, double ScanDist); protected: - TDynamicObject *__fastcall ABuFindObject(TTrack *Track, int ScanDir, Byte &CouplFound, + TDynamicObject * ABuFindObject(TTrack *Track, int ScanDir, Byte &CouplFound, double &dist); void ABuCheckMyTrack(); @@ -333,10 +336,11 @@ class TDynamicObject int *iLights; // wskaźnik na bity zapalonych świateł (własne albo innego członu) double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym // pojazdem) - TDynamicObject *__fastcall PrevAny(); - TDynamicObject *__fastcall Prev(); - TDynamicObject *__fastcall Next(); - TDynamicObject *__fastcall NextC(int C); + TDynamicObject * PrevAny(); + TDynamicObject * Prev(); + TDynamicObject * Next(); + TDynamicObject * PrevC(int C); + TDynamicObject * NextC(int C); double NextDistance(double d = -1.0); void SetdMoveLen(double dMoveLen) { @@ -367,9 +371,9 @@ class TDynamicObject // float EmR; // vector3 smokeoffset; - TDynamicObject *__fastcall ABuScanNearestObject(TTrack *Track, double ScanDir, double ScanDist, + TDynamicObject * ABuScanNearestObject(TTrack *Track, double ScanDir, double ScanDist, int &CouplNr); - TDynamicObject *__fastcall GetFirstDynamic(int cpl_type); + TDynamicObject * GetFirstDynamic(int cpl_type, int cf = 1); // TDynamicObject* GetFirstCabDynamic(int cpl_type); void ABuSetModelShake(vector3 mShake); @@ -435,7 +439,7 @@ class TDynamicObject { return vLeft; }; - inline double *__fastcall Matrix() + inline double * Matrix() { return mMatrix.getArray(); }; @@ -451,7 +455,7 @@ class TDynamicObject { return MoverParameters->Dim.W; }; - inline TTrack *__fastcall GetTrack() + inline TTrack * GetTrack() { return (iAxleFirst ? Axle1.GetTrack() : Axle0.GetTrack()); }; @@ -476,15 +480,16 @@ class TDynamicObject { // zwraca przesunięcie wózka względem Point1 toru z aktywną osią return iAxleFirst ? Axle1.GetTranslation() : Axle0.GetTranslation(); }; - inline TTrack *__fastcall RaTrackGet() + inline TTrack * RaTrackGet() { // zwraca tor z aktywną osią return iAxleFirst ? Axle1.GetTrack() : Axle0.GetTrack(); }; void CouplersDettach(double MinDist, int MyScanDir); void RadioStop(); - void RaLightsSet(int head, int rear); + void Damage(char flag); + void RaLightsSet(int head, int rear); // void RaAxleEvent(TEvent *e); - TDynamicObject *__fastcall FirstFind(int &coupler_nr); + TDynamicObject * FirstFind(int &coupler_nr, int cf = 1); float GetEPP(); // wyliczanie sredniego cisnienia w PG int DirectionSet(int d); // ustawienie kierunku w składzie int DirectionGet() @@ -493,15 +498,16 @@ class TDynamicObject }; // odczyt kierunku w składzie int DettachStatus(int dir); int Dettach(int dir); - TDynamicObject *__fastcall Neightbour(int &dir); + TDynamicObject * Neightbour(int &dir); void CoupleDist(); - TDynamicObject *__fastcall ControlledFind(); + TDynamicObject * ControlledFind(); void ParamSet(int what, int into); int RouteWish(TTrack *tr); // zapytanie do AI, po którym segmencie skrzyżowania // jechać void DestinationSet(AnsiString to); AnsiString TextureTest(AnsiString &name); void OverheadTrack(float o); + double MED[9][8]; // lista zmiennych do debugowania hamulca ED }; //--------------------------------------------------------------------------- diff --git a/EU07.bpr b/EU07.bpr index 61f494f1d..30c44f0e8 100644 --- a/EU07.bpr +++ b/EU07.bpr @@ -3,23 +3,24 @@ - + + McZapkie\hamulce.obj McZapkie\Oerlikon_ESt.obj EU07.obj dumb3d.obj + Camera.obj Texture.obj World.obj Model3d.obj MdlMngr.obj Train.obj + wavread.obj Timer.obj Event.obj MemCell.obj Logs.obj Spring.obj Button.obj + Globals.obj Gauge.obj AnimModel.obj Ground.obj TrkFoll.obj Segment.obj + Sound.obj AdvSound.obj Track.obj DynObj.obj RealSound.obj EvLaunch.obj + FadeSound.obj Traction.obj TractionPower.obj parser.obj sky.obj + AirCoupler.obj opengl\glew.obj ResourceManager.obj VBO.obj TextureDDS.obj + opengl\ARB_Multisample.obj Float3d.obj Classes.obj Driver.obj Names.obj + Console.obj Mover.obj Console\PoKeys55.obj Forth.obj Console\LPT.obj + PyInt.obj"/> - + @@ -33,15 +34,15 @@ - - + + - - + + @@ -56,10 +57,10 @@ [Version Info] IncludeVerInfo=1 AutoIncBuild=0 -MajorVer=15 -MinorVer=3 -Release=1167 -Build=470 +MajorVer=16 +MinorVer=0 +Release=1172 +Build=475 Debug=1 PreRelease=0 Special=0 @@ -71,22 +72,31 @@ CodePage=1250 [Version Info Keys] CompanyName=EU07 Team FileDescription=MaSzyna EU07-424 -FileVersion=15.3.1167.470 -InternalName=9th by firleju + SPKS + MP +FileVersion=16.0.1172.475 +InternalName=10th exe + SPKS + asynch + python LegalCopyright= LegalTrademarks= OriginalFilename=eu07.exe ProductName=MaSzyna EU07-424 -ProductVersion=15.3 +ProductVersion=16.0 Comments= +[Excluded Packages] +$(BCB)\Bin\bcbsmp50.bpl=Borland C++ Sample Components +$(BCB)\Bin\dclqrt50.bpl=QuickReport Components +C:\Windows\system32\ibsmp50.bpl=Borland C++ InterBase Alerter Component +$(BCB)\Bin\dcltee50.bpl=TeeChart 5.0 Components +$(BCB)\Bin\applet50.bpl=Borland Control Panel Applet Package + [HistoryLists\hlIncludePath] -Count=1 -Item0=Console;opengl;McZapkie;$(BCB)\include;$(BCB)\include\vcl +Count=2 +Item0=Console;opengl;McZapkie;$(BCB)\include;$(BCB)\include\vcl;python\include +Item1=Console;opengl;McZapkie;$(BCB)\include;$(BCB)\include\vcl [HistoryLists\hlLibraryPath] -Count=1 -Item0=Console;opengl;McZapkie;$(BCB)\lib\obj;$(BCB)\lib +Count=2 +Item0=Console;opengl;McZapkie;$(BCB)\lib\obj;$(BCB)\lib;python\libs +Item1=Console;opengl;McZapkie;$(BCB)\lib\obj;$(BCB)\lib [HistoryLists\hlDebugSourcePath] Count=2 @@ -96,24 +106,26 @@ Item1=$(BCB)\source\vcl [HistoryLists\hlConditionals] Count=8 Item0=GLEW_STATIC;_DEBUG -Item1=GLEW_STATIC;_DEBUG;USE_VBO -Item2=GLEW_STATIC;_DEBUG;_USE_OLD_RW_STL -Item3=GLEW_STATIC +Item1=GLEW_STATIC +Item2=GLEW_STATIC;_DEBUG;USE_VBO +Item3=GLEW_STATIC;_DEBUG;_USE_OLD_RW_STL Item4=GLEW_STATIC;USE_VERTEX_ARRAYS;_DEBUG Item5=GLEW_STATIC;USE_VERTEX_ARRAYS Item6=GLEW_STATIC;_DEBUG;USE_VERTEX_ARRAYS Item7=_DEBUG [HistoryLists\hlFinalOutputDir] -Count=2 -Item0=D:\EU07\ -Item1=E:\EU07\ +Count=4 +Item0=E:\Gry\MaSzyna_15_04\ +Item1=E:\Gry\MaSzyna_15_04 +Item2=D:\EU07\ +Item3=E:\EU07\ [Debugging] DebugSourceDirs=McZapkie\ [Parameters] -RunParams= +RunParams=-s $.scn -v EN57AKL-1ra HostApplication= RemoteHost= RemotePath= diff --git a/EU07.cpp b/EU07.cpp index bdfadfa60..21c95236c 100644 --- a/EU07.cpp +++ b/EU07.cpp @@ -11,7 +11,11 @@ obtain one at Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others */ - +/* +Authors: +MarcinW, McZapkie, Shaxbee, ABu, nbmx, youBy, Ra, winger, mamut, Q424, +Stele, firleju, szociu, hunter, ZiomalCl and others +*/ #include "opengl/glew.h" #include "opengl/glut.h" #include "opengl/ARB_Multisample.h" @@ -33,6 +37,7 @@ USEUNIT("Camera.cpp"); USEUNIT("Texture.cpp"); USEUNIT("World.cpp"); USELIB("opengl\glut32.lib"); +USELIB("omf_python27.lib"); USEUNIT("Model3d.cpp"); USEUNIT("MdlMngr.cpp"); USEUNIT("Train.cpp"); @@ -77,9 +82,11 @@ USEUNIT("Console.cpp"); USEUNIT("Mover.cpp"); USEUNIT("McZapkie\_mover.pas"); USEUNIT("McZapkie\hamulce.pas"); +USEUNIT("McZapkie\Oerlikon_ESt.pas"); USEUNIT("Console\PoKeys55.cpp"); USEUNIT("Forth.cpp"); USEUNIT("Console\LPT.cpp"); +USEUNIT("PyInt.cpp"); //--------------------------------------------------------------------------- #include "World.h" diff --git a/EU07.res b/EU07.res index b7e359bdc..210268342 100644 Binary files a/EU07.res and b/EU07.res differ diff --git a/Event.cpp b/Event.cpp index fc3265dfc..d66df9bf5 100644 --- a/Event.cpp +++ b/Event.cpp @@ -338,16 +338,26 @@ void TEvent::Load(cParser *parser, vector3 *org) bEnabled = false; Params[6].asCommand = cm_SetVelocity; } - else if (str == "ShuntVelocity") + else if (str == "RoadVelocity") { bEnabled = false; - Params[6].asCommand = cm_ShuntVelocity; + Params[6].asCommand = cm_RoadVelocity; } - else if (str == "SetProximityVelocity") + else if (str == "SectionVelocity") { bEnabled = false; - Params[6].asCommand = cm_SetProximityVelocity; + Params[6].asCommand = cm_SectionVelocity; + } + else if (str == "ShuntVelocity") + { + bEnabled = false; + Params[6].asCommand = cm_ShuntVelocity; } + //else if (str == "SetProximityVelocity") + //{ + // bEnabled = false; + // Params[6].asCommand = cm_SetProximityVelocity; + //} else if (str == "OutsideStation") { bEnabled = false; // ma być skanowny, aby AI nie przekraczało W5 diff --git a/Float3d.h b/Float3d.h index 4e0fc10aa..a6bbb376f 100644 --- a/Float3d.h +++ b/Float3d.h @@ -192,11 +192,11 @@ class float4x4 for (int i = 0; i < 16; ++i) e[i] = f[i]; }; - float *__fastcall operator()(int i) + float * operator()(int i) { return &e[i << 2]; } - const float *__fastcall readArray(void) + const float * readArray(void) { return e; } diff --git a/Gauge.cpp b/Gauge.cpp index 1772754fc..9c65a502f 100644 --- a/Gauge.cpp +++ b/Gauge.cpp @@ -50,7 +50,8 @@ void TGauge::Init(TSubModel *NewSubModel, TGaugeType eNewType, double fNewScale, double fNewFriction, double fNewValue) { // ustawienie parametrów animacji submodelu if (NewSubModel) - { // warunek na wszelki wypadek, gdyby się submodel nie podłączył + { // warunek na wszelki wypadek, gdyby się submodel nie + // podłączył fFriction = fNewFriction; fValue = fNewValue; fOffset = fNewOffset; @@ -61,11 +62,12 @@ void TGauge::Init(TSubModel *NewSubModel, TGaugeType eNewType, double fNewScale, { TSubModel *sm = SubModel->ChildGet(); do - { // pętla po submodelach potomnych i obracanie ich o kąt zależy od cyfry w (fValue) + { // pętla po submodelach potomnych i obracanie ich o kąt zależy od + // cyfry w (fValue) if (sm->pName) { // musi mieć niepustą nazwę - if ((*sm->pName) >= '0') - if ((*sm->pName) <= '9') + if (sm->pName[0] >= '0') + if (sm->pName[0] <= '9') sm->WillBeAnimated(); // wyłączenie optymalizacji } sm = sm->NextGet(); @@ -137,14 +139,16 @@ void TGauge::PutValue(double fNewDesired) void TGauge::Update() { float dt = Timer::GetDeltaTime(); - if ((fFriction > 0) && - (dt < - 0.5 * fFriction)) // McZapkie-281102: zabezpieczenie przed oscylacjami dla dlugich czasow + if ((fFriction > 0) && (dt < 0.5 * fFriction)) // McZapkie-281102: + // zabezpieczenie przed + // oscylacjami dla dlugich + // czasow fValue += dt * (fDesiredValue - fValue) / fFriction; else fValue = fDesiredValue; if (SubModel) - { // warunek na wszelki wypadek, gdyby się submodel nie podłączył + { // warunek na wszelki wypadek, gdyby się submodel nie + // podłączył TSubModel *sm; switch (eType) { @@ -167,16 +171,17 @@ void TGauge::Update() break; case gt_Digital: // Ra 2014-07: licznik cyfrowy sm = SubModel->ChildGet(); - AnsiString n = FormatFloat("0000000000", floor(fValue)); // na razie tak trochę bez - // sensu + AnsiString n = + FormatFloat("0000000000", floor(fValue)); // na razie tak trochę bez sensu do - { // pętla po submodelach potomnych i obracanie ich o kąt zależy od cyfry w (fValue) + { // pętla po submodelach potomnych i obracanie ich o kąt zależy od + // cyfry w (fValue) if (sm->pName) { // musi mieć niepustą nazwę - if ((*sm->pName) >= '0') - if ((*sm->pName) <= '9') + if (sm->pName[0] >= '0') + if (sm->pName[0] <= '9') sm->SetRotate(float3(0, 1, 0), - -36.0 * (n['0' + 10 - (*sm->pName)] - '0')); + -36.0 * (n['0' + 10 - sm->pName[0]] - '0')); } sm = sm->NextGet(); } while (sm); diff --git a/Geom.cpp b/Geom.cpp index 6d42ab006..9b2d7b029 100644 --- a/Geom.cpp +++ b/Geom.cpp @@ -19,11 +19,11 @@ obtain one at #include "Globals.h" #include "Geom.h" -__fastcall TGeometry::TGeometry() + TGeometry::TGeometry() { } -__fastcall TGeometry::~TGeometry() + TGeometry::~TGeometry() { } diff --git a/Globals.cpp b/Globals.cpp index bce123ba6..65aedecd2 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -49,9 +49,9 @@ AnsiString Global::asSky = "1"; int Global::iReCompile = 0; // zwiększany, gdy trzeba odświeżyć siatki HWND Global::hWnd = NULL; // uchwyt okna int Global::iCameraLast = -1; -AnsiString Global::asRelease = "15.3.1167.470"; +AnsiString Global::asRelease = "16.0.1172.475"; AnsiString Global::asVersion = - "Compilation 2015-04-14, release " + Global::asRelease + "."; // tutaj, bo wysyłany + "Compilation 2016-05-25, release " + Global::asRelease + "."; // tutaj, bo wysyłany int Global::iViewMode = 0; // co aktualnie widać: 0-kabina, 1-latanie, 2-sprzęgi, 3-dokumenty int Global::iTextMode = 0; // tryb pracy wyświetlacza tekstowego int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0, @@ -85,6 +85,7 @@ vector3 Global::pFreeCameraInit[10]; vector3 Global::pFreeCameraInitAngle[10]; double Global::fFogStart = 1700; double Global::fFogEnd = 2000; +float Global::Background[3] = { 0.2, 0.4, 0.33 }; GLfloat Global::AtmoColor[] = {0.423f, 0.702f, 1.0f}; GLfloat Global::FogColor[] = {0.6f, 0.7f, 0.8f}; GLfloat Global::ambientDayLight[] = {0.40f, 0.40f, 0.45f, 1.0f}; // robocze @@ -99,7 +100,7 @@ GLfloat Global::noLight[] = {0.00f, 0.00f, 0.00f, 1.0f}; GLfloat Global::lightPos[4]; bool Global::bRollFix = true; // czy wykonać przeliczanie przechyłki bool Global::bJoinEvents = false; // czy grupować eventy o tych samych nazwach -int Global::iHiddenEvents = 0; // czy łączyć eventy z torami poprzez nazwę toru +int Global::iHiddenEvents = 1; // czy łączyć eventy z torami poprzez nazwę toru // parametry użytkowe (jak komu pasuje) int Global::Keys[MaxKeys]; @@ -160,16 +161,21 @@ bool Global::bDecompressDDS = false; // czy programowa dekompresja DDS // parametry do kalibracji // kolejno współczynniki dla potęg 0, 1, 2, 3 wartości odczytanej z urządzenia -double Global::fCalibrateIn[6][4] = { - {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}}; -double Global::fCalibrateOut[7][4] = {{0, 1, 0, 0}, - {0, 1, 0, 0}, - {0, 1, 0, 0}, - {0, 1, 0, 0}, - {0, 1, 0, 0}, - {0, 1, 0, 0}, - {0, 1, 0, 0}}; - +double Global::fCalibrateIn[6][6] = {{0, 1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}}; +double Global::fCalibrateOut[7][6] = {{0, 1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}}; +double Global::fCalibrateOutMax[7] = {0, 0, 0, 0, 0, 0, 0}; +int Global::iCalibrateOutDebugInfo = -1; // parametry przejściowe (do usunięcia) // bool Global::bTimeChange=false; //Ra: ZiomalCl wyłączył starą wersję nocy // bool Global::bRenderAlpha=true; //Ra: wywaliłam tę flagę @@ -441,7 +447,21 @@ void Global::ConfigParse(TQueryParserComp *qp, cParser *cp) fCalibrateIn[i][1] = GetNextSymbol().ToDouble(); // mnożnik fCalibrateIn[i][2] = GetNextSymbol().ToDouble(); // mnożnik dla kwadratu fCalibrateIn[i][3] = GetNextSymbol().ToDouble(); // mnożnik dla sześcianu - } + fCalibrateIn[i][4] = 0.0; // mnożnik 4 potęgi + fCalibrateIn[i][5] = 0.0; // mnożnik 5 potęgi + } + else if (str == AnsiString("calibrate5din")) // parametry kalibracji wejść + { // + i = GetNextSymbol().ToIntDef(-1); // numer wejścia + if ((i < 0) || (i > 5)) + i = 5; // na ostatni, bo i tak trzeba pominąć wartości + fCalibrateIn[i][0] = GetNextSymbol().ToDouble(); // wyraz wolny + fCalibrateIn[i][1] = GetNextSymbol().ToDouble(); // mnożnik + fCalibrateIn[i][2] = GetNextSymbol().ToDouble(); // mnożnik dla kwadratu + fCalibrateIn[i][3] = GetNextSymbol().ToDouble(); // mnożnik dla sześcianu + fCalibrateIn[i][4] = GetNextSymbol().ToDouble(); // mnożnik 4 potęgi + fCalibrateIn[i][5] = GetNextSymbol().ToDouble(); // mnożnik 5 potęgi + } else if (str == AnsiString("calibrateout")) // parametry kalibracji wyjść { // i = GetNextSymbol().ToIntDef(-1); // numer wejścia @@ -451,7 +471,33 @@ void Global::ConfigParse(TQueryParserComp *qp, cParser *cp) fCalibrateOut[i][1] = GetNextSymbol().ToDouble(); // mnożnik liniowy fCalibrateOut[i][2] = GetNextSymbol().ToDouble(); // mnożnik dla kwadratu fCalibrateOut[i][3] = GetNextSymbol().ToDouble(); // mnożnik dla sześcianu + fCalibrateOut[i][4] = 0.0; // mnożnik dla 4 potęgi + fCalibrateOut[i][5] = 0.0; // mnożnik dla 5 potęgi } + else if (str == AnsiString("calibrate5dout")) // parametry kalibracji wyjść + { // + i = GetNextSymbol().ToIntDef(-1); // numer wejścia + if ((i < 0) || (i > 6)) + i = 6; // na ostatni, bo i tak trzeba pominąć wartości + fCalibrateOut[i][0] = GetNextSymbol().ToDouble(); // wyraz wolny + fCalibrateOut[i][1] = GetNextSymbol().ToDouble(); // mnożnik liniowy + fCalibrateOut[i][2] = GetNextSymbol().ToDouble(); // mnożnik dla kwadratu + fCalibrateOut[i][3] = GetNextSymbol().ToDouble(); // mnożnik dla sześcianu + fCalibrateOut[i][4] = GetNextSymbol().ToDouble(); // mnożnik dla 4 potęgi + fCalibrateOut[i][5] = GetNextSymbol().ToDouble(); // mnożnik dla 5 potęgi + } + else if (str == AnsiString("calibrateoutmaxvalues")) + { // maksymalne wartości jakie można wyświetlić na mierniku + fCalibrateOutMax[0] = GetNextSymbol().ToDouble(); + fCalibrateOutMax[1] = GetNextSymbol().ToDouble(); + fCalibrateOutMax[2] = GetNextSymbol().ToDouble(); + fCalibrateOutMax[3] = GetNextSymbol().ToDouble(); + fCalibrateOutMax[4] = GetNextSymbol().ToDouble(); + fCalibrateOutMax[5] = GetNextSymbol().ToDouble(); + fCalibrateOutMax[6] = GetNextSymbol().ToDouble(); + } + else if (str == AnsiString("calibrateoutdebuginfo")) // wyjście z info o przebiegu kalibracji + iCalibrateOutDebugInfo = GetNextSymbol().ToInt(); else if (str == AnsiString("brakestep")) // krok zmiany hamulca dla klawiszy [Num3] i [Num9] fBrakeStep = GetNextSymbol().ToDouble(); else if (str == @@ -465,7 +511,17 @@ void Global::ConfigParse(TQueryParserComp *qp, cParser *cp) asLang = GetNextSymbol(); // domyślny język - http://tools.ietf.org/html/bcp47 else if (str == AnsiString("opengl")) // deklarowana wersja OpenGL, żeby powstrzymać błędy fOpenGL = GetNextSymbol().ToDouble(); // wymuszenie wersji OpenGL - } while (str != "endconfig"); //(!Parser->EndOfFile) + else if (str == AnsiString("pyscreenrendererpriority")) // priority of python screen + // renderer + TPythonInterpreter::getInstance()->setScreenRendererPriority( + GetNextSymbol().LowerCase().c_str()); + else if (str == AnsiString("background")) + { + Background[0] = GetNextSymbol().ToDouble(); // r + Background[1] = GetNextSymbol().ToDouble(); // g + Background[2] = GetNextSymbol().ToDouble(); // b + } + } while (str != "endconfig"); //(!Parser->EndOfFile) // na koniec trochę zależności if (!bLoadTraction) // wczytywanie drutów i słupów { // tutaj wyłączenie, bo mogą nie być zdefiniowane w INI @@ -669,12 +725,12 @@ void Global::TrainDelete(TDynamicObject *d) pWorld->TrainDelete(d); }; -TDynamicObject *__fastcall Global::DynamicNearest() +TDynamicObject * Global::DynamicNearest() { // ustalenie pojazdu najbliższego kamerze return pGround->DynamicNearest(pCamera->Pos); }; -TDynamicObject *__fastcall Global::CouplerNearest() +TDynamicObject * Global::CouplerNearest() { // ustalenie pojazdu najbliższego kamerze return pGround->CouplerNearest(pCamera->Pos); }; @@ -837,6 +893,23 @@ AnsiString Global::Bezogonkow(AnsiString str, bool _) if (str[i] == '_') // nazwy stacji nie mogą zawierać spacji str[i] = ' '; // więc trzeba wyświetlać inaczej return str; -} +}; + +double Global::Min0RSpeed(double vel1, double vel2) +{ // rozszerzenie funkcji Min0R o wartości -1.0 + if (vel1 == -1.0) + vel1 = std::numeric_limits::max(); + if (vel2 == -1.0) + vel2 = std::numeric_limits::max(); + return Min0R(vel1, vel2); +}; + +double Global::CutValueToRange(double min, double value, double max) +{ // przycinanie wartosci do podanych granic + value = Max0R(value, min); + value = Min0R(value, max); + return value; +}; + #pragma package(smart_init) diff --git a/Globals.h b/Globals.h index 327a1186b..522475a1c 100644 --- a/Globals.h +++ b/Globals.h @@ -14,6 +14,7 @@ obtain one at #include "system.hpp" #include "opengl/glew.h" #include "dumb3d.h" +#include "PyInt.h" //#include "Classes.h" using namespace Math3D; @@ -214,7 +215,8 @@ class Global static void SetCameraRotation(double Yaw); static int iWriteLogEnabled; // maska bitowa: 1-zapis do pliku, 2-okienko // McZapkie-221002: definicja swiatla dziennego - static GLfloat AtmoColor[]; + static float Background[3]; + static GLfloat AtmoColor[]; static GLfloat FogColor[]; // static bool bTimeChange; static GLfloat ambientDayLight[]; @@ -294,8 +296,11 @@ class Global static double fRadiusFactor; // współczynnik zmiany promienia static TCamera *pCamera; // parametry kamery static TDynamicObject *pUserDynamic; // pojazd użytkownika, renderowany bez trzęsienia - static double fCalibrateIn[6][4]; // parametry kalibracyjne wejść z pulpitu - static double fCalibrateOut[7][4]; // parametry kalibracyjne wyjść dla pulpitu + static double fCalibrateIn[6][6]; // parametry kalibracyjne wejść z pulpitu + static double fCalibrateOut[7][6]; // parametry kalibracyjne wyjść dla pulpitu + static double fCalibrateOutMax[7]; // wartości maksymalne wyjść dla pulpitu + static int iCalibrateOutDebugInfo; // numer wyjścia kalibrowanego dla którego wyświetlać + // informacje podczas kalibracji static double fBrakeStep; // krok zmiany hamulca dla klawiszy [Num3] i [Num9] static bool bJoinEvents; // czy grupować eventy o tych samych nazwach static bool bSmudge; // czy wyświetlać smugę, a pojazd użytkownika na końcu @@ -308,11 +313,13 @@ class Global static void TrainDelete(TDynamicObject *d); static void ConfigParse(Queryparsercomp::TQueryParserComp *qp, cParser *cp = NULL); static AnsiString GetNextSymbol(); - static TDynamicObject *__fastcall DynamicNearest(); - static TDynamicObject *__fastcall CouplerNearest(); + static TDynamicObject * DynamicNearest(); + static TDynamicObject * CouplerNearest(); static bool AddToQuery(TEvent *event, TDynamicObject *who); static bool DoEvents(); static AnsiString Bezogonkow(AnsiString str, bool _ = false); + static double Min0RSpeed(double vel1, double vel2); + static double CutValueToRange(double min, double value, double max); }; //--------------------------------------------------------------------------- diff --git a/Ground.cpp b/Ground.cpp index 88a6a0b40..a99a79fc6 100644 --- a/Ground.cpp +++ b/Ground.cpp @@ -975,7 +975,7 @@ void TSubRect::Sort() }; } -TTrack *__fastcall TSubRect::FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude) +TTrack * TSubRect::FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude) { // szukanie toru, którego koniec jest najbliższy (*Point) TTrack *Track; for (int i = 0; i < iTracks; ++i) @@ -1022,7 +1022,7 @@ void TSubRect::RaAnimate() tTrackAnim = tTrackAnim->RaAnimate(); // przeliczenie animacji kolejnego }; -TTraction *__fastcall TSubRect::FindTraction(vector3 *Point, int &iConnection, TTraction *Exclude) +TTraction * TSubRect::FindTraction(vector3 *Point, int &iConnection, TTraction *Exclude) { // szukanie przęsła w sektorze, którego koniec jest najbliższy (*Point) TGroundNode *Current; for (Current = nRenderWires; Current; Current = Current->nNext3) @@ -1360,7 +1360,7 @@ void TGround::Free() delete sTracks; } -TGroundNode *__fastcall TGround::DynamicFindAny(AnsiString asNameToFind) +TGroundNode * TGround::DynamicFindAny(AnsiString asNameToFind) { // wyszukanie pojazdu o podanej nazwie, szukanie po wszystkich (użyć drzewa!) for (TGroundNode *Current = nRootDynamic; Current; Current = Current->nNext) if ((Current->asName == asNameToFind)) @@ -1368,7 +1368,7 @@ TGroundNode *__fastcall TGround::DynamicFindAny(AnsiString asNameToFind) return NULL; }; -TGroundNode *__fastcall TGround::DynamicFind(AnsiString asNameToFind) +TGroundNode * TGround::DynamicFind(AnsiString asNameToFind) { // wyszukanie pojazdu z obsadą o podanej nazwie (użyć drzewa!) for (TGroundNode *Current = nRootDynamic; Current; Current = Current->nNext) if (Current->DynamicObject->Mechanik) @@ -1386,7 +1386,7 @@ void TGround::DynamicList(bool all) WyslijString("none", 6); // informacja o końcu listy }; -TGroundNode *__fastcall TGround::FindGroundNode(AnsiString asNameToFind, TGroundNodeType iNodeType) +TGroundNode * TGround::FindGroundNode(AnsiString asNameToFind, TGroundNodeType iNodeType) { // wyszukiwanie obiektu o podanej nazwie i konkretnym typie if ((iNodeType == TP_TRACK) || (iNodeType == TP_MEMCELL) || (iNodeType == TP_MODEL)) { // wyszukiwanie w drzewie binarnym @@ -1540,7 +1540,7 @@ void TGround::RaTriangleDivider(TGroundNode *node) RaTriangleDivider(ntri); }; -TGroundNode *__fastcall TGround::AddGroundNode(cParser *parser) +TGroundNode * TGround::AddGroundNode(cParser *parser) { // wczytanie wpisu typu "node" // parser->LoadTraction=Global::bLoadTraction; //Ra: tu nie potrzeba powtarzać AnsiString str, str1, str2, str3, str4, Skin, DriverType, asNodeName; @@ -1704,9 +1704,7 @@ TGroundNode *__fastcall TGround::AddGroundNode(cParser *parser) parser->getTokens(3); *parser >> tmp->pCenter.x >> tmp->pCenter.y >> tmp->pCenter.z; tmp->pCenter += pOrigin; - tmp->psTractionPowerSource = new TTractionPowerSource(); - tmp->psTractionPowerSource->gMyNode = - tmp; // Ra 2015-03: znowu prowizorka, aby mieć nazwę do logowania + tmp->psTractionPowerSource = new TTractionPowerSource(tmp); tmp->psTractionPowerSource->Load(parser); break; case TP_MEMCELL: @@ -2201,7 +2199,7 @@ TGroundNode *__fastcall TGround::AddGroundNode(cParser *parser) return tmp; } -TSubRect *__fastcall TGround::FastGetSubRect(int iCol, int iRow) +TSubRect * TGround::FastGetSubRect(int iCol, int iRow) { int br, bc, sr, sc; br = iRow / iNumSubRects; @@ -2213,7 +2211,7 @@ TSubRect *__fastcall TGround::FastGetSubRect(int iCol, int iRow) return (Rects[br][bc].FastGetRect(sc, sr)); } -TSubRect *__fastcall TGround::GetSubRect(int iCol, int iRow) +TSubRect * TGround::GetSubRect(int iCol, int iRow) { // znalezienie małego kwadratu mapy int br, bc, sr, sc; br = iRow / iNumSubRects; // współrzędne kwadratu kilometrowego @@ -2225,7 +2223,7 @@ TSubRect *__fastcall TGround::GetSubRect(int iCol, int iRow) return (Rects[br][bc].SafeGetRect(sc, sr)); // pobranie małego kwadratu } -TEvent *__fastcall TGround::FindEvent(const AnsiString &asEventName) +TEvent * TGround::FindEvent(const AnsiString &asEventName) { return (TEvent *)sTracks->Find(0, asEventName.c_str()); // wyszukiwanie w drzewie /* //powolna wyszukiwarka @@ -2238,7 +2236,7 @@ TEvent *__fastcall TGround::FindEvent(const AnsiString &asEventName) */ } -TEvent *__fastcall TGround::FindEventScan(const AnsiString &asEventName) +TEvent * TGround::FindEventScan(const AnsiString &asEventName) { // wyszukanie eventu z opcją utworzenia niejawnego dla komórek skanowanych TEvent *e = (TEvent *)sTracks->Find(0, asEventName.c_str()); // wyszukiwanie w drzewie eventów if (e) @@ -3374,7 +3372,7 @@ void TGround::InitTraction() nTemp = new TGroundNode(); nTemp->iType = TP_TRACTIONPOWERSOURCE; nTemp->asName = Traction->asPowerSupplyName; - nTemp->psTractionPowerSource = new TTractionPowerSource(); + nTemp->psTractionPowerSource = new TTractionPowerSource(nTemp); nTemp->psTractionPowerSource->Init(Traction->NominalVoltage, Traction->MaxCurrent); nTemp->nNext = nRootOfType[nTemp->iType]; // ostatni dodany dołączamy na końcu // nowego @@ -3621,7 +3619,7 @@ bool TGround::InitLaunchers() return true; } -TTrack *__fastcall TGround::FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude) +TTrack * TGround::FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude) { // wyszukiwanie innego toru kończącego się w (Point) TTrack *Track; TGroundNode *Current; @@ -3669,7 +3667,7 @@ TTrack *__fastcall TGround::FindTrack(vector3 Point, int &iConnection, TGroundNo return NULL; } -TTraction *__fastcall TGround::FindTraction(vector3 *Point, int &iConnection, TGroundNode *Exclude) +TTraction * TGround::FindTraction(vector3 *Point, int &iConnection, TGroundNode *Exclude) { // wyszukiwanie innego przęsła kończącego się w (Point) TTraction *Traction; TGroundNode *Current; @@ -3707,7 +3705,7 @@ TTraction *__fastcall TGround::FindTraction(vector3 *Point, int &iConnection, TG return NULL; }; -TTraction *__fastcall TGround::TractionNearestFind(vector3 &p, int dir, TGroundNode *n) +TTraction * TGround::TractionNearestFind(vector3 &p, int dir, TGroundNode *n) { // wyszukanie najbliższego do (p) przęsła o tej samej nazwie sekcji (ale innego niż podłączone) // oraz zasilanego z kierunku (dir) TGroundNode *nCurrent, *nBest = NULL; @@ -4774,6 +4772,24 @@ void TGround::WyslijEvent(const AnsiString &e, const AnsiString &d) cData.cbData = 12 + i + j; // 8+dwa liczniki i dwa zera kończące cData.lpData = &r; Navigate("TEU07SRK", WM_COPYDATA, (WPARAM)Global::hWnd, (LPARAM)&cData); + CommLog(AnsiString(Now()) + " " + IntToStr(r.iComm) + " " + e + " sent"); +}; +//--------------------------------------------------------------------------- +void TGround::WyslijUszkodzenia(const AnsiString &t, char fl) +{ // wysłanie informacji w postaci pojedynczego tekstu + DaneRozkaz r; + r.iSygn = 'EU07'; + r.iComm = 13; // numer komunikatu + int i = t.Length(); + r.cString[0] = char(fl); + r.cString[1] = char(i); + strcpy(r.cString + 2, t.c_str()); // z zerem kończącym + COPYDATASTRUCT cData; + cData.dwData = 'EU07'; // sygnatura + cData.cbData = 11 + i; // 8+licznik i zero kończące + cData.lpData = &r; + Navigate("TEU07SRK", WM_COPYDATA, (WPARAM)Global::hWnd, (LPARAM)&cData); + CommLog(AnsiString(Now()) + " " + IntToStr(r.iComm) + " " + t + " sent"); }; //--------------------------------------------------------------------------- void TGround::WyslijString(const AnsiString &t, int n) @@ -4789,6 +4805,7 @@ void TGround::WyslijString(const AnsiString &t, int n) cData.cbData = 10 + i; // 8+licznik i zero kończące cData.lpData = &r; Navigate("TEU07SRK", WM_COPYDATA, (WPARAM)Global::hWnd, (LPARAM)&cData); + CommLog(AnsiString(Now()) + " " + IntToStr(r.iComm) + " " + t + " sent"); }; //--------------------------------------------------------------------------- void TGround::WyslijWolny(const AnsiString &t) @@ -4868,7 +4885,51 @@ void TGround::WyslijNamiary(TGroundNode *t) // WriteLog("Ramka gotowa"); Navigate("TEU07SRK", WM_COPYDATA, (WPARAM)Global::hWnd, (LPARAM)&cData); // WriteLog("Ramka poszla!"); + CommLog(AnsiString(Now()) + " " + IntToStr(r.iComm) + " " + t->asName + " sent"); }; +// +void TGround::WyslijObsadzone() +{ // wysłanie informacji o pojeździe + DaneRozkaz2 r; + r.iSygn = 'EU07'; + r.iComm = 12; // kod 12 + for (int i; i<1984; i++) r.cString[i] = 0; + + int i = 0; + for (TGroundNode *Current = nRootDynamic; Current; Current = Current->nNext) + if (Current->DynamicObject->Mechanik) + { + strcpy(r.cString + 64 * i, Current->DynamicObject->asName.c_str()); + r.fPar[16 * i + 4] = Current->DynamicObject->GetPosition().x; + r.fPar[16 * i + 5] = Current->DynamicObject->GetPosition().y; + r.fPar[16 * i + 6] = Current->DynamicObject->GetPosition().z; + r.iPar[16 * i + 7] = Current->DynamicObject->Mechanik->GetAction(); + strcpy(r.cString + 64 * i + 32, Current->DynamicObject->GetTrack()->IsolatedName().c_str()); + strcpy(r.cString + 64 * i + 48, Current->DynamicObject->Mechanik->Timetable()->TrainName.c_str()); + i++; + if (i>30) break; + } + while (i <= 30) + { + strcpy(r.cString + 64 * i, AnsiString("none").c_str()); + r.fPar[16 * i + 4] = 1; + r.fPar[16 * i + 5] = 2; + r.fPar[16 * i + 6] = 3; + r.iPar[16 * i + 7] = 0; + strcpy(r.cString + 64 * i + 32, AnsiString("none").c_str()); + strcpy(r.cString + 64 * i + 48, AnsiString("none").c_str()); + i++; + } + + COPYDATASTRUCT cData; + cData.dwData = 'EU07'; // sygnatura + cData.cbData = 8 + 1984; // 8+licznik i zero kończące + cData.lpData = &r; + // WriteLog("Ramka gotowa"); + Navigate("TEU07SRK", WM_COPYDATA, (WPARAM)Global::hWnd, (LPARAM)&cData); + CommLog(AnsiString(Now()) + " " + IntToStr(r.iComm) + " obsadzone" + " sent"); +} + //-------------------------------- void TGround::WyslijParam(int nr, int fl) { // wysłanie parametrów symulacji w ramce (nr) z flagami (fl) @@ -4910,7 +4971,7 @@ void TGround::RadioStop(vector3 pPosition) node->pTrack->RadioStop(); // przekazanie do każdego toru w każdym segmencie }; -TDynamicObject *__fastcall TGround::DynamicNearest(vector3 pPosition, double distance, bool mech) +TDynamicObject * TGround::DynamicNearest(vector3 pPosition, double distance, bool mech) { // wyszukanie pojazdu najbliższego względem (pPosition) TGroundNode *node; TSubRect *tmp; @@ -4936,7 +4997,7 @@ TDynamicObject *__fastcall TGround::DynamicNearest(vector3 pPosition, double dis } return dyn; }; -TDynamicObject *__fastcall TGround::CouplerNearest(vector3 pPosition, double distance, bool mech) +TDynamicObject * TGround::CouplerNearest(vector3 pPosition, double distance, bool mech) { // wyszukanie pojazdu, którego sprzęg jest najbliżej względem (pPosition) TGroundNode *node; TSubRect *tmp; diff --git a/Ground.h b/Ground.h index dc97bce2b..0502cc4ae 100644 --- a/Ground.h +++ b/Ground.h @@ -46,6 +46,18 @@ struct DaneRozkaz }; }; +struct DaneRozkaz2 +{ // struktura komunikacji z EU07.EXE + int iSygn; // sygnatura 'EU07' + int iComm; // rozkaz/status (kod ramki) + union + { + float fPar[496]; + int iPar[496]; + char cString[1984]; // upakowane stringi + }; +}; + typedef int TGroundNodeType; struct TGroundVertex @@ -144,7 +156,7 @@ class TGroundNode : public Resource void MoveMe(vector3 pPosition); // przesuwanie (nie działa) // bool Disable(); - inline TGroundNode *__fastcall Find(const AnsiString &asNameToFind, TGroundNodeType iNodeType) + inline TGroundNode * Find(const AnsiString &asNameToFind, TGroundNodeType iNodeType) { // wyszukiwanie czołgowe z typem if ((iNodeType == iType) && (asNameToFind == asName)) return this; @@ -196,8 +208,8 @@ class TSubRect : public Resource, public CMesh void NodeAdd(TGroundNode *Node); // dodanie obiektu do sektora na etapie rozdzielania na sektory void RaNodeAdd(TGroundNode *Node); // dodanie obiektu do listy renderowania void Sort(); // optymalizacja obiektów w sektorze (sortowanie wg tekstur) - TTrack *__fastcall FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude); - TTraction *__fastcall FindTraction(vector3 *Point, int &iConnection, TTraction *Exclude); + TTrack * FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude); + TTraction * FindTraction(vector3 *Point, int &iConnection, TTraction *Exclude); bool StartVBO(); // ustwienie VBO sektora dla (nRenderRect), (nRenderRectAlpha) i // (nRenderWires) bool RaTrackAnimAdd(TTrack *t); // zgłoszenie toru do animacji @@ -237,13 +249,13 @@ class TGroundRect : public TSubRect TGroundRect(); virtual ~TGroundRect(); - TSubRect *__fastcall SafeGetRect(int iCol, int iRow) + TSubRect * SafeGetRect(int iCol, int iRow) { // pobranie wskaźnika do małego kwadratu, utworzenie jeśli trzeba if (!pSubRects) Init(); // utworzenie małych kwadratów return pSubRects + iRow * iNumSubRects + iCol; // zwrócenie właściwego }; - TSubRect *__fastcall FastGetRect(int iCol, int iRow) + TSubRect * FastGetRect(int iCol, int iRow) { // pobranie wskaźnika do małego kwadratu, bez tworzenia jeśli nie ma return (pSubRects ? pSubRects + iRow * iNumSubRects + iCol : NULL); }; @@ -296,11 +308,11 @@ class TGround void InitTraction(); bool InitEvents(); bool InitLaunchers(); - TTrack *__fastcall FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude); - TTraction *__fastcall FindTraction(vector3 *Point, int &iConnection, TGroundNode *Exclude); - TTraction *__fastcall TractionNearestFind(vector3 &p, int dir, TGroundNode *n); + TTrack * FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude); + TTraction * FindTraction(vector3 *Point, int &iConnection, TGroundNode *Exclude); + TTraction * TractionNearestFind(vector3 &p, int dir, TGroundNode *n); // TGroundNode* CreateGroundNode(); - TGroundNode *__fastcall AddGroundNode(cParser *parser); + TGroundNode * AddGroundNode(cParser *parser); bool AddGroundNode(double x, double z, TGroundNode *Node) { TSubRect *tmp = GetSubRect(x, z); @@ -314,7 +326,7 @@ class TGround }; // bool Include(TQueryParserComp *Parser); // TGroundNode* GetVisible(AnsiString asName); - TGroundNode *__fastcall GetNode(AnsiString asName); + TGroundNode * GetNode(AnsiString asName); bool AddDynamic(TGroundNode *Node); void MoveGroundNode(vector3 pPosition); void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem @@ -343,24 +355,24 @@ class TGround return NULL; } */ - TGroundNode *__fastcall DynamicFindAny(AnsiString asNameToFind); - TGroundNode *__fastcall DynamicFind(AnsiString asNameToFind); + TGroundNode * DynamicFindAny(AnsiString asNameToFind); + TGroundNode * DynamicFind(AnsiString asNameToFind); void DynamicList(bool all = false); - TGroundNode *__fastcall FindGroundNode(AnsiString asNameToFind, TGroundNodeType iNodeType); - TGroundRect *__fastcall GetRect(double x, double z) + TGroundNode * FindGroundNode(AnsiString asNameToFind, TGroundNodeType iNodeType); + TGroundRect * GetRect(double x, double z) { return &Rects[GetColFromX(x) / iNumSubRects][GetRowFromZ(z) / iNumSubRects]; }; - TSubRect *__fastcall GetSubRect(double x, double z) + TSubRect * GetSubRect(double x, double z) { return GetSubRect(GetColFromX(x), GetRowFromZ(z)); }; - TSubRect *__fastcall FastGetSubRect(double x, double z) + TSubRect * FastGetSubRect(double x, double z) { return FastGetSubRect(GetColFromX(x), GetRowFromZ(z)); }; - TSubRect *__fastcall GetSubRect(int iCol, int iRow); - TSubRect *__fastcall FastGetSubRect(int iCol, int iRow); + TSubRect * GetSubRect(int iCol, int iRow); + TSubRect * FastGetSubRect(int iCol, int iRow); int GetRowFromZ(double z) { return (z / fSubRectSize + fHalfTotalNumSubRects); @@ -369,8 +381,8 @@ class TGround { return (x / fSubRectSize + fHalfTotalNumSubRects); }; - TEvent *__fastcall FindEvent(const AnsiString &asEventName); - TEvent *__fastcall FindEventScan(const AnsiString &asEventName); + TEvent * FindEvent(const AnsiString &asEventName); + TEvent * FindEventScan(const AnsiString &asEventName); void TrackJoin(TGroundNode *Current); private: @@ -386,10 +398,13 @@ class TGround void WyslijWolny(const AnsiString &t); void WyslijNamiary(TGroundNode *t); void WyslijParam(int nr, int fl); - void RadioStop(vector3 pPosition); - TDynamicObject *__fastcall DynamicNearest(vector3 pPosition, double distance = 20.0, + void WyslijUszkodzenia(const AnsiString &t, char fl); + void WyslijPojazdy(int nr); // -> skladanie wielu pojazdow + void WyslijObsadzone(); // -> skladanie wielu pojazdow + void RadioStop(vector3 pPosition); + TDynamicObject * DynamicNearest(vector3 pPosition, double distance = 20.0, bool mech = false); - TDynamicObject *__fastcall CouplerNearest(vector3 pPosition, double distance = 20.0, + TDynamicObject * CouplerNearest(vector3 pPosition, double distance = 20.0, bool mech = false); void DynamicRemove(TDynamicObject *dyn); void TerrainRead(const AnsiString &f); diff --git a/Logs.cpp b/Logs.cpp index 50a8a3b94..a462a1103 100644 --- a/Logs.cpp +++ b/Logs.cpp @@ -20,6 +20,7 @@ obtain one at std::ofstream output; // standardowy "log.txt", można go wyłączyć std::ofstream errors; // lista błędów "errors.txt", zawsze działa +std::ofstream comms; // lista komunikatow "comms.txt", można go wyłączyć char endstring[10] = "\n"; @@ -33,14 +34,15 @@ void WriteConsoleOnly(const char *str, double value) // WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),endstring,strlen(endstring),&wr,NULL); } -void WriteConsoleOnly(const char *str) +void WriteConsoleOnly(const char *str, bool newline) { // printf("%n ffafaf /n",str); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_INTENSITY); DWORD wr = 0; WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), str, strlen(str), &wr, NULL); - WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), endstring, strlen(endstring), &wr, NULL); + if (newline) + WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), endstring, strlen(endstring), &wr, NULL); } void WriteLog(const char *str, double value) @@ -55,7 +57,7 @@ void WriteLog(const char *str, double value) } } }; -void WriteLog(const char *str) +void WriteLog(const char *str, bool newline) { if (str) { @@ -63,12 +65,14 @@ void WriteLog(const char *str) { if (!output.is_open()) output.open("log.txt", std::ios::trunc); - output << str << "\n"; + output << str; + if (newline) + output << "\n"; output.flush(); } // hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana if (Global::iWriteLogEnabled & 2) - WriteConsoleOnly(str); + WriteConsoleOnly(str, newline); } }; void ErrorLog(const char *str) @@ -96,10 +100,33 @@ void ErrorLog(const AnsiString &asMessage) WriteLog(asMessage.c_str()); // do "log.txt" ewentualnie też } -void WriteLog(const AnsiString &str) +void WriteLog(const AnsiString &str, bool newline) { // Ra: wersja z AnsiString jest zamienna z Error() - WriteLog(str.c_str()); + WriteLog(str.c_str(), newline); }; + +void CommLog(const char *str) +{ // Ra: warunkowa rejestracja komunikatów + WriteLog(str); + /* if (Global::iWriteLogEnabled & 4) + { + if (!comms.is_open()) + { + comms.open("comms.txt", std::ios::trunc); + comms << AnsiString("EU07.EXE " + Global::asRelease).c_str() << "\n"; + } + if (str) + comms << str; + comms << "\n"; + comms.flush(); + }*/ +}; + +void CommLog(const AnsiString &str) +{ // Ra: wersja z AnsiString jest zamienna z Error() + CommLog(str.c_str()); +}; + //--------------------------------------------------------------------------- #pragma package(smart_init) diff --git a/Logs.h b/Logs.h index 69c36c5f0..b9071e3aa 100644 --- a/Logs.h +++ b/Logs.h @@ -12,11 +12,13 @@ obtain one at #include void WriteConsoleOnly(const char *str, double value); -void WriteConsoleOnly(const char *str); +void WriteConsoleOnly(const char *str, bool newline = true); void WriteLog(const char *str, double value); -void WriteLog(const char *str); +void WriteLog(const char *str, bool newline = true); void Error(const AnsiString &asMessage, bool box = true); void ErrorLog(const AnsiString &asMessage); -void WriteLog(const AnsiString &str); +void WriteLog(const AnsiString &str, bool newline = true); +void CommLog(const char *str); +void CommLog(const AnsiString &str); //--------------------------------------------------------------------------- #endif diff --git a/Machajka.cpp b/Machajka.cpp index 3d75b5417..4aeefe267 100644 --- a/Machajka.cpp +++ b/Machajka.cpp @@ -15,12 +15,12 @@ obtain one at #include "Timer.h" #include "Globals.h" -__fastcall TMachajka::TMachajka() : TTrain() + TMachajka::TMachajka() : TTrain() { TTrain::TTrain(); } -__fastcall TMachajka::~TMachajka() + TMachajka::~TMachajka() { } diff --git a/McZapkie/Mover.hpp b/McZapkie/Mover.hpp index 009f5b8fd..98c609a6e 100644 --- a/McZapkie/Mover.hpp +++ b/McZapkie/Mover.hpp @@ -93,8 +93,9 @@ enum TBrakeValve { NoValve, W, W_Lu_VI, W_Lu_L, W_Lu_XR, K, Kg, Kp, Kss, Kkg, Kk #pragma option pop #pragma option push -b- -enum TBrakeHandle { NoHandle, West, FV4a, M394, M254, FVel1, FVel6, D2, Knorr, FD1, BS2, testH, St113 - }; +enum TBrakeHandle { + NoHandle, West, FV4a, M394, M254, FVel1, FVel6, D2, Knorr, FD1, BS2, testH, St113, + MHZ_P, MHZ_T, MHZ_EN57 }; #pragma option pop #pragma option push -b- @@ -153,6 +154,7 @@ struct TCurrentCollector double CSW; double MinV; double MaxV; + double OVP; double InsetV; double MinPress; double MaxPress; @@ -425,8 +427,13 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject Byte BrakeCtrlPosNo; Byte MainCtrlPosNo; Byte ScndCtrlPosNo; + Byte LightsPosNo; + Byte LightsDefPos; + bool LightsWrap; + Byte Lights[2][16]; bool ScndInMain; bool MBrake; + double StopBrakeDecc; TSecuritySystem SecuritySystem; TScheme RList[65]; int RlistSize; @@ -454,6 +461,7 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject double RVentCutOff; int CompressorPower; int SmallCompressorPower; + bool Trafo; double dizel_Mmax; double dizel_nMmax; double dizel_Mnmax; @@ -481,7 +489,7 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject TShuntScheme SST[33]; double PowerCorRatio; double Ftmax; - double eimc[21]; + double eimc[26]; int MaxLoad; AnsiString LoadAccepted; AnsiString LoadQuantity; @@ -496,7 +504,11 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject double DoorCloseSpeed; double DoorMaxShiftL; double DoorMaxShiftR; + double DoorMaxPlugShift; Byte DoorOpenMethod; + double PlatformSpeed; + double PlatformMaxShift; + Byte PlatformOpenMethod; bool ScndS; TLocation Loc; TRotation Rot; @@ -555,10 +567,13 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject bool EmergencyBrakeFlag; Byte BrakeDelayFlag; Byte BrakeDelays; + Byte BrakeOpModeFlag; + Byte BrakeOpModes; bool DynamicBrakeFlag; double LimPipePress; double ActFlowSpeed; Byte DamageFlag; + Byte EngDmgFlag; Byte DerailReason; TCommand CommandIn; AnsiString CommandOut; @@ -571,6 +586,7 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject bool Mains; Byte MainCtrlPos; Byte ScndCtrlPos; + Byte LightsPos; int ActiveDir; int CabNo; int DirAbsolute; @@ -763,6 +779,7 @@ static const Shortint maxcc = 0x4; static const Shortint LocalBrakePosNo = 0xa; static const Shortint MainBrakeMaxPos = 0xa; static const Shortint ManualBrakePosNo = 0x14; +static const Shortint LightsSwitchPosNo = 0x10; static const Shortint dtrack_railwear = 0x2; static const Shortint dtrack_freerail = 0x4; static const Shortint dtrack_thinrail = 0x8; @@ -847,6 +864,8 @@ static const Shortint eimc_p_Ph = 0x11; static const Shortint eimc_p_Vh0 = 0x12; static const Shortint eimc_p_Vh1 = 0x13; static const Shortint eimc_p_Imax = 0x14; +static const Shortint eimc_p_abed = 0x15; +static const Shortint eimc_p_eped = 0x16; static const Shortint eimv_FMAXMAX = 0x0; static const Shortint eimv_Fmax = 0x1; static const Shortint eimv_ks = 0x2; @@ -867,6 +886,11 @@ static const Shortint eimv_Uzsmax = 0x10; static const Shortint eimv_Pmax = 0x11; static const Shortint eimv_Fzad = 0x12; static const Shortint eimv_Imax = 0x13; +static const Shortint eimv_Fful = 0x14; +static const Shortint bom_PS = 0x1; +static const Shortint bom_PN = 0x2; +static const Shortint bom_EP = 0x4; +static const Shortint bom_MED = 0x8; extern PACKAGE double __fastcall Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2); diff --git a/McZapkie/_Mover.hpp b/McZapkie/_Mover.hpp index 81065a919..09463a1e8 100644 --- a/McZapkie/_Mover.hpp +++ b/McZapkie/_Mover.hpp @@ -92,8 +92,8 @@ enum TBrakeValve { NoValve, W, W_Lu_VI, W_Lu_L, W_Lu_XR, K, Kg, Kp, Kss, Kkg, Kk #pragma option pop #pragma option push -b- -enum TBrakeHandle { NoHandle, West, FV4a, M394, M254, FVel1, FVel6, D2, Knorr, FD1, BS2, testH, St113 - }; +enum TBrakeHandle { NoHandle, West, FV4a, M394, M254, FVel1, FVel6, D2, Knorr, FD1, BS2, testH, St113, + MHZ_P, MHZ_T, MHZ_EN57 }; #pragma option pop #pragma option push -b- @@ -152,6 +152,7 @@ struct TCurrentCollector double CSW; double MinV; double MaxV; + double OVP; double InsetV; double MinPress; double MaxPress; @@ -404,8 +405,13 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject Byte BrakeCtrlPosNo; Byte MainCtrlPosNo; Byte ScndCtrlPosNo; + Byte LightsPosNo; + Byte LightsDefPos; + bool LightsWrap; + Byte Lights[2][16]; bool ScndInMain; bool MBrake; + double StopBrakeDecc; TSecuritySystem SecuritySystem; TScheme RList[65]; int RlistSize; @@ -433,6 +439,7 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject double RVentCutOff; int CompressorPower; int SmallCompressorPower; + bool Trafo; double dizel_Mmax; double dizel_nMmax; double dizel_Mnmax; @@ -460,7 +467,7 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject TShuntScheme SST[33]; double PowerCorRatio; double Ftmax; - double eimc[21]; + double eimc[26]; int MaxLoad; AnsiString LoadAccepted; AnsiString LoadQuantity; @@ -475,7 +482,11 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject double DoorCloseSpeed; double DoorMaxShiftL; double DoorMaxShiftR; + double DoorMaxPlugShift; Byte DoorOpenMethod; + double PlatformSpeed; + double PlatformMaxShift; + Byte PlatformOpenMethod; bool ScndS; TLocation Loc; TRotation Rot; @@ -534,10 +545,13 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject bool EmergencyBrakeFlag; Byte BrakeDelayFlag; Byte BrakeDelays; + Byte BrakeOpModeFlag; + Byte BrakeOpModes; bool DynamicBrakeFlag; double LimPipePress; double ActFlowSpeed; Byte DamageFlag; + Byte EngDmgFlag; Byte DerailReason; TCommand CommandIn; AnsiString CommandOut; @@ -550,6 +564,7 @@ class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject bool Mains; Byte MainCtrlPos; Byte ScndCtrlPos; + Byte LightsPos; int ActiveDir; int CabNo; int DirAbsolute; @@ -761,6 +776,7 @@ static const Shortint maxcc = 0x4; static const Shortint LocalBrakePosNo = 0xa; static const Shortint MainBrakeMaxPos = 0xa; static const Shortint ManualBrakePosNo = 0x14; +static const Shortint LightsSwitchPosNo = 0x10; static const Shortint dtrack_railwear = 0x2; static const Shortint dtrack_freerail = 0x4; static const Shortint dtrack_thinrail = 0x8; @@ -845,6 +861,8 @@ static const Shortint eimc_p_Ph = 0x11; static const Shortint eimc_p_Vh0 = 0x12; static const Shortint eimc_p_Vh1 = 0x13; static const Shortint eimc_p_Imax = 0x14; +static const Shortint eimc_p_abed = 0x15; +static const Shortint eimc_p_eped = 0x16; static const Shortint eimv_FMAXMAX = 0x0; static const Shortint eimv_Fmax = 0x1; static const Shortint eimv_ks = 0x2; @@ -865,6 +883,11 @@ static const Shortint eimv_Uzsmax = 0x10; static const Shortint eimv_Pmax = 0x11; static const Shortint eimv_Fzad = 0x12; static const Shortint eimv_Imax = 0x13; +static const Shortint eimv_Fful = 0x14; +static const Shortint bom_PS = 0x1; +static const Shortint bom_PN = 0x2; +static const Shortint bom_EP = 0x4; +static const Shortint bom_MED = 0x8; extern PACKAGE double __fastcall Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2); diff --git a/McZapkie/_mover.pas b/McZapkie/_mover.pas index c35523fe8..010206a9d 100644 --- a/McZapkie/_mover.pas +++ b/McZapkie/_mover.pas @@ -1,13 +1,5 @@ unit _mover; {fizyka ruchu dla symulatora lokomotywy} -(* -This Source Code Form is subject to the -terms of the Mozilla Public License, v. -2.0. If a copy of the MPL was not -distributed with this file, You can -obtain one at -http://mozilla.org/MPL/2.0/. -*) (* MaSzyna EU07 locomotive simulator Copyright (C) 2001-2004 Maciej Czapkiewicz and others @@ -85,6 +77,7 @@ interface uses mctools,sysutils,hamulce,Oerlikon_ESt; LocalBrakePosNo=10; {ilosc nastaw hamulca pomocniczego} MainBrakeMaxPos=10; {max. ilosc nastaw hamulca zasadniczego} ManualBrakePosNo=20; {ilosc nastaw hamulca recznego} + LightsSwitchPosNo=16; {uszkodzenia toru} dtrack_railwear=2; @@ -190,6 +183,8 @@ interface uses mctools,sysutils,hamulce,Oerlikon_ESt; eimc_p_Vh0=18; eimc_p_Vh1=19; eimc_p_Imax=20; + eimc_p_abed=21; + eimc_p_eped=22; //zmienne dla asynchronów eimv_FMAXMAX=0; @@ -212,7 +207,12 @@ interface uses mctools,sysutils,hamulce,Oerlikon_ESt; eimv_Pmax=17; eimv_Fzad=18; eimv_Imax=19; + eimv_Fful=20; + bom_PS = 1; + bom_PN = 2; + bom_EP = 4; + bom_MED = 8; TYPE {ogolne} @@ -255,7 +255,7 @@ TTractionParam= record {podtypy hamulcow zespolonych} TBrakeSubSystem = (ss_None, ss_W, ss_K, ss_KK, ss_Hik, ss_ESt, ss_KE, ss_LSt, ss_MT, ss_Dako); TBrakeValve = (NoValve, W, W_Lu_VI, W_Lu_L, W_Lu_XR, K, Kg, Kp, Kss, Kkg, Kkp, Kks, Hikg1, Hikss, Hikp1, KE, SW, EStED, NESt3, ESt3, LSt, ESt4, ESt3AL2, EP1, EP2, M483, CV1_L_TR, CV1, CV1_R, Other); - TBrakeHandle = (NoHandle, West, FV4a, M394, M254, FVel1, FVel6, D2, Knorr, FD1, BS2, testH, St113); + TBrakeHandle = (NoHandle, West, FV4a, M394, M254, FVel1, FVel6, D2, Knorr, FD1, BS2, testH, St113, MHZ_P, MHZ_T, MHZ_EN57); {typy hamulcow indywidualnych} TLocalBrake = (NoBrake, ManualBrake, PneumaticBrake, HydraulicBrake); @@ -298,6 +298,7 @@ TCurrentCollector = record MinH,MaxH: real; //zakres ruchu pantografu, nigdzie nie używany CSW: real; //szerokość części roboczej (styku) ślizgacza MinV,MaxV: real; //minimalne i maksymalne akceptowane napięcie + OVP: real; //czy jest przekaznik nadnapieciowy InsetV: real; //minimalne napięcie wymagane do załączenia MinPress: real; //minimalne ciśnienie do załączenia WS MaxPress: real; //maksymalne ciśnienie za reduktorem @@ -479,7 +480,7 @@ T_MoverParameters = class(TObject) //Ra: dodana kreska w celu zrobienia wrap {promien cylindra, skok cylindra, przekladnia hamulcowa} BrakeCylSpring: real; {suma nacisku sprezyn powrotnych, kN} BrakeSlckAdj: real; {opor nastawiacza skoku tloka, kN} - BrakeRigEff: real; {sprawnosc przekladni dzwigniowej} + BrakeRigEff: real; {sprawnosc przekladni dzwigniowej} RapidMult: real; {przelozenie rapidu} BrakeValveSize: integer; BrakeValveParams: string; @@ -491,8 +492,12 @@ T_MoverParameters = class(TObject) //Ra: dodana kreska w celu zrobienia wrap {nastawniki:} MainCtrlPosNo: byte; {ilosc pozycji nastawnika} ScndCtrlPosNo: byte; + LightsPosNo, LightsDefPos: byte; + LightsWrap: boolean; + Lights: array [0..1] of array [1..16] of byte; ScndInMain: boolean; {zaleznosc bocznika od nastawnika} MBrake: boolean; {Czy jest hamulec reczny} + StopBrakeDecc: real; SecuritySystem: TSecuritySystem; {-sekcja parametrow dla lokomotywy elektrycznej} @@ -527,6 +532,7 @@ T_MoverParameters = class(TObject) //Ra: dodana kreska w celu zrobienia wrap RVentCutOff: real; {rezystancja wylaczania wentylatorow dla RVentType=2} CompressorPower: integer; {0: bezp. z obwodow silnika, 1: z przetwornicy, reczne, 2: w przetwornicy, stale, 5: z silnikowego} SmallCompressorPower: integer; {Winger ZROBIC} + Trafo: boolean; {pojazd wyposażony w transformator} {-sekcja parametrow dla lokomotywy spalinowej z przekladnia mechaniczna} dizel_Mmax, dizel_nMmax, dizel_Mnmax, dizel_nmax, dizel_nominalfill: real; @@ -560,7 +566,7 @@ T_MoverParameters = class(TObject) //Ra: dodana kreska w celu zrobienia wrap Ftmax:real; {- dla lokomotyw z silnikami indukcyjnymi -} - eimc: array [0..20] of real; + eimc: array [0..25] of real; {-dla wagonow} MaxLoad: longint; {masa w T lub ilosc w sztukach - ladownosc} @@ -571,8 +577,11 @@ T_MoverParameters = class(TObject) //Ra: dodana kreska w celu zrobienia wrap DoorStayOpen: real; {jak dlugo otwarte w przypadku DoorCloseCtrl=2} DoorClosureWarning: boolean; {czy jest ostrzeganie przed zamknieciem} DoorOpenSpeed, DoorCloseSpeed: real; {predkosc otwierania i zamykania w j.u. } - DoorMaxShiftL,DoorMaxShiftR: real;{szerokosc otwarcia lub kat} + DoorMaxShiftL,DoorMaxShiftR,DoorMaxPlugShift: real;{szerokosc otwarcia lub kat} DoorOpenMethod: byte; {sposob otwarcia - 1: przesuwne, 2: obrotowe, 3: trójelementowe} + PlatformSpeed: real; {szybkosc stopnia} + PlatformMaxShift: real; {wysuniecie stopnia} + PlatformOpenMethod: byte; {sposob animacji stopnia} ScndS: boolean; {Czy jest bocznikowanie na szeregowej} {--sekcja zmiennych} @@ -629,6 +638,8 @@ T_MoverParameters = class(TObject) //Ra: dodana kreska w celu zrobienia wrap EmergencyBrakeFlag: boolean; {hamowanie nagle} BrakeDelayFlag: byte; {nastawa opoznienia ham. osob/towar/posp/exp 0/1/2/4} BrakeDelays: byte; {nastawy mozliwe do uzyskania} + BrakeOpModeFlag: byte; {nastawa trybu pracy PS/PN/EP/MED 1/2/4/8} + BrakeOpModes: byte; {nastawy mozliwe do uzyskania} DynamicBrakeFlag: boolean; {czy wlaczony hamulec elektrodymiczny} // NapUdWsp: integer; LimPipePress: real; {stabilizator cisnienia} @@ -636,6 +647,7 @@ T_MoverParameters = class(TObject) //Ra: dodana kreska w celu zrobienia wrap DamageFlag: byte; //kombinacja bitowa stalych dtrain_* } + EngDmgFlag: byte; //kombinacja bitowa stalych usterek} DerailReason: byte; //przyczyna wykolejenia //EndSignalsFlag: byte; {ABu 060205: zmiany - koncowki: 1/16 - swiatla prz/tyl, 2/31 - blachy prz/tyl} @@ -655,6 +667,7 @@ T_MoverParameters = class(TObject) //Ra: dodana kreska w celu zrobienia wrap Mains: boolean; {polozenie glownego wylacznika} MainCtrlPos: byte; {polozenie glownego nastawnika} ScndCtrlPos: byte; {polozenie dodatkowego nastawnika} + LightsPos: byte; ActiveDir: integer; //czy lok. jest wlaczona i w ktorym kierunku: //względem wybranej kabiny: -1 - do tylu, +1 - do przodu, 0 - wylaczona CabNo: integer; //numer kabiny, z której jest sterowanie: 1 lub -1; w przeciwnym razie brak sterowania - rozrzad @@ -1055,6 +1068,7 @@ function SPR(ph,pl:real): real; {---------rozwiniecie deklaracji metod obiektu T_MoverParameters--------} +(* function T_MoverParameters.GetTrainsetVoltage: real; //ABu: funkcja zwracajaca napiecie dla calego skladu, przydatna dla EZT var volt: real; @@ -1081,6 +1095,14 @@ function T_MoverParameters.GetTrainsetVoltage: real; end; GetTrainsetVoltage:=volt; end; +*) + +function T_MoverParameters.GetTrainsetVoltage: real; +//ABu: funkcja zwracajaca napiecie dla calego skladu, przydatna dla EZT +//var volt: real; +begin + GetTrainsetVoltage:=Max0R(HVCouplers[1][1],HVCouplers[0][1]); +end; @@ -1116,6 +1138,12 @@ function T_MoverParameters.BrakeRatio: real; function T_MoverParameters.LocalBrakeRatio: real; var LBR:real; begin + if BrakeHandle=MHZ_EN57 then + if (BrakeOpModeFlag>=bom_EP) then + LBR:=(Handle as TMHZ_EN57).GetEP(BrakeCtrlPosR) + else + LBR:=0 + else if LocalBrakePosNo>0 then LBR:=LocalBrakePos/LocalBrakePosNo else @@ -1561,6 +1589,12 @@ function T_MoverParameters.IncScndCtrl(CtrlSpeed:integer): boolean; if (LastRelayTime>CtrlDelay) then LastRelayTime:=0; + if (OK) and (EngineType=ElectricInductionMotor) then + if (Vmax<250) then + ScndCtrlActualPos:=Round(Vel+0.5) + else + ScndCtrlActualPos:=Round(Vel/2+0.5); + IncScndCtrl:=OK; end; @@ -1604,6 +1638,10 @@ function T_MoverParameters.DecScndCtrl(CtrlSpeed:integer): boolean; if OK then if (LastRelayTime>CtrlDownDelay) then LastRelayTime:=0; + + if (OK) and (EngineType=ElectricInductionMotor) then + ScndCtrlActualPos:=0; + DecScndCtrl:=OK; end; @@ -1638,7 +1676,7 @@ function T_MoverParameters.MainSwitch(State:boolean): boolean; MainSwitch:=false; //Ra: przeniesione z końca if ((Mains<>State) and (MainCtrlPosNo>0)) then begin - if (State=false) or ({(MainCtrlPos=0) and} (ScndCtrlPos=0) and (ConvOvldFlag=false) and (LastSwitchingTime>CtrlDelay) and not TestFlag(DamageFlag,dtrain_out)) then + if (State=false) or ({(MainCtrlPos=0) and} (ScndCtrlPos=0) and ((ConvOvldFlag=false)or(TrainType=dt_EZT)) and (LastSwitchingTime>CtrlDelay) and not TestFlag(DamageFlag,dtrain_out) and not TestFlag(EngDmgFlag,1)) then begin if Mains then //jeśli był załączony SendCtrlToNext('MainSwitch',ord(State),CabNo); //wysłanie wyłączenia do pozostałych? @@ -1651,6 +1689,8 @@ function T_MoverParameters.MainSwitch(State:boolean): boolean; begin dizel_enginestart:=State; end; + if ((TrainType=dt_EZT)and(not State)) then + ConvOvldFlag:=true; //if (State=false) then //jeśli wyłączony // begin //SetFlag(SoundFlag,sound_relay); //hunter-091012: przeniesione do Train.cpp, zeby sie nie zapetlal @@ -1946,6 +1986,8 @@ procedure T_MoverParameters.SecuritySystemCheck(dt:real); //poza tym jest zdefiniowany we wszystkich 3 członach EN57 with SecuritySystem do begin + if (not Radio) then + EmergencyBrakeSwitch(false); if (SystemType>0) and (Status>0) and (Battery) then //Ra: EZT ma teraz czuwak w rozrządczym begin //CA @@ -1995,6 +2037,7 @@ procedure T_MoverParameters.SecuritySystemCheck(dt:real); end else if not (Battery) then begin //wyłączenie baterii deaktywuje sprzęt + EmergencyBrakeSwitch(false); //SecuritySystem.Status:=0; //deaktywacja czuwaka end; end; @@ -2068,11 +2111,11 @@ function T_MoverParameters.DecBrakeLevelOld:boolean; begin dec(BrakeCtrlPos); // BrakeCtrlPosR:=BrakeCtrlPos; - if EmergencyBrakeFlag then - begin - EmergencyBrakeFlag:=false; {!!!} - SendCtrlToNext('Emergency_brake',0,CabNo); - end; +//// if EmergencyBrakeFlag then //yB: czy to jest potrzebne? +//// begin +//// EmergencyBrakeFlag:=false; {!!!} +//// SendCtrlToNext('Emergency_brake',0,CabNo); +//// end; //youBy: wywalilem to, jak jest EP, to sa przenoszone sygnaly nt. co ma robic, a nie poszczegolne pozycje; // wystarczy spojrzec na Knorra i Oerlikona EP w EN57; mogly ze soba wspolapracowac @@ -2252,7 +2295,17 @@ function T_MoverParameters.AntiSlippingButton: boolean; function T_MoverParameters.BrakeDelaySwitch(BDS:byte): boolean; begin // if BrakeCtrlPosNo>0 then - if Hamulec.SetBDF(BDS) then + if BrakeHandle=MHZ_EN57 then + begin + if (BDS<>BrakeOpModeFlag) and ((BDS and BrakeOpModes) > 0) then + begin + BrakeOpModeFlag:=BDS; + BrakeDelaySwitch:=true; + end + else + BrakeDelaySwitch:=false; + end + else if Hamulec.SetBDF(BDS) then begin BrakeDelayFlag:=BDS; BrakeDelaySwitch:=true; @@ -2425,17 +2478,25 @@ procedure T_MoverParameters.UpdatePipePressure(dt:real); dpMainValve:=0; -if (BrakeCtrlPosNo>1) and (ActiveCab<>0)then +if (BrakeCtrlPosNo>1) {and(ActiveCab<>0)}then with BrakePressureTable[BrakeCtrlPos] do begin - dpLocalValve:=LocHandle.GetPF(LocalBrakePos/LocalBrakePosNo, Hamulec.GetBCP, ScndPipePress, dt, 0); + if(EngineType<>ElectricInductionMotor)then + dpLocalValve:=LocHandle.GetPF(Max0R(LocalBrakePos/LocalBrakePosNo,LocalBrakePosA), Hamulec.GetBCP, ScndPipePress, dt, 0) + else + dpLocalValve:=LocHandle.GetPF(LocalBrakePosA, Hamulec.GetBCP, ScndPipePress, dt, 0); if(BrakeHandle=FV4a)and((PipePress<2.75)and((Hamulec.GetStatus and b_rls)=0))and(BrakeSubsystem=ss_LSt)and(TrainType<>dt_EZT)then temp:=PipePress+0.00001 else temp:=ScndPipePress; Handle.SetReductor(BrakeCtrlPos2); - dpMainValve:=Handle.GetPF(BrakeCtrlPosR, PipePress, temp, dt, EqvtPipePress); + if (BrakeOpModeFlag<>bom_PS) then + if (BrakeOpModeFlagMHZ_EN57) then + dpMainValve:=Handle.GetPF(BrakeCtrlPosR, PipePress, temp, dt, EqvtPipePress) + else + dpMainValve:=Handle.GetPF(0, PipePress, temp, dt, EqvtPipePress); + if (dpMainValve<0){and(PipePressureVal>0.01)} then {50} if Compressor>ScndPipePress then begin @@ -2447,7 +2508,7 @@ procedure T_MoverParameters.UpdatePipePressure(dt:real); end; // if(EmergencyBrakeFlag)and(BrakeCtrlPosNo=0)then {ulepszony hamulec bezp.} - if(EmergencyBrakeFlag)or TestFlag(SecuritySystem.Status,s_SHPebrake) or TestFlag(SecuritySystem.Status,s_CAebrake) or (s_CAtestebrake=true)then {ulepszony hamulec bezp.} + if(EmergencyBrakeFlag)or TestFlag(SecuritySystem.Status,s_SHPebrake) or TestFlag(SecuritySystem.Status,s_CAebrake) or (s_CAtestebrake=true) or (TestFlag(EngDmgFlag,32)){ or (not Battery)}then {ulepszony hamulec bezp.} dpMainValve:=dpMainValve/1+PF(0,PipePress,0.15)*dt; //0.2*Spg Pipe.Flow(-dpMainValve); @@ -2483,11 +2544,18 @@ procedure T_MoverParameters.UpdatePipePressure(dt:real); if(DynamicBrakeFlag)and(EngineType=ElectricInductionMotor)then begin - if(Vel>10)then LocBrakePress:=0 else - if(Vel>5)then LocBrakePress:=(10-Vel)/5*LocBrakePress - end; + (Hamulec as TLSt).SetLBP(LocBrakePress); +// if(Vel>10)then LocBrakePress:=0 else +// if(Vel>5)then LocBrakePress:=(10-Vel)/5*LocBrakePress + end + else + (Hamulec as TLSt).SetLBP(LocBrakePress); + if (BrakeValve = EStED) then + if MBPM<2 then + (Hamulec as TEStED).PLC(MaxBrakePress[LoadFlag]) + else + (Hamulec as TEStED).PLC(TotalMass); - (Hamulec as TLSt).SetLBP(LocBrakePress); end; CV1_L_TR: begin @@ -2499,7 +2567,7 @@ procedure T_MoverParameters.UpdatePipePressure(dt:real); begin if MBPM<2 then (Hamulec as TNESt3).PLC(MaxBrakePress[LoadFlag]) - else + else (Hamulec as TNESt3).PLC(TotalMass); LocBrakePress:=LocHandle.GetCP; (Hamulec as TNESt3).SetLBP(LocBrakePress); @@ -2573,7 +2641,7 @@ procedure T_MoverParameters.CompressorCheck(dt:real); else begin CompressedVolume:=CompressedVolume+dt*CompressorSpeed*(2*MaxCompressor-Compressor)/MaxCompressor; - TotalCurrent:=0.0015*Voltage; //tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę + TotalCurrent:=TotalCurrent+0.0015*Voltage; //tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę end else begin @@ -2639,11 +2707,11 @@ procedure T_MoverParameters.CompressorCheck(dt:real); begin CompressedVolume:=CompressedVolume+dt*CompressorSpeed*(2*MaxCompressor-Compressor)/MaxCompressor; if (CompressorPower=5)and(Couplers[1].Connected<>NIL) then - Couplers[1].Connected.TotalCurrent:=0.0015*Couplers[1].Connected.Voltage //tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę + Couplers[1].Connected.TotalCurrent:=Couplers[1].Connected.TotalCurrent+0.0015*Couplers[1].Connected.Voltage //tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę else if (CompressorPower=4)and(Couplers[0].Connected<>NIL) then - Couplers[0].Connected.TotalCurrent:=0.0015*Couplers[0].Connected.Voltage //tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę + Couplers[0].Connected.TotalCurrent:=Couplers[0].Connected.TotalCurrent+0.0015*Couplers[0].Connected.Voltage //tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę else - TotalCurrent:=0.0015*Voltage; //tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę + TotalCurrent:=TotalCurrent+0.0015*Voltage; //tymczasowo tylko obciążenie sprężarki, tak z 5A na sprężarkę end end; end; @@ -2751,7 +2819,7 @@ function T_MoverParameters.FuseFlagCheck: boolean; function T_MoverParameters.FuseOn: boolean; begin FuseOn:=false; - if (MainCtrlPos=0) and (ScndCtrlPos=0) and (TrainType<>dt_ET40) and Mains then + if (MainCtrlPos=0) and (ScndCtrlPos=0) and (TrainType<>dt_ET40) and ((Mains) or (TrainType<>dt_EZT)) and (not TestFlag(EngDmgFlag,1)) then begin //w ET40 jest blokada nastawnika, ale czy działa dobrze? SendCtrlToNext('FuseSwitch',1,CabNo); if ((EngineType=ElectricSeriesMotor)or((EngineType=DieselElectric))) and FuseFlag then @@ -3520,7 +3588,7 @@ function T_MoverParameters.AutoRelayCheck: boolean; begin //Ra 2014-06: dla SN61 nie działa prawidłowo //rozlaczanie stycznikow liniowych - if (not Mains) or (FuseFlag) or (MainCtrlPos=0) or (BrakePress>2.1) or (ActiveDir=0) then //hunter-111211: wylacznik cisnieniowy + if (not Mains) or (FuseFlag) or (MainCtrlPos=0) or ((BrakePress>2.1)and(TrainType<>dt_EZT)) or (ActiveDir=0) then //hunter-111211: wylacznik cisnieniowy begin StLinFlag:=false; //yBARC - rozlaczenie stycznikow liniowych AutoRelayCheck:=false; @@ -3537,6 +3605,9 @@ function T_MoverParameters.AutoRelayCheck: boolean; //brak PSR na tej pozycji działa PSR i prąd poniżej progu na tej pozycji nie działa PSR i pozycja walu ponizej // chodzi w tym wszystkim o to, żeby można było zatrzymać rozruch na jakiejś pozycji wpisując Autoswitch=0 i wymuszać // przejście dalej przez danie nastawnika na dalszą pozycję - tak to do tej pory działało i na tym się opiera fizyka ET22-2k + +////// LocalBrakePos:=byte(ARFASI)+2*byte(ARFASI2); + begin if (StLinFlag) then begin @@ -3655,7 +3726,7 @@ function T_MoverParameters.AutoRelayCheck: boolean; begin OK:=false; //ybARC - tutaj sa wszystkie warunki, jakie musza byc spelnione, zeby mozna byla zalaczyc styczniki liniowe - if ((MainCtrlPos=1)or((TrainType=dt_EZT)and(MainCtrlPos>0)))and(not FuseFlag)and(Mains)and(BrakePress<1.0)and(MainCtrlActualPos=0)and(ActiveDir<>0) then + if ((MainCtrlPos=1)or((TrainType=dt_EZT)and(MainCtrlPos>0)))and(not FuseFlag)and(Mains)and((BrakePress<1.0)or(TrainType=dt_EZT))and(MainCtrlActualPos=0)and(ActiveDir<>0) then begin DelayCtrlFlag:=true; if (LastRelayTime>=InitialCtrlDelay) then @@ -3678,7 +3749,7 @@ function T_MoverParameters.AutoRelayCheck: boolean; MainCtrlActualPos:=0; OK:=true; end - else + else if(LastRelayTime>CtrlDownDelay)then begin if(MainCtrlActualPosImax) then - Vhyp:=Vhyp+dt*(Abs(Im)/Imax-0.9)*10 //zwieksz czas oddzialywania na PN + Vhyp:=Vhyp+dt//*(Abs(Im)/Imax-0.9)*10 //zwieksz czas oddzialywania na PN else Vhyp:=0; if (Vhyp>CtrlDelay/2) then //jesli czas oddzialywania przekroczony +// dec(MainCtrlActualPos); FuseOff; {wywalanie bezpiecznika z powodu przetezenia silnikow} if (Mains) then //nie wchodzić w funkcję bez potrzeby - if (Abs(Voltage)EnginePowerSource.CollectorParameters.MaxV) then + if (Abs(Voltage)EnginePowerSource.CollectorParameters.MaxV) then if MainSwitch(false) then EventFlag:=true; //wywalanie szybkiego z powodu niewłaściwego napięcia @@ -4292,34 +4365,66 @@ function T_MoverParameters.TractionForce(dt:real):real; end; ElectricInductionMotor: begin - if (Voltage>1800) and (MainS) then + if (Mains) then //nie wchodzić w funkcję bez potrzeby + if (Abs(Voltage)EnginePowerSource.CollectorParameters.MaxV+200) then + begin + MainSwitch(false); + end; + tmpV:=abs(nrot)*(Pi*WheelDiameter)*3.6;//*DirAbsolute*eimc[eimc_s_p]; - do przemyslenia dzialanie pp + if (MainS) then begin - if ((Hamulec as TLSt).GetEDBCP<0.25)and(LocHandle.GetCP<0.25) then + dtrans:=(Hamulec as TLSt).GetEDBCP; + if ((DoorLeftOpened)or(DoorRightOpened)) then + DynamicBrakeFlag:=true + else if ((dtrans<0.25) and (LocHandle.GetCP<0.25) and (AnPos<0.01)) or ((dtrans<0.25) and (ShuntModeAllow) and (LocalBrakePos=0)) then DynamicBrakeFlag:=false - else if ((BrakePress>0.25) and ((Hamulec as TLSt).GetEDBCP>0.25)) or (LocHandle.GetCP>0.25) then + else if (((BrakePress>0.25) and (dtrans>0.25) or (LocHandle.GetCP>0.25))) or (AnPos>0.02) then DynamicBrakeFlag:=true; - + dtrans:=(Hamulec as TLSt).GetEDBCP*eimc[eimc_p_abed]; //stala napedu if(DynamicBrakeFlag)then begin if eimv[eimv_Fmax]*sign(V)*DirAbsolute<-1 then - PosRatio:=-sign(V)*DirAbsolute*eimv[eimv_Fr]/(eimc[eimc_p_Fh]*Max0R((Hamulec as TLSt).GetEDBCP,LocHandle.GetCP)/MaxBrakePress[0]{dizel_fill}) + begin + PosRatio:=-sign(V)*DirAbsolute*eimv[eimv_Fr]/(eimc[eimc_p_Fh]*Max0R(dtrans/MaxBrakePress[0],AnPos){dizel_fill}); + end else PosRatio:=0; PosRatio:=round(20*Posratio)/20; if PosRatio<19.5/20 then PosRatio:=PosRatio*0.9; - (Hamulec as TLSt).SetED(PosRatio); - PosRatio:=-Max0R((Hamulec as TLSt).GetEDBCP,LocHandle.GetCP)/MaxBrakePress[0]*Max0R(0,Min0R(1,(Vel-eimc[eimc_p_Vh0])/(eimc[eimc_p_Vh1]-eimc[eimc_p_Vh0]))); +// if PosRatio<0 then +// PosRatio:=2+PosRatio-2; + (Hamulec as TLSt).SetED(Max0R(0.0,Min0R(PosRatio,1))); +// (Hamulec as TLSt).SetLBP(LocBrakePress*(1-PosRatio)); + PosRatio:=-Max0R(Min0R(dtrans/MaxBrakePress[0],1),AnPos)*Max0R(0,Min0R(1,(Vel-eimc[eimc_p_Vh0])/(eimc[eimc_p_Vh1]-eimc[eimc_p_Vh0]))); + eimv[eimv_Fzad]:=-Max0R(LocalBrakeRatio,dtrans/MaxBrakePress[0]); tmp:=5; end else begin PosRatio:=(MainCtrlPos/MainCtrlPosNo); + eimv[eimv_Fzad]:=PosRatio; + if(Flat)and(eimc[eimc_p_F0]*eimv[eimv_Fful]>0)then + PosRatio:=Min0R(PosRatio*eimc[eimc_p_F0]/eimv[eimv_Fful],1); + if ScndCtrlActualPos>0 then + if (Vmax<250) then + PosRatio:=Min0R(PosRatio,Max0R(-1,0.5*(ScndCtrlActualPos-Vel))) + else + PosRatio:=Min0R(PosRatio,Max0R(-1,0.5*(ScndCtrlActualPos*2-Vel))); PosRatio:=1.0*(PosRatio*0+1)*PosRatio; (Hamulec as TLSt).SetED(0); +// (Hamulec as TLSt).SetLBP(LocBrakePress); if (PosRatio>dizel_fill) then tmp:=1 else tmp:=4; //szybkie malenie, powolne wzrastanie end; - if SlippingWheels then begin PosRatio:=0; tmp:=10; SandDoseOn; end;//przeciwposlizg +// if SlippingWheels then begin PosRatio:=0; tmp:=10; SandDoseOn; end;//przeciwposlizg + +// if(Flat)then //PRZECIWPOŚLIZG + dmoment:=eimv[eimv_Fful]; +// else +// dmoment:=eimc[eimc_p_F0]*0.99; + if (abs((PosRatio+9.66*dizel_fill)*dmoment*100)>0.95*Adhesive(RunningTrack.friction)*TotalMassxg) then begin PosRatio:=0; tmp:=4; SandDoseOn; end;//przeciwposlizg + if (abs((PosRatio+9.80*dizel_fill)*dmoment*100)>0.95*Adhesive(RunningTrack.friction)*TotalMassxg) then begin PosRatio:=0; tmp:=9; SandDoseOn; end;//przeciwposlizg + if (SlippingWheels) then begin PosRatio:=-PosRatio*0; tmp:=9; SandDoseOn; end;//przeciwposlizg dizel_fill:=dizel_fill+Max0R(Min0R(PosRatio-dizel_fill,0.1),-0.1)*2*(tmp{2{+4*byte(PosRatioeimc[eimc_p_Vh0])then - eimv[eimv_Fmax]:=-sign(V)*(DirAbsolute)*Min0R(eimc[eimc_p_Ph]*3.6/Vel,-eimc[eimc_p_Fh]*dizel_fill)//*Min0R(1,(Vel-eimc[eimc_p_Vh0])/(eimc[eimc_p_Vh1]-eimc[eimc_p_Vh0])) -// else -// eimv[eimv_Fmax]:=0 + if(dizel_fill<0)then + begin + eimv[eimv_Fful]:=Min0R(eimc[eimc_p_Ph]*3.6/Vel,Min0R(eimc[eimc_p_Fh],eimv[eimv_FMAXMAX])); + eimv[eimv_Fmax]:=-sign(V)*(DirAbsolute)*Min0R(eimc[eimc_p_Ph]*3.6/Vel,Min0R(-eimc[eimc_p_Fh]*dizel_fill,eimv[eimv_FMAXMAX]));//*Min0R(1,(Vel-eimc[eimc_p_Vh0])/(eimc[eimc_p_Vh1]-eimc[eimc_p_Vh0])) + end else - eimv[eimv_Fmax]:=Min0R(Min0R(3.6*eimv[eimv_Pmax]/Max0R(Vel,1),eimc[eimc_p_F0]-Vel*eimc[eimc_p_a1]),eimv[eimv_FMAXMAX])*dizel_fill; + begin + eimv[eimv_Fful]:=Min0R(Min0R(3.6*eimv[eimv_Pmax]/Max0R(Vel,1),eimc[eimc_p_F0]-Vel*eimc[eimc_p_a1]),eimv[eimv_FMAXMAX]); +// if(not Flat)then + eimv[eimv_Fmax]:=eimv[eimv_Fful]*dizel_fill +// else +// eimv[eimv_Fmax]:=Min0R(eimc[eimc_p_F0]*dizel_fill,eimv[eimv_Fful]); + end; + eimv[eimv_ks]:=eimv[eimv_Fmax]/eimv[eimv_FMAXMAX]; eimv[eimv_df]:=eimv[eimv_ks]*eimc[eimc_s_dfmax]; - eimv[eimv_fp]:=DirAbsolute*enrot*eimc[eimc_s_p]+eimv[eimv_df]; + eimv[eimv_fp]:=DirAbsolute*enrot*eimc[eimc_s_p]+eimv[eimv_df]; //do przemyslenia dzialanie pp z tmpV // eimv[eimv_U]:=Max0R(eimv[eimv_Uzsmax],Min0R(eimc[eimc_f_cfu]*eimv[eimv_fp],eimv[eimv_Uzsmax])); // eimv[eimv_pole]:=eimv[eimv_U]/(eimv[eimv_fp]*eimc[eimc_s_cfu]); if(abs(eimv[eimv_fp])<=eimv[eimv_fkr])then @@ -4360,18 +4471,24 @@ function T_MoverParameters.TractionForce(dt:real):real; eimv[eimv_eta]:=eimv[eimv_Pm]/eimv[eimv_Pe]; Im:=eimv[eimv_If]; - Itot:=eimv[eimv_Ipoj]; + if (eimv[eimv_Ipoj]>=0) then + Vadd:=Vadd*(1-2*dt) + else if (Voltage1) or (abs(tmpV)>0.1) then + if ((abs(eimv[eimv_If])>1) or (abs(tmpV)>0.1))and(RlistSize>0) then begin - if abs(tmpV)<32 then RventRot:=1.0 else - if abs(tmpV)<39 then RventRot:=0.33*abs(tmpV)/32 else - RventRot:=0.25*abs(tmpV)/39;//} + i:=0; + while (i0 then FTrain:=TractionForce(dt) @@ -4851,34 +4977,43 @@ function T_MoverParameters.ComputeMovement(dt:real; dt1:real; Shape:TTrackShape; var b:byte; Vprev,AccSprev:real; // Iheat:real; prad ogrzewania + hvc: real; const Vepsilon=1e-5; Aepsilon=1e-3; //ASBSpeed=0.8; begin -{ + TotalCurrent:=0; + hvc:=Max0R(Max0R(PantFrontVolt,PantRearVolt),ElectricTraction.TractionVoltage); for b:=0 to 1 do //przekazywanie napiec if ((Couplers[b].CouplingFlag and ctrain_power) = ctrain_power)or(((Couplers[b].CouplingFlag and ctrain_heating) = ctrain_heating)and(Heating)) then begin - HVCouplers[1-b][1]:=Max0R(Abs(Voltage),Couplers[b].Connected.HVCouplers[Couplers[b].ConnectedNr][1]); + HVCouplers[1-b][1]:=Max0R(Abs(hvc),Couplers[b].Connected.HVCouplers[Couplers[b].ConnectedNr][1]-HVCouplers[b][0]*0.02); end else - HVCouplers[1-b][1]:=Max0R(Abs(Voltage),0); - end; + HVCouplers[1-b][1]:=Abs(hvc)-HVCouplers[b][0]*0.02;//Max0R(Abs(Voltage),0); +// end; - for b:=0 to 1 do //przekazywanie pradow - if ((Couplers[b].CouplingFlag and ctrain_power) = ctrain_power)or(((Couplers[b].CouplingFlag and ctrain_heating) = ctrain_heating)and(Heating)) then //jesli spiety - begin - if (HVCouplers[b][1]) > 1 then //przewod pod napiecie - HVCouplers[b][0]:=Couplers[b].Connected.HVCouplers[1-Couplers[b].ConnectedNr][0]+Iheat//obciążenie - else - HVCouplers[b][0]:=0; - end - else //pierwszy pojazd - begin - if (HVCouplers[b][1]) > 1 then //pod napieciem - HVCouplers[b][0]:=0+Iheat//obciążenie - else - HVCouplers[b][0]:=0; - end; -} + hvc:=HVCouplers[0][1]+HVCouplers[1][1]; + + if (Abs(PantFrontVolt)+Abs(PantRearVolt)<1) and (hvc>1)then //bez napiecia, ale jest cos na sprzegach: + begin + for b:=0 to 1 do //przekazywanie pradow + if ((Couplers[b].CouplingFlag and ctrain_power) = ctrain_power)or(((Couplers[b].CouplingFlag and ctrain_heating) = ctrain_heating)and(Heating)) then //jesli spiety + begin + HVCouplers[b][0]:=Couplers[b].Connected.HVCouplers[1-Couplers[b].ConnectedNr][0]+Itot*HVCouplers[b][1]/hvc; //obciążenie rozkladane stosownie do napiec + end + else //pierwszy pojazd + begin + HVCouplers[b][0]:=Itot*HVCouplers[b][1]/hvc; + end; + end + else + begin + if ((Couplers[0].CouplingFlag and ctrain_power) = ctrain_power)or(((Couplers[0].CouplingFlag and ctrain_heating) = ctrain_heating)and(Heating)) then + TotalCurrent:=TotalCurrent+Couplers[0].Connected.HVCouplers[1-Couplers[0].ConnectedNr][0]; + if ((Couplers[1].CouplingFlag and ctrain_power) = ctrain_power)or(((Couplers[1].CouplingFlag and ctrain_heating) = ctrain_heating)and(Heating)) then + TotalCurrent:=TotalCurrent+Couplers[1].Connected.HVCouplers[1-Couplers[1].ConnectedNr][0]; + HVCouplers[0][0]:=0; + HVCouplers[1][0]:=0; + end; ClearPendingExceptions; if not TestFlag(DamageFlag,dtrain_out) then @@ -4888,7 +5023,7 @@ function T_MoverParameters.ComputeMovement(dt:real; dt1:real; Shape:TTrackShape; RunningTraction:=ElectricTraction; with ElectricTraction do if not DynamicBrakeFlag then - RunningTraction.TractionVoltage:=TractionVoltage-Abs(TractionResistivity*(Itot+HVCouplers[0][0]+HVCouplers[1][0])) + RunningTraction.TractionVoltage:=TractionVoltage{-Abs(TractionResistivity*(Itot+HVCouplers[0][0]+HVCouplers[1][0]))} else RunningTraction.TractionVoltage:=TractionVoltage-Abs(TractionResistivity*Itot*0); //zasadniczo ED oporowe nie zmienia napięcia w sieci end; @@ -5174,6 +5309,14 @@ function T_MoverParameters.RunCommand(command:string; CValue1,CValue2:real):bool end else if command='ScndCtrl' then begin + if (EngineType=ElectricInductionMotor) then + if (ScndCtrlPos=0) and (Trunc(CValue1)>0) then + if (Vmax<250) then + ScndCtrlActualPos:=Round(Vel+0.5) + else + ScndCtrlActualPos:=Round(Vel/2+0.5) + else if (Trunc(CValue1)=0) then + ScndCtrlActualPos:=0; if ScndCtrlPosNo>=Trunc(CValue1) then ScndCtrlPos:=Trunc(CValue1); OK:=SendCtrlToNext(command,CValue1,CValue2); @@ -5417,7 +5560,7 @@ function T_MoverParameters.RunCommand(command:string; CValue1,CValue2:real):bool end else if command='Emergency_brake' then begin - if EmergencyBrakeSwitch(Trunc(CValue1)=1) then + if EmergencyBrakeSwitch(Trunc(CValue1)=1) then //YB: czy to jest potrzebne? OK:=true else OK:=false; end @@ -5544,6 +5687,8 @@ constructor T_MoverParameters.Init(//LocInitial:TLocation; RotInitial:TRotation; end; WheelDiameter:=1.0; BrakeCtrlPosNo:=0; + LightsPosNo:=0; + LightsDefPos:=1; for k:=-1 to MainBrakeMaxPos do with BrakePressureTable[k] do begin @@ -5623,6 +5768,10 @@ constructor T_MoverParameters.Init(//LocInitial:TLocation; RotInitial:TRotation; InsideConsist:=false; CompressorPower:=1; SmallCompressorPower:=0; + for b:=0 to 25 do + eimc[b]:=0; + eimc[eimc_p_eped]:=1.5; + StopBrakeDecc:=0; ScndInMain:=false; @@ -5654,6 +5803,7 @@ constructor T_MoverParameters.Init(//LocInitial:TLocation; RotInitial:TRotation; ScndCtrlPos:=0; MainCtrlActualPos:=0; ScndCtrlActualPos:=0; + LightsPos:=0; Heating:=false; Mains:=false; ActiveDir:=0; //kierunek nie ustawiony @@ -5717,6 +5867,8 @@ constructor T_MoverParameters.Init(//LocInitial:TLocation; RotInitial:TRotation; dizel_enginestart:=false; dizel_engagedeltaomega:=0; PhysicActivation:=true; + for b:=1 to 20 do + eimv[b]:=0; with RunningShape do begin @@ -5897,6 +6049,10 @@ function T_MoverParameters.CheckLocomotiveParameters(ReadyFlag:boolean;Dir:longi EStED :begin Hamulec := TEStED.Create(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); (Hamulec as TEStED).SetRM(RapidMult); + if(MBPM<2)then //jesli przystawka wazaca + (Hamulec as TEStED).SetLP(0,MaxBrakePress[3],0) + else + (Hamulec as TEStED).SetLP(Mass, MBPM, MaxBrakePress[1]); end; EP2:begin Hamulec :=TEStEP2.Create(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); @@ -5915,6 +6071,7 @@ function T_MoverParameters.CheckLocomotiveParameters(ReadyFlag:boolean;Dir:longi case BrakeHandle of FV4a: Handle := TFV4aM.Create; + MHZ_EN57: Handle := TMHZ_EN57.Create; FVel6: Handle := TFVel6.Create; testH: Handle := Ttest.Create; M394: Handle := TM394.Create; @@ -5929,6 +6086,8 @@ function T_MoverParameters.CheckLocomotiveParameters(ReadyFlag:boolean;Dir:longi begin LocHandle := TFD1.Create; LocHandle.Init(MaxBrakePress[0]); + if(TrainType=dt_EZT)then + (LocHandle as TFD1).SetSpeed(3.5); end; Knorr: begin @@ -5950,7 +6109,9 @@ function T_MoverParameters.CheckLocomotiveParameters(ReadyFlag:boolean;Dir:longi Pipe.CreateCap((Max0R(Dim.L,14)+0.5)*Spg*1); //dlugosc x przekroj x odejscia i takie tam Pipe2.CreateCap((Max0R(Dim.L,14)+0.5)*Spg*1); - {to dac potem do init} + if LightsPosNo>0 then LightsPos:=LightsDefPos; + +{to dac potem do init} if ReadyFlag then {gotowy do drogi} begin CompressedVolume:=VeselVolume*MinCompressor*(9.8+Random)/10; @@ -5978,8 +6139,8 @@ function T_MoverParameters.CheckLocomotiveParameters(ReadyFlag:boolean;Dir:longi CompressedVolume:=VeselVolume*MinCompressor*0.55; ScndPipePress:=5.1; PipePress:=LowPipePress; - PipeBrakePress:=MaxBrakePress[3]; - BrakePress:=MaxBrakePress[3]; + PipeBrakePress:=MaxBrakePress[3]*0.5; + BrakePress:=MaxBrakePress[3]*0.5; LocalBrakePos:=0; // if (BrakeSystem=Pneumatic) and (BrakeCtrlPosNo>0) then // BrakeCtrlPos:=-2; //Ra: hamulec jest poprawiany w DynObj.cpp @@ -6029,6 +6190,12 @@ function T_MoverParameters.CheckLocomotiveParameters(ReadyFlag:boolean;Dir:longi if(TestFlag(BrakeDelays,bdelay_R))and not(TestFlag(BrakeDelays,bdelay_G))then BrakeDelayFlag:=bdelay_R; +//ustawianie PS/PN/EP/MED + BrakeOpModeFlag:=bom_PN; + if (BrakeOpModes and bom_PS)>0 then BrakeOpModeFlag:=bom_PS; +// if (BrakeOpModes and bom_EP)>0 then BrakeOpModeFlag:=bom_EP; +// if (BrakeOpModes and bom_MED)>0 then BrakeOpModeFlag:=bom_MED; +// //yB: jesli pojazdy nie maja zadeklarowanych czasow, to wsadz z przepisow +-16,(6)% for b:=1 to 4 do begin @@ -6312,6 +6479,11 @@ function PowerDecode(s:string): TPowerType; MaxH:=s2rE(DUE(ExtractKeyWord(lines,'MaxH='))); CSW:=s2rE(DUE(ExtractKeyWord(lines,'CSW='))); //szerokość części roboczej MaxV:=s2rE(DUE(ExtractKeyWord(lines,'MaxVoltage='))); + s:=ExtractKeyWord(lines,'OverVoltProt='); //przekaźnik nadnapięciowy + if s='Yes' then + OVP:=1 + else + OVP:=0; s:=ExtractKeyWord(lines,'MinV='); //napięcie rozłączające WS if s='' then MinV:=0.5*MaxV //gdyby parametr nie podany @@ -6564,6 +6736,7 @@ function PowerDecode(s:string): TPowerType; if s='P10-Bg' then BrakeMethod:=bp_P10Bg else if s='P10-Bgu' then BrakeMethod:=bp_P10Bgu else if s='FR513' then BrakeMethod:=bp_FR513 else + if s='FR510' then BrakeMethod:=bp_FR510 else if s='Cosid' then BrakeMethod:=bp_Cosid else if s='P10yBg' then BrakeMethod:=bp_P10yBg else if s='P10yBgu' then BrakeMethod:=bp_P10yBgu else @@ -6642,6 +6815,7 @@ function PowerDecode(s:string): TPowerType; s:=DUE(ExtractKeyWord(lines,'DoorOpenMethod=')); if s='Shift' then DoorOpenMethod:=1 //przesuw else if s='Fold' then DoorOpenMethod:=3 //3 submodele się obracają + else if s='Plug' then DoorOpenMethod:=4 //odskokowo-przesuwne else DoorOpenMethod:=2; //obrót s:=DUE(ExtractKeyWord(lines,'DoorClosureWarning=')); @@ -6653,6 +6827,16 @@ function PowerDecode(s:string): TPowerType; if s='Yes' then DoorBlocked:=true else DoorBlocked:=false; + s:=ExtractKeyWord(lines,'DoorMaxShiftPlug='); + DoorMaxPlugShift:=s2r(DUE(s)); + s:=ExtractKeyWord(lines,'PlatformSpeed='); + PlatformSpeed:=s2r(DUE(s)); + s:=ExtractKeyWord(lines,'PlatformMaxSpeed='); + PlatformMaxShift:=s2r(DUE(s)); + s:=DUE(ExtractKeyWord(lines,'PlatformOpenMethod=')); + if s='Shift' then PlatformOpenMethod:=1 //przesuw + else + PlatformOpenMethod:=2; //obrót end else if (Pos('BuffCoupl.',lines)>0) or (Pos('BuffCoupl1.',lines)>0) then {zderzaki i sprzegi} begin @@ -6828,6 +7012,10 @@ function PowerDecode(s:string): TPowerType; else if s='GPR+Mg' then BrakeDelays:=bdelay_G+bdelay_P+bdelay_R+bdelay_M else if s='PR+Mg' then BrakeDelays:=bdelay_P+bdelay_R+bdelay_M; + s:=DUE(ExtractKeyWord(lines,'BrakeOpModes=')); + if s='PN' then BrakeOpModes:=bom_PS+bom_PN + else if s='PNEPMED' then BrakeOpModes:=bom_PS+bom_PN+bom_EP+bom_MED; + { else if s='DPR+Mg' then begin Brakedelays:=bdelay_R; BrakeMethod:=3; end else if s='DGPR+Mg' then begin Brakedelays:=bdelay_G+bdelay_R; BrakeMethod:=3; end else if s='DGPR' then begin Brakedelays:=bdelay_G+bdelay_R; BrakeMethod:=1; end @@ -6839,6 +7027,7 @@ function PowerDecode(s:string): TPowerType; if s='FV4a' then BrakeHandle:=FV4a else if s='test' then BrakeHandle:=testH else if s='D2' then BrakeHandle:=D2 + else if s='MHZ_EN57' then BrakeHandle:=MHZ_EN57 else if s='M394' then BrakeHandle:=M394 else if s='Knorr' then BrakeHandle:=Knorr else if s='Westinghouse' then BrakeHandle:=West @@ -6919,6 +7108,8 @@ function PowerDecode(s:string): TPowerType; FastSerialCircuit:=1 else FastSerialCircuit:=0; + s:=ExtractKeyWord(lines,'SBD='); + StopBrakeDecc:=s2r(DUE(s)); if BrakeCtrlPosNo>0 then for i:=0 to BrakeCtrlPosNo+1 do @@ -7169,7 +7360,9 @@ function PowerDecode(s:string): TPowerType; s:=ExtractKeyWord(lines,'Vh0='); eimc[eimc_p_Vh0]:=s2r(DUE(s)); s:=ExtractKeyWord(lines,'Vh1='); eimc[eimc_p_Vh1]:=s2r(DUE(s)); s:=ExtractKeyWord(lines,'Imax='); eimc[eimc_p_Imax]:=s2r(DUE(s)); - + s:=ExtractKeyWord(lines,'abed='); if DUE(s)<>'' then eimc[eimc_p_abed]:=s2r(DUE(s)); + s:=ExtractKeyWord(lines,'edep='); if DUE(s)<>'' then eimc[eimc_p_eped]:=s2r(DUE(s)); + s:=ExtractKeyWord(lines,'Flat='); if DUE(s)='Yes' then Flat:=true else Flat:=false; end; else ConversionError:=-13; {not implemented yet!} @@ -7357,7 +7550,22 @@ function PowerDecode(s:string): TPowerType; SST[k].Pmax:=Min0R(SST[k].Pmax,sqr(SST[k].Umax)/47.6); end; end; + end + else if (Pos('ffList:',lines)>0) then {dla asynchronow} + begin + RListSize:=s2b(DUE(ExtractKeyWord(lines,'Size='))); + for k:=0 to RListSize do + readln(fin, DEList[k].rpm, DEList[k].genpower) + end + else if (Pos('LightsList:',lines)>0) then {dla asynchronow} + begin + LightsPosNo:=s2b(DUE(ExtractKeyWord(lines,'Size='))); + LightsWrap:=('Yes')=(DUE(ExtractKeyWord(lines,'Wrap='))); + LightsDefPos:=s2b(DUE(ExtractKeyWord(lines,'Default='))); + for k:=1 to LightsPosNo do + readln(fin, Lights[0][k], Lights[1][k]) end; + end; end; {koniec filtru importu parametrow} if ConversionError=0 then diff --git a/McZapkie/hamulce.hpp b/McZapkie/hamulce.hpp index a868bddd2..4deb23de0 100644 --- a/McZapkie/hamulce.hpp +++ b/McZapkie/hamulce.hpp @@ -322,11 +322,17 @@ class PASCALIMPLEMENTATION TEStED : public TLSt bool Zamykajacy; bool Przys_blok; TReservoir* Miedzypoj; + double TareM; + double LoadM; + double TareBP; + double LoadC; public: virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF); virtual double __fastcall GetPF(double PP, double dt, double Vel); virtual double __fastcall GetEDBCP(void); + void __fastcall PLC(double mass); + void __fastcall SetLP(double TM, double LM, double TBP); public: #pragma option push -w-inl /* TBrake.Create */ inline __fastcall TEStED(double i_mbp, double i_bcr, double i_bcd, double i_brc @@ -584,6 +590,37 @@ class PASCALIMPLEMENTATION TFV4aM : public THandle }; +class DELPHICLASS TMHZ_EN57; +class PASCALIMPLEMENTATION TMHZ_EN57 : public THandle +{ + typedef THandle inherited; + +private: + double CP; + double TP; + double RP; + double RedAdj; + bool Fala; + +public: + virtual double __fastcall GetPF(double i_bcp, double pp, double hp, double dt, double ep); + virtual void __fastcall Init(double press); + virtual void __fastcall SetReductor(double nAdj); + virtual double __fastcall GetSound(Byte i); + virtual double __fastcall GetPos(Byte i); + virtual double __fastcall GetCP(void); + double __fastcall GetEP(double pos); +public: + #pragma option push -w-inl + /* TObject.Create */ inline __fastcall TMHZ_EN57(void) : THandle() { } + #pragma option pop + #pragma option push -w-inl + /* TObject.Destroy */ inline __fastcall virtual ~TMHZ_EN57(void) { } + #pragma option pop + +}; + + class DELPHICLASS TM394; class PASCALIMPLEMENTATION TM394 : public THandle { @@ -692,9 +729,11 @@ class PASCALIMPLEMENTATION TFD1 : public THandle double BP; public: + double Speed; virtual double __fastcall GetPF(double i_bcp, double pp, double hp, double dt, double ep); virtual void __fastcall Init(double press); virtual double __fastcall GetCP(void); + void __fastcall SetSpeed(double nSpeed); public: #pragma option push -w-inl /* TObject.Create */ inline __fastcall TFD1(void) : THandle() { } @@ -802,6 +841,7 @@ static const Shortint bp_PKPBgu = 0xe; static const Byte bp_MHS = 0x80; static const Shortint bp_P10yBg = 0xf; static const Shortint bp_P10yBgu = 0x10; +static const Shortint bp_FR510 = 0x11; static const Shortint sf_Acc = 0x1; static const Shortint sf_BR = 0x2; static const Shortint sf_CylB = 0x4; diff --git a/McZapkie/hamulce.pas b/McZapkie/hamulce.pas index 18872658c..efd36cbcc 100644 --- a/McZapkie/hamulce.pas +++ b/McZapkie/hamulce.pas @@ -1,3022 +1,3200 @@ -unit hamulce; {fizyka hamulcow dla symulatora} - -(* -This Source Code Form is subject to the -terms of the Mozilla Public License, v. -2.0. If a copy of the MPL was not -distributed with this file, You can -obtain one at -http://mozilla.org/MPL/2.0/. -*) -(* - MaSzyna EU07 - SPKS - Brakes. - Copyright (C) 2007-2014 Maciej Cierniak -*) - - -(* -(C) youBy -Co brakuje: -moze jeszcze jakis SW -*) -(* -Zrobione: -ESt3, ESt3AL2, ESt4R, LSt, FV4a, FD1, EP2, prosty westinghouse -duzo wersji żeliwa -KE -Tarcze od 152A -Magnetyki (implementacja w mover.pas) -Matrosow 394 -H14K1 (zasadniczy), H1405 (pomocniczy), St113 (ep) -Knorr/West EP - żeby był -*) - -interface - -uses mctools,sysutils,friction; - -CONST - - LocalBrakePosNo=10; {ilosc nastaw hamulca recznego lub pomocniczego} - MainBrakeMaxPos=10; {max. ilosc nastaw hamulca zasadniczego} - - {nastawy hamulca} - bdelay_G=1; //G - bdelay_P=2; //P - bdelay_R=4; //R - bdelay_M=8; //Mg - bdelay_GR=128; //G-R - - - {stan hamulca} - b_off = 0; //luzowanie - b_hld = 1; //trzymanie - b_on = 2; //napelnianie - b_rfl = 4; //uzupelnianie - b_rls = 8; //odluzniacz - b_ep = 16; //elektropneumatyczny - b_asb = 32; //elektropneumatyczny - b_dmg =128; //wylaczony z dzialania - - {uszkodzenia hamulca} - df_on = 1; //napelnianie - df_off = 2; //luzowanie - df_br = 4; //wyplyw z ZP - df_vv = 8; //wyplyw z komory wstepnej - df_bc = 16; //wyplyw z silownika - df_cv = 32; //wyplyw z ZS - df_PP = 64; //zawsze niski stopien - df_RR =128; //zawsze wysoki stopien - - {indeksy dzwiekow FV4a} - s_fv4a_b = 0; //hamowanie - s_fv4a_u = 1; //luzowanie - s_fv4a_e = 2; //hamowanie nagle - s_fv4a_x = 3; //wyplyw sterujacego fala - s_fv4a_t = 4; //wyplyw z czasowego - - {pary cierne} - bp_P10 = 0; - bp_P10Bg = 2; //żeliwo fosforowe P10 - bp_P10Bgu = 1; - bp_LLBg = 4; //komp. b.n.t. - bp_LLBgu = 3; - bp_LBg = 6; //komp. n.t. - bp_LBgu = 5; - bp_KBg = 8; //komp. w.t. - bp_KBgu = 7; - bp_D1 = 9; //tarcze - bp_D2 = 10; - bp_FR513 = 11; //Frenoplast FR513 - bp_Cosid = 12; //jakistam kompozyt :D - bp_PKPBg = 13; //żeliwo PKP - bp_PKPBgu = 14; - bp_MHS = 128; //magnetyczny hamulec szynowy - bp_P10yBg = 15; //żeliwo fosforowe P10 - bp_P10yBgu= 16; - - sf_Acc = 1; //przyspieszacz - sf_BR = 2; //przekladnia - sf_CylB = 4; //cylinder - napelnianie - sf_CylU = 8; //cylinder - oproznianie - sf_rel = 16; //odluzniacz - sf_ep = 32; //zawory ep - - bh_MIN= 0; //minimalna pozycja - bh_MAX= 1; //maksymalna pozycja - bh_FS = 2; //napelnianie uderzeniowe //jesli nie ma, to jazda - bh_RP = 3; //jazda - bh_NP = 4; //odciecie - podwojna trakcja - bh_MB = 5; //odciecie - utrzymanie stopnia hamowania/pierwszy 1 stopien hamowania - bh_FB = 6; //pelne - bh_EB = 7; //nagle - bh_EPR= 8; //ep - luzowanie //pelny luz dla ep kątowego - bh_EPN= 9; //ep - utrzymanie //jesli rowne luzowaniu, wtedy sterowanie przyciskiem - bh_EPB=10; //ep - hamowanie //pelne hamowanie dla ep kątowego - - - SpgD=0.7917; - SpO=0.5067; //przekroj przewodu 1" w l/m - //wyj: jednostka dosyc dziwna, ale wszystkie obliczenia - //i pojemnosci sa podane w litrach (rozsadne wielkosci) - //zas dlugosc pojazdow jest podana w metrach - //a predkosc przeplywu w m/s //3.5 - //7//1.5 -// BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (14, 5.4), (9, 5.0), (6, 4.6), (9, 4.5), (9, 4.0), (9, 3.5), (9, 2.8), (34, 2.8)); -// BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (7, 5.0), (2.0, 5.0), (4.5, 4.6), (4.5, 4.2), (4.5, 3.8), (4.5, 3.4), (4.5, 2.8), (8, 2.8)); - BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (7, 5.0), (2.0, 5.0), (4.5, 4.6), (4.5, 4.2), (4.5, 3.8), (4.5, 3.4), (4.5, 2.8), (8, 2.8)); - BPT_394: array[-1..5] of array [0..1] of real= ((13, 10.0), (5, 5.0), (0, -1), (5, -1), (5, 0.0), (5, 0.0), (18, 0.0)); -// BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (12, 5.4), (9, 5.0), (9, 4.6), (9, 4.2), (9, 3.8), (9, 3.4), (9, 2.8), (34, 2.8)); -// BPT: array[-2..6] of array [0..1] of real= ((0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0)); - i_bcpno= 6; - -TYPE - //klasa obejmujaca pojedyncze zbiorniki - TReservoir= class - protected - Cap: real; - Vol: real; - dVol: real; - public - constructor Create; - procedure CreateCap(Capacity: real); - procedure CreatePress(Press: real); - function pa: real; virtual; - function P: real; virtual; - procedure Flow(dv: real); - procedure Act; - end; - - PReservoir=^TReservoir; - - TBrakeCyl= class(TReservoir) - public - function pa: real; override; - function P: real; override; - end; - - //klasa obejmujaca uklad hamulca zespolonego pojazdu - TBrake= class - protected - BrakeCyl: TReservoir; //silownik - BrakeRes: TReservoir; //ZP - ValveRes: TReservoir; //komora wstepna - BCN: byte; //ilosc silownikow - BCM: real; //przekladnia hamulcowa - BCA: real; //laczny przekroj silownikow - BrakeDelays: byte; //dostepne opoznienia - BrakeDelayFlag: byte; //aktualna nastawa - FM: TFricMat; //material cierny - MaxBP: real; //najwyzsze cisnienie - BA: byte; //osie hamowane - NBpA: byte; //klocki na os - SizeBR: real; //rozmiar^2 ZP (w stosunku do 14") - SizeBC: real; //rozmiar^2 CH (w stosunku do 14") - DCV: boolean; //podwojny zawor zwrotny - ASBP: real; //cisnienie hamulca pp - - BrakeStatus: byte; //flaga stanu - SoundFlag: byte; - public - constructor Create(i_mbp, i_bcr, i_bcd, i_brc: real; - i_bcn, i_BD, i_mat, i_ba, i_nbpa: byte); - //maksymalne cisnienie, promien, skok roboczy, pojemnosc ZP; - //ilosc cylindrow, opoznienia hamulca, material klockow, osie hamowane, klocki na os; - - function GetFC(Vel, N: real): real; virtual; //wspolczynnik tarcia - hamulec wie lepiej - function GetPF(PP, dt, Vel: real): real; virtual; //przeplyw miedzy komora wstepna i PG - function GetBCF: real; //sila tlokowa z tloka - function GetHPFlow(HP, dt: real): real; virtual; //przeplyw - 8 bar - function GetBCP: real; virtual; //cisnienie cylindrow hamulcowych - function GetBRP: real; //cisnienie zbiornika pomocniczego - function GetVRP: real; //cisnienie komory wstepnej rozdzielacza - function GetCRP: real; virtual; //cisnienie zbiornika sterujacego - procedure Init(PP, HPP, LPP, BP: real; BDF: byte); virtual; //inicjalizacja hamulca - function SetBDF(nBDF: byte): boolean; //nastawiacz GPRM - procedure Releaser(state: byte); //odluzniacz - procedure SetEPS(nEPS:real); virtual;//hamulec EP - procedure ASB(state: byte); //hamulec przeciwposlizgowy - function GetStatus(): byte; //flaga statusu, moze sie przydac do odglosow - procedure SetASBP(press: real); //ustalenie cisnienia pp - procedure ForceEmptiness(); virtual; - function GetSoundFlag: byte; -// procedure - end; - - TWest= class(TBrake) - private - LBP: real; //cisnienie hamulca pomocniczego - dVP: real; //pobor powietrza wysokiego cisnienia - EPS: real; //stan elektropneumatyka - TareM, LoadM: real; //masa proznego i pelnego - TareBP: real; //cisnienie dla proznego - LoadC: real; //wspolczynnik przystawki wazacej - public - procedure SetLBP(P: real); //cisnienie z hamulca pomocniczego - function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG - procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; - function GetHPFlow(HP, dt: real): real; override; - procedure PLC(mass: real); //wspolczynnik cisnienia przystawki wazacej - procedure SetEPS(nEPS: real); override; //stan hamulca EP - procedure SetLP(TM, LM, TBP: real); //parametry przystawki wazacej - end; - - TESt= class(TBrake) - private - CntrlRes: TReservoir; //zbiornik sterujący - BVM: real; //przelozenie PG-CH - public - function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG - procedure EStParams(i_crc: real); //parametry charakterystyczne dla ESt - procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; - function GetCRP: real; override; - procedure CheckState(BCP: real; var dV1: real); //glowny przyrzad rozrzadczy - procedure CheckReleaser(dt: real); //odluzniacz - function CVs(bp: real): real; //napelniacz sterujacego - function BVs(BCP: real): real; //napelniacz pomocniczego - end; - - TESt3= class(TESt) - private - CylFlowSpeed: array[0..1] of array [0..1] of real; - public - function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG - end; - - TESt3AL2= class(TESt3) - private - TareM, LoadM: real; //masa proznego i pelnego - TareBP: real; //cisnienie dla proznego - LoadC: real; - public - ImplsRes: TReservoir; //komora impulsowa - function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG - procedure PLC(mass: real); //wspolczynnik cisnienia przystawki wazacej - procedure SetLP(TM, LM, TBP: real); //parametry przystawki wazacej - procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; - end; - - TESt4R= class(TESt) - private - RapidStatus: boolean; - RapidTemp: real; //akrualne, zmienne przelozenie - public - ImplsRes: TReservoir; //komora impulsowa - function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG - procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; - end; - - TLSt= class(TESt4R) - private - CylFlowSpeed: array[0..1] of array [0..1] of real; - LBP: real; //cisnienie hamulca pomocniczego - RM: real; //przelozenie rapida - EDFlag: real; //luzowanie hamulca z powodu zalaczonego ED - public - procedure SetLBP(P: real); //cisnienie z hamulca pomocniczego - procedure SetRM(RMR: real); //ustalenie przelozenia rapida - function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG - function GetHPFlow(HP, dt: real): real; override; //przeplyw - 8 bar - procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; - function GetEDBCP: real; virtual; //cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED w EP09 - procedure SetED(EDstate: real); //stan hamulca ED do luzowania - end; - - TEStED= class(TLSt) //zawor z EP09 - Est4 z oddzielnym przekladnikiem, kontrola rapidu i takie tam - private - Nozzles: array[0..10] of real; //dysze - Zamykajacy: boolean; //pamiec zaworka zamykajacego - Przys_blok: boolean; //blokada przyspieszacza - Miedzypoj: TReservoir; //pojemnosc posrednia (urojona) do napelniania ZP i ZS - public - procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; - function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG - function GetEDBCP: real; override; //cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED w EP09 - end; - - TEStEP2= class(TLSt) - private - TareM, LoadM: real; //masa proznego i pelnego - TareBP: real; //cisnienie dla proznego - LoadC: real; - EPS: real; - public - function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG - procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; //inicjalizacja - procedure PLC(mass: real); //wspolczynnik cisnienia przystawki wazacej - procedure SetEPS(nEPS: real); override; //stan hamulca EP - procedure SetLP(TM, LM, TBP: real); //parametry przystawki wazacej - end; - - TCV1= class(TBrake) - private - CntrlRes: TReservoir; //zbiornik sterujący - BVM: real; //przelozenie PG-CH - public - function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG - procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; - function GetCRP: real; override; - procedure CheckState(BCP: real; var dV1: real); - function CVs(bp: real): real; - function BVs(BCP: real): real; - public - end; - - TCV1R= class(TCV1) - private - ImplsRes: TReservoir; //komora impulsowa - RapidStatus: boolean; - public -// function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG -// procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; - end; - - TCV1L_TR= class(TCV1) - private - ImplsRes: TReservoir; //komora impulsowa - LBP: real; //cisnienie hamulca pomocniczego - public - function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG - procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; - procedure SetLBP(P: real); //cisnienie z hamulca pomocniczego - function GetHPFlow(HP, dt: real): real; override; //przeplyw - 8 bar - end; - - TKE= class(TBrake) //Knorr Einheitsbauart — jeden do wszystkiego - private - RapidStatus: boolean; - ImplsRes: TReservoir; //komora impulsowa - CntrlRes: TReservoir; //zbiornik sterujący - Brak2Res: TReservoir; //zbiornik pomocniczy 2 - BVM: real; //przelozenie PG-CH - TareM, LoadM: real; //masa proznego i pelnego - TareBP: real; //cisnienie dla proznego - LoadC: real; //wspolczynnik zaladowania - RM: real; //przelozenie rapida - LBP: real; //cisnienie hamulca pomocniczego - public - procedure SetRM(RMR: real); //ustalenie przelozenia rapida - function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG - procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; - function GetHPFlow(HP, dt: real): real; override; //przeplyw - 8 bar - function GetCRP: real; override; - procedure CheckState(BCP: real; var dV1: real); - procedure CheckReleaser(dt: real); //odluzniacz - function CVs(bp: real): real; //napelniacz sterujacego - function BVs(BCP: real): real; //napelniacz pomocniczego - procedure PLC(mass: real); //wspolczynnik cisnienia przystawki wazacej - procedure SetLP(TM, LM, TBP: real); //parametry przystawki wazacej - procedure SetLBP(P: real); //cisnienie z hamulca pomocniczego - end; - - - - - //klasa obejmujaca krany - THandle= class - private -// BCP: integer; - public - Time: boolean; - TimeEP: boolean; - Sounds: array[0..4] of real; //wielkosci przeplywow dla dzwiekow - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; virtual; - procedure Init(press: real); virtual; - function GetCP(): real; virtual; - procedure SetReductor(nAdj: real); virtual; - function GetSound(i: byte): real; virtual; - function GetPos(i: byte): real; virtual; - end; - - TFV4a= class(THandle) - private - CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny - public - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; - procedure Init(press: real); override; - end; - - TFV4aM= class(THandle) - private - CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny - XP: real; //komora powietrzna w reduktorze — jest potrzebna do odwzorowania fali - RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem) -// Sounds: array[0..4] of real; //wielkosci przeplywow dla dzwiekow - Fala: boolean; - public - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; - procedure Init(press: real); override; - procedure SetReductor(nAdj: real); override; - function GetSound(i: byte): real; override; - function GetPos(i: byte): real; override; - end; - -{ FBS2= class(THandle) - private - CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny - XP: real; //komora powietrzna w reduktorze — jest potrzebna do odwzorowania fali - RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem) -// Sounds: array[0..4] of real; //wielkosci przeplywow dla dzwiekow - Fala: boolean; - public - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; - procedure Init(press: real); override; - procedure SetReductor(nAdj: real); override; - function GetSound(i: byte): real; override; - function GetPos(i: byte): real; override; - end; } - -{ TD2= class(THandle) - private - CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny - XP: real; //komora powietrzna w reduktorze — jest potrzebna do odwzorowania fali - RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem) -// Sounds: array[0..4] of real; //wielkosci przeplywow dla dzwiekow - Fala: boolean; - public - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; - procedure Init(press: real); override; - procedure SetReductor(nAdj: real); override; - function GetSound(i: byte): real; override; - function GetPos(i: byte): real; override; - end;} - - TM394= class(THandle) - private - CP: real; //zbiornik sterujący, czasowy, redukcyjny - RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem) - public - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; - procedure Init(press: real); override; - procedure SetReductor(nAdj: real); override; - function GetCP: real; override; - function GetPos(i: byte): real; override; - end; - - TH14K1= class(THandle) - private - CP: real; //zbiornik sterujący, czasowy, redukcyjny - RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem) - public - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; - procedure Init(press: real); override; - procedure SetReductor(nAdj: real); override; - function GetCP: real; override; - function GetPos(i: byte): real; override; - end; - - TSt113= class(TH14K1) - private - EPS: real; - public - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; - function GetCP: real; override; - function GetPos(i: byte): real; override; - procedure Init(press: real); override; - end; - - Ttest= class(THandle) - private - CP: real; - public - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; - procedure Init(press: real); override; - end; - - TFD1= class(THandle) - private - MaxBP: real; //najwyzsze cisnienie - BP: real; //aktualne cisnienie - public - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; - procedure Init(press: real); override; - function GetCP(): real; override; -// procedure Init(press: real; MaxBP: real); overload; - end; - - TH1405= class(THandle) - private - MaxBP: real; //najwyzsze cisnienie - BP: real; //aktualne cisnienie - public - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; - procedure Init(press: real); override; - function GetCP(): real; override; -// procedure Init(press: real; MaxBP: real); overload; - end; - - - TFVel6= class(THandle) - private - EPS: real; - public - function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; - function GetCP(): real; override; - function GetPos(i: byte): real; override; - function GetSound(i: byte): real; override; - procedure Init(press: real); override; - end; - -function PF(P1,P2,S:real;DP:real = 0.25):real; -function PF1(P1,P2,S:real):real; - -function PFVa(PH,PL,S,LIM:real;DP:real = 0.1):real; //zawor napelniajacy z PH do PL, PL do LIM -function PFVd(PH,PL,S,LIM:real;DP:real = 0.1):real; //zawor wypuszczajacy z PH do PL, PH do LIM - -implementation - -uses _mover; -//---FUNKCJE OGOLNE--- - -const DPL=0.25; - -function PR(p1,p2:real):real; -var ph,pl: real; -begin - ph:=Max0R(p1,p2)+0.1; - pl:=p1+p2-ph+0.2; - PR:=(p2-p1)/(1.13*ph-pl); -end; - -function PF_old(P1,P2,S:real):real; -var ph,pl: real; -begin - PH:=Max0R(P1,P2)+1; - PL:=P1+P2-PH+2; - if PH-PL<0.0001 then PF_old:=0 else - if (PH-PL)<0.05 then - PF_old:=20*(PH-PL)*(PH+1)*222*S*(P2-P1)/(1.13*ph-pl) - else - PF_old:=(PH+1)*222*S*(P2-P1)/(1.13*ph-pl); -end; - -function PF(P1,P2,S:real;DP:real = 0.25):real; -var ph,pl,sg,fm: real; -begin - PH:=Max0R(P1,P2)+1; //wyzsze cisnienie absolutne - PL:=P1+P2-PH+2; //nizsze cisnienie absolutne - sg:=PL/PH; //bezwymiarowy stosunek cisnien - fm:=PH*197*S*sign(P2-P1); //najwyzszy mozliwy przeplyw, wraz z kierunkiem - if (SG>0.5) then //jesli ponizej stosunku krytycznego - if (PH-PL)0.5) then //jesli ponizej stosunku krytycznego - if (SGPL then - begin - LIM:=LIM+1; - PH:=PH+1; //wyzsze cisnienie absolutne - PL:=PL+1; //nizsze cisnienie absolutne - sg:=PL/PH; //bezwymiarowy stosunek cisnien - fm:=PH*197*S; //najwyzszy mozliwy przeplyw, wraz z kierunkiem - if (LIM-PL)0.5) then //jesli ponizej stosunku krytycznego - if (PH-PL)0.5) then //jesli ponizej stosunku krytycznego - if (PH-PL)0.88 then P:=0.5+(VtoC-0.88)*1.043-0.064*(VtoC-0.88)*(VtoC-0.88) - else P:=0.15+0.35/0.82*(VtoC-0.06); -end; *) - -//(* STARA WERSJA -function TBrakeCyl.P:real; -var VtoC: real; //stosunek cisnienia do objetosci -const - VS = 0.005; - pS = 0.05; - VD = 1.40; - cD = 1; - pD = VD-cD; -begin - VtoC:=Vol/Cap; -// P:=VtoC; - if VtoCVD then P:=VtoC-cD //caly silownik - else P:=pS+(VtoC-VS)/(VD-VS)*(pD-pS); //wysuwanie tloka -end; //*) - - -//---HAMULEC--- -(* -constructor TBrake.Create(i_mbp, i_bcr, i_bcd, i_brc: real; i_bcn, i_BD, i_mat, i_ba, i_nbpa: byte); -begin - inherited Create; - MaxBP:=i_mbp; - BCN:=i_bcn; - BCA:=i_bcn*i_bcr*i_bcr*pi; - BA:=i_ba; - NBpA:=i_nbpa; - BrakeDelays:=i_BD; - -//tworzenie zbiornikow - BrakeCyl.CreateCap(i_bcd*BCA*1000); - BrakeRes.CreateCap(i_brc); - ValveRes.CreateCap(0.2); - -// FM.Free; -//materialy cierne - case i_mat of - bp_P10Bg: FM:=TP10Bg.Create; - bp_P10Bgu: FM:=TP10Bgu.Create; - else //domyslnie - FM:=TP10.Create; - end; - - -end ; *) - -constructor TBrake.Create(i_mbp, i_bcr, i_bcd, i_brc: real; i_bcn, i_BD, i_mat, i_ba, i_nbpa: byte); -begin - inherited Create; - MaxBP:=i_mbp; - BCN:=i_bcn; - BCA:=i_bcn*i_bcr*i_bcr*pi; - BA:=i_ba; - NBpA:=i_nbpa; - BrakeDelays:=i_BD; - //210.88 -// SizeBR:=i_bcn*i_bcr*i_bcr*i_bcd*40.17*MaxBP/(5-MaxBP); //objetosc ZP w stosunku do cylindra 14" i cisnienia 4.2 atm - SizeBR:=i_brc*0.0128; - SizeBC:=i_bcn*i_bcr*i_bcr*i_bcd*210.88*MaxBP/4.2; //objetosc CH w stosunku do cylindra 14" i cisnienia 4.2 atm - -// BrakeCyl:=TReservoir.Create; - BrakeCyl:=TBrakeCyl.Create; - BrakeRes:=TReservoir.Create; - ValveRes:=TReservoir.Create; - -//tworzenie zbiornikow - BrakeCyl.CreateCap(i_bcd*BCA*1000); - BrakeRes.CreateCap(i_brc); - ValveRes.CreateCap(0.25); - -// FM.Free; -//materialy cierne - i_mat:=i_mat and (255-bp_MHS); - case i_mat of - bp_P10Bg: FM:=TP10Bg.Create; - bp_P10Bgu: FM:=TP10Bgu.Create; - bp_FR513: FM:=TFR513.Create; - bp_Cosid: FM:=TCosid.Create; - bp_P10yBg: FM:=TP10yBg.Create; - bp_P10yBgu: FM:=TP10yBgu.Create; - bp_D1: FM:=TDisk1.Create; - bp_D2: FM:=TDisk2.Create; - else //domyslnie - FM:=TP10.Create; - end; -end; - -//inicjalizacja hamulca (stan poczatkowy) -procedure TBrake.Init(PP, HPP, LPP, BP: real; BDF: byte); -begin - -end; - -//pobranie wspolczynnika tarcia materialu -function TBrake.GetFC(Vel, N: real): real; -begin - GetFC:=FM.GetFC(N, Vel); -end; - -//cisnienie cylindra hamulcowego -function TBrake.GetBCP: real; -begin - GetBCP:=BrakeCyl.P; -end; - -//cisnienie zbiornika pomocniczego -function TBrake.GetBRP: real; -begin - GetBRP:=BrakeRes.P; -end; - -//cisnienie komory wstepnej -function TBrake.GetVRP: real; -begin - GetVRP:=ValveRes.P; -end; - -//cisnienie zbiornika sterujacego -function TBrake.GetCRP: real; -begin - GetCRP:=0; -end; - -//przeplyw z przewodu glowneg -function TBrake.GetPF(PP, dt, Vel: real): real; -begin - ValveRes.Act; - BrakeCyl.Act; - BrakeRes.Act; - GetPF:=0; -end; - -//przeplyw z przewodu zasilajacego -function TBrake.GetHPFlow(HP, dt: real): real; -begin - GetHPFlow:=0; -end; - -function TBrake.GetBCF: real; -begin - GetBCF:=BCA*100*BrakeCyl.P; -end; - -function TBrake.SetBDF(nBDF: byte): boolean; -begin - if ((nBDF and BrakeDelays)=nBDF)and(nBDF<>BrakeDelayFlag) then - begin - BrakeDelayFlag:=nBDF; - SetBDF:=true; - end - else - SetBDF:=false; -end; - -procedure TBrake.Releaser(state: byte); -begin - BrakeStatus:=(BrakeStatus and 247) or state*b_rls; -end; - -procedure TBrake.SetEPS(nEPS: real); -begin - -end; - -procedure TBrake.ASB(state: byte); -begin //255-b_asb(32) - BrakeStatus:=(BrakeStatus and 223) or state*b_asb; -end; - -function TBrake.GetStatus(): byte; -begin - GetStatus:=BrakeStatus; -end; - -function TBrake.GetSoundFlag: byte; -begin - GetSoundFlag:=SoundFlag; - SoundFlag:=0; -end; - -procedure TBrake.SetASBP(press: real); -begin - ASBP:=press; -end; - -procedure TBrake.ForceEmptiness(); -begin - ValveRes.CreatePress(0); - BrakeRes.CreatePress(0); - ValveRes.Act(); - BrakeRes.Act(); -end; - - -//---WESTINGHOUSE--- - -procedure TWest.Init(PP, HPP, LPP, BP: real; BDF: byte); -begin - ValveRes.CreatePress(PP); - BrakeCyl.CreatePress(BP); - BrakeRes.CreatePress(PP/2+HPP/2); -// BrakeStatus:=3*Byte(BP>0.1); -end; - -function TWest.GetPF(PP, dt, Vel: real): real; -var dv, dv1:real; - VVP, BVP, CVP, BCP: real; - temp: real; -begin - - BVP:=BrakeRes.P; - VVP:=ValveRes.P; - CVP:=BrakeCyl.P; - BCP:=BrakeCyl.P; - - if (BrakeStatus and 1)=1 then - if(VVP+0.03BVP+0.1) then - BrakeStatus:=(BrakeStatus and 252) - else if(VVP>BVP) then - BrakeStatus:=(BrakeStatus and 253) - else - else - if(VVP+0.25LBP+0.01) and (DCV) then - dV:=PF(0,CVP,0.1*sizeBC)*dt - else dV:=0; - BrakeCyl.Flow(-dV); - -//hamulec EP - temp:=BVP*Byte(EPS>0); - dV:=PF(temp,LBP,0.0015)*dt*EPS*EPS*Byte(LBP*EPS silowniki - if((BrakeStatus and b_on)=b_on)and((TareBP<0.1)or(BCPLBP)then - begin - DCV:=false; - dV:=PF(BVP,CVP,0.017*sizeBC)*dt; - end - else dV:=0 - else dV:=0; - BrakeRes.Flow(dV); - BrakeCyl.Flow(-dV); - if(DCV)then - dVP:=PF(LBP,BCP,0.01*sizeBC)*dt - else dVP:=0; - BrakeCyl.Flow(-dVP); - if(dVP>0)then dVP:=0; -//przeplyw ZP <-> rozdzielacz - if((BrakeStatus and b_hld)=b_off)then - dV:=PF(BVP,VVP,0.0011*sizeBR)*dt - else dV:=0; - BrakeRes.Flow(dV); - dV1:=dV*0.95; - ValveRes.Flow(-0.05*dV); -//przeplyw PG <-> rozdzielacz - dV:=PF(PP,VVP,0.01*sizeBR)*dt; - ValveRes.Flow(-dV); - - ValveRes.Act; - BrakeCyl.Act; - BrakeRes.Act; - GetPF:=dV-dV1; -end; - -function TWest.GetHPFlow(HP, dt: real): real; -begin - GetHPFlow:=dVP; -end; - -procedure TWest.SetLBP(P: real); -begin - LBP:=P; - if P>BrakeCyl.P then -// begin - DCV:=true; -// end -// else -// LBP:=P; -end; - -procedure TWest.SetEPS(nEPS: real); -var - BCP: real; -begin - BCP:=BrakeCyl.P; - if nEPS>0 then - DCV:=true - else if nEPS=0 then - begin - if(EPS<>0)then - begin - if(LBP>0.4)then - LBP:=BrakeCyl.P; - if(LBP<0.15)then - LBP:=0; - end; - end; - EPS:=nEPS; -end; - -procedure TWest.PLC(mass: real); -begin - LoadC:=1+Byte(Mass0.25)then - if(VVP+0.003+BCP/BVMCVP) then - BrakeStatus:=(BrakeStatus and 252) //luzowanie - else if(VVP+BCP/BVM>CVP) then - BrakeStatus:=(BrakeStatus and 253) //zatrzymanie napelaniania - else - else - if(VVP+0.100.25)and(BCP>0.25)then //zatrzymanie luzowanie - BrakeStatus:=(BrakeStatus or 1); - - if (BrakeStatus and 1)=0 then - SoundFlag:=SoundFlag or sf_CylU; -end; - -function TESt.CVs(bp: real): real; -var VVP, BVP, CVP: real; -begin - BVP:=BrakeRes.P; - CVP:=CntrlRes.P; - VVP:=ValveRes.P; - -//przeplyw ZS <-> PG - if(VVP0.4)then - CVs:=0 - else - if(VVP>CVP+0.4)then - if(BVP>CVP+0.2)then - CVs:=0.23 - else - CVs:=0.05 - else - if(BVP>CVP-0.1)then - CVs:=1 - else - CVs:=0.3; -end; - -function TESt.BVs(BCP: real): real; -var VVP, BVP, CVP: real; -begin - BVP:=BrakeRes.P; - CVP:=CntrlRes.P; - VVP:=ValveRes.P; - -//przeplyw ZP <-> rozdzielacz - if(BVPCVP+0.4)then - BVs:=0.1 - else - BVs:=0.3 - else - BVs:=0; -end; - - - - - -function TESt.GetPF(PP, dt, Vel: real): real; -var dv, dv1, temp:real; - VVP, BVP, BCP, CVP: real; -begin - BVP:=BrakeRes.P; - VVP:=ValveRes.P; - BCP:=BrakeCyl.P; - CVP:=CntrlRes.P-0.0; - - dV:=0; dV1:=0; - -//sprawdzanie stanu - CheckState(BCP, dV1); - CheckReleaser(dt); - - CVP:=CntrlRes.P; - VVP:=ValveRes.P; -//przeplyw ZS <-> PG - temp:=CVs(BCP); - dV:=PF(CVP,VVP,0.0015*temp)*dt; - CntrlRes.Flow(+dV); - ValveRes.Flow(-0.04*dV); - dV1:=dV1-0.96*dV; - - -//luzowanie - if(BrakeStatus and b_hld)=b_off then - dV:=PF(0,BCP,0.0058*sizeBC)*dt - else dV:=0; - BrakeCyl.Flow(-dV); - -//przeplyw ZP <-> silowniki - if(BrakeStatus and b_on)=b_on then - dV:=PF(BVP,BCP,0.016*sizeBC)*dt - else dV:=0; - BrakeRes.Flow(dV); - BrakeCyl.Flow(-dV); - -//przeplyw ZP <-> rozdzielacz - temp:=BVs(BCP); -// if(BrakeStatus and b_hld)=b_off then - if(VVP-0.05>BVP)then - dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt - else dV:=0; - BrakeRes.Flow(dV); - dV1:=dV1+dV*0.96; - ValveRes.Flow(-0.04*dV); -//przeplyw PG <-> rozdzielacz - dV:=PF(PP,VVP,0.01)*dt; - ValveRes.Flow(-dV); - - ValveRes.Act; - BrakeCyl.Act; - BrakeRes.Act; - CntrlRes.Act; - GetPF:=dV-dV1; -end; - -procedure TESt.Init(PP, HPP, LPP, BP: real; BDF: byte); -begin - ValveRes.CreatePress(PP); - BrakeCyl.CreatePress(BP); - BrakeRes.CreatePress(PP); - CntrlRes:=TReservoir.Create; - CntrlRes.CreateCap(15); - CntrlRes.CreatePress(HPP); - BrakeStatus:=0; - - BVM:=1/(HPP-LPP)*MaxBP; - - BrakeDelayFlag:=BDF; -end; - - -procedure TESt.EStParams(i_crc: real); -begin - -end; - - -function TESt.GetCRP: real; -begin - GetCRP:=CntrlRes.P; -end; - -//---EP2--- - -procedure TEStEP2.Init(PP, HPP, LPP, BP: real; BDF: byte); -begin - inherited; - ImplsRes.CreateCap(1); - ImplsRes.CreatePress(BP); - - BrakeRes.CreatePress(PP); - - BrakeDelayFlag:=bdelay_P; - BrakeDelays:=bdelay_P; -end; - - -function TEStEP2.GetPF(PP, dt, Vel: real): real; -var dv, dv1, temp:real; - VVP, BVP, BCP, CVP: real; -begin - BVP:=BrakeRes.P; - VVP:=ValveRes.P; - BCP:=ImplsRes.P; - CVP:=CntrlRes.P; //110115 - konsultacje warszawa1 - - dV:=0; dV1:=0; - -//odluzniacz - CheckReleaser(dt); - -//sprawdzanie stanu - if ((BrakeStatus and 1)=1)and(BCP>0.25) then - if(VVP+0.003+BCP/BVMCVP-0.12) then - BrakeStatus:=(BrakeStatus and 252) //luzowanie - else if(VVP+BCP/BVM>CVP-0.12) then - BrakeStatus:=(BrakeStatus and 253) //zatrzymanie napelaniania - else - else - if(VVP+0.100.25) then //zatrzymanie luzowanie - BrakeStatus:=(BrakeStatus or 1); - -//przeplyw ZS <-> PG - if(BVP0)or(BCP>0.25)then - temp:=0 - else - if(VVP>CVP+0.4)then - temp:=0.1 - else - temp:=0.5; - - dV:=PF(CVP,VVP,0.0015*temp/1.8)*dt; - CntrlRes.Flow(+dV); - ValveRes.Flow(-0.04*dV); - dV1:=dV1-0.96*dV; - -//hamulec EP - temp:=BVP*Byte(EPS>0); - dV:=PF(temp,LBP,0.00053+0.00060*Byte(EPS<0))*dt*EPS*EPS*Byte(LBP*EPS KI - if ((BrakeStatus and b_on)=b_on) and (BCP rozdzielacz - dV:=PF(PP,VVP,0.01*sizeBR)*dt; - ValveRes.Flow(-dV); - - GetPF:=dV-dV1; - - temp:=Max0R(BCP,LBP); - - if(ImplsRes.P>LBP+0.01)then - LBP:=0; - -//luzowanie CH - if(BrakeCyl.P>temp+0.005)or(Max0R(ImplsRes.P,8*LBP)<0.05) then - dV:=PF(0,BrakeCyl.P,0.25*sizeBC*(0.01+(BrakeCyl.P-temp)))*dt - else dV:=0; - BrakeCyl.Flow(-dV); -//przeplyw ZP <-> CH - if(BrakeCyl.P0.10)and(Max0R(BCP,LBP)0) and (LBP+0.01 PG - temp:=CVs(BCP); - dV:=PF(CVP,VVP,0.0015*temp)*dt; - CntrlRes.Flow(+dV); - ValveRes.Flow(-0.04*dV); - dV1:=dV1-0.96*dV; - - -//luzowanie - if(BrakeStatus and b_hld)=b_off then - dV:=PF(0,BCP,0.0042*(1.37-Byte(BrakeDelayFlag=bdelay_G))*sizeBC)*dt - else dV:=0; - BrakeCyl.Flow(-dV); -//przeplyw ZP <-> silowniki - if(BrakeStatus and b_on)=b_on then - dV:=PF(BVP,BCP,0.017*(1+Byte((BCP<0.58)and(BrakeDelayFlag=bdelay_G)))*(1.13-Byte((BCP>0.6)and(BrakeDelayFlag=bdelay_G)))*sizeBC)*dt - else dV:=0; - BrakeRes.Flow(dV); - BrakeCyl.Flow(-dV); -//przeplyw ZP <-> rozdzielacz - temp:=BVs(BCP); - if(VVP-0.05>BVP)then - dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt - else dV:=0; - BrakeRes.Flow(dV); - dV1:=dV1+dV*0.96; - ValveRes.Flow(-0.04*dV); -//przeplyw PG <-> rozdzielacz - dV:=PF(PP,VVP,0.01)*dt; - ValveRes.Flow(-dV); - - ValveRes.Act; - BrakeCyl.Act; - BrakeRes.Act; - CntrlRes.Act; - GetPF:=dV-dV1; -end; - -//---EST4-RAPID--- - -function TESt4R.GetPF(PP, dt, Vel: real): real; -var dv, dv1, temp:real; - VVP, BVP, BCP, CVP: real; -begin - BVP:=BrakeRes.P; - VVP:=ValveRes.P; - BCP:=ImplsRes.P; - CVP:=CntrlRes.P-0.0; - - dV:=0; dV1:=0; - -//sprawdzanie stanu - CheckState(BCP, dV1); - CheckReleaser(dt); - - CVP:=CntrlRes.P; - VVP:=ValveRes.P; -//przeplyw ZS <-> PG - temp:=CVs(BCP); - dV:=PF(CVP,VVP,0.0015*temp/1.8)*dt; - CntrlRes.Flow(+dV); - ValveRes.Flow(-0.04*dV); - dV1:=dV1-0.96*dV; - - -//luzowanie KI - if(BrakeStatus and b_hld)=b_off then - dV:=PF(0,BCP,0.00037*1.14*15/19)*dt - else dV:=0; - ImplsRes.Flow(-dV); -//przeplyw ZP <-> KI - if(BrakeStatus and b_on)=b_on then - dV:=PF(BVP,BCP,0.0014)*dt - else dV:=0; -// BrakeRes.Flow(dV); - ImplsRes.Flow(-dV); -//przeplyw ZP <-> rozdzielacz - temp:=BVs(BCP); - if(BVP rozdzielacz - dV:=PF(PP,VVP,0.01*sizeBR)*dt; - ValveRes.Flow(-dV); - - GetPF:=dV-dV1; - - - - RapidStatus:=(BrakeDelayFlag=bdelay_R)and(((Vel>55)and(RapidStatus))or(Vel>70)); - - RapidTemp:=RapidTemp+(0.9*Byte(RapidStatus)-RapidTemp)*dt/2; - temp:=1.9-RapidTemp; - if((BrakeStatus and b_asb)=b_asb)then - temp:=1000; -//luzowanie CH - if(BrakeCyl.P*temp>ImplsRes.P+0.005)or(ImplsRes.P<0.25) then - if((BrakeStatus and b_asb)=b_asb)then - dV:=PFVd(BrakeCyl.P,0,0.115*sizeBC*4,ImplsRes.P/temp)*dt - else - dV:=PFVd(BrakeCyl.P,0,0.115*sizeBC,ImplsRes.P/temp)*dt -// dV:=PF(0,BrakeCyl.P,0.115*sizeBC/2)*dt -// dV:=PFVd(BrakeCyl.P,0,0.015*sizeBC/2,ImplsRes.P/temp)*dt - else dV:=0; - BrakeCyl.Flow(-dV); -//przeplyw ZP <-> CH - if(BrakeCyl.P*temp0.3) then -// dV:=PFVa(BVP,BrakeCyl.P,0.020*sizeBC,ImplsRes.P/temp)*dt - dV:=PFVa(BVP,BrakeCyl.P,0.60*sizeBC,ImplsRes.P/temp)*dt - else dV:=0; - BrakeRes.Flow(-dV); - BrakeCyl.Flow(+dV); - - ImplsRes.Act; - ValveRes.Act; - BrakeCyl.Act; - BrakeRes.Act; - CntrlRes.Act; -end; - -procedure TESt4R.Init(PP, HPP, LPP, BP: real; BDF: byte); -begin - inherited; - ImplsRes:=TReservoir.Create; - ImplsRes.CreateCap(1); - ImplsRes.CreatePress(BP); - - BrakeDelayFlag:=bdelay_R; -end; - - -//---EST3/AL2--- - -function TESt3AL2.GetPF(PP, dt, Vel: real): real; -var dv, dv1, temp:real; - VVP, BVP, BCP, CVP: real; -begin - BVP:=BrakeRes.P; - VVP:=ValveRes.P; - BCP:=ImplsRes.P; - CVP:=CntrlRes.P-0.0; - - dV:=0; dV1:=0; - -//sprawdzanie stanu - CheckState(BCP, dV1); - CheckReleaser(dt); - - VVP:=ValveRes.P; -//przeplyw ZS <-> PG - temp:=CVs(BCP); - dV:=PF(CVP,VVP,0.0015*temp)*dt; - CntrlRes.Flow(+dV); - ValveRes.Flow(-0.04*dV); - dV1:=dV1-0.96*dV; - -//luzowanie KI - if(BrakeStatus and b_hld)=b_off then - dV:=PF(0,BCP,0.00017*(1.37-Byte(BrakeDelayFlag=bdelay_G)))*dt - else dV:=0; - ImplsRes.Flow(-dV); -//przeplyw ZP <-> KI - if ((BrakeStatus and b_on)=b_on) and (BCP0.6)and(BrakeDelayFlag=bdelay_G))))*dt - else dV:=0; - BrakeRes.Flow(dV); - ImplsRes.Flow(-dV); -//przeplyw ZP <-> rozdzielacz - temp:=BVs(BCP); - if(VVP-0.05>BVP)then - dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt - else dV:=0; - BrakeRes.Flow(dV); - dV1:=dV1+dV*0.96; - ValveRes.Flow(-0.04*dV); -//przeplyw PG <-> rozdzielacz - dV:=PF(PP,VVP,0.01)*dt; - ValveRes.Flow(-dV); - GetPF:=dV-dV1; - -//luzowanie CH - if(BrakeCyl.P>ImplsRes.P*LoadC+0.005)or(ImplsRes.P<0.15) then - dV:=PF(0,BrakeCyl.P,0.015*sizeBC)*dt - else dV:=0; - BrakeCyl.Flow(-dV); - -//przeplyw ZP <-> CH - if(BrakeCyl.P0.15) then - dV:=PF(BVP,BrakeCyl.P,0.020*sizeBC)*dt - else dV:=0; - BrakeRes.Flow(dV); - BrakeCyl.Flow(-dV); - - ImplsRes.Act; - ValveRes.Act; - BrakeCyl.Act; - BrakeRes.Act; - CntrlRes.Act; -end; - -procedure TESt3AL2.PLC(mass: real); -begin - LoadC:=1+Byte(Mass PG - if((CVP-BCP)*BVM>0.5)then - temp:=0 - else - if(VVP>CVP+0.4)then - temp:=0.5 - else - temp:=0.5; - - dV:=PF1(CVP,VVP,0.0015*temp/1.8/2)*dt; - CntrlRes.Flow(+dV); - ValveRes.Flow(-0.04*dV); - dV1:=dV1-0.96*dV; - - -//luzowanie KI {G} -// if VVP>BCP then -// dV:=PF(VVP,BCP,0.00004)*dt -// else if (CVP-BCP)<1.5 then -// dV:=PF(VVP,BCP,0.00020*(1.33-Byte((CVP-BCP)*BVM>0.65)))*dt -// else dV:=0; 0.00025 P - {P} - if VVP>BCP then - dV:=PF(VVP,BCP,0.00043*(1.5-Byte(((CVP-BCP)*BVM>1)and(BrakeDelayFlag=bdelay_G))),0.1)*dt - else if (CVP-BCP)<1.5 then - dV:=PF(VVP,BCP,0.001472*(1.36-Byte(((CVP-BCP)*BVM>1)and(BrakeDelayFlag=bdelay_G))),0.1)*dt - else dV:=0; - - ImplsRes.Flow(-dV); - ValveRes.Flow(+dV); -//przeplyw PG <-> rozdzielacz - dV:=PF(PP,VVP,0.01,0.1)*dt; - ValveRes.Flow(-dV); - - GetPF:=dV-dV1; - -// if Vel>55 then temp:=0.72 else -// temp:=1;{R} -//cisnienie PP - RapidTemp:=RapidTemp+(RM*Byte((Vel>55)and(BrakeDelayFlag=bdelay_R))-RapidTemp)*dt/2; - temp:=1-RapidTemp; - if EDFlag>0.2 then temp:=10000; - -//powtarzacz — podwojny zawor zwrotny - temp:=Max0R(((CVP-BCP)*BVM+ASBP*Byte((BrakeStatus and b_asb)=b_asb))/temp,LBP); -//luzowanie CH - if(BrakeCyl.P>temp+0.005)or(temp<0.28) then -// dV:=PF(0,BrakeCyl.P,0.0015*3*sizeBC)*dt -// dV:=PF(0,BrakeCyl.P,0.005*3*sizeBC)*dt - dV:=PFVd(BrakeCyl.P,0,0.005*7*sizeBC,temp)*dt - else dV:=0; - BrakeCyl.Flow(-dV); -//przeplyw ZP <-> CH - if(BrakeCyl.P0.29) then -// dV:=PF(BVP,BrakeCyl.P,0.002*3*sizeBC*2)*dt - dV:=-PFVa(BVP,BrakeCyl.P,0.002*7*sizeBC*2,temp)*dt - else dV:=0; - BrakeRes.Flow(dV); - BrakeCyl.Flow(-dV); - - ImplsRes.Act; - ValveRes.Act; - BrakeCyl.Act; - BrakeRes.Act; - CntrlRes.Act; -// LBP:=ValveRes.P; -// ValveRes.CreatePress(ImplsRes.P); -end; - -procedure TLSt.Init(PP, HPP, LPP, BP: real; BDF: byte); -begin - inherited; - ValveRes.CreateCap(1); - ImplsRes.CreateCap(8); - ImplsRes.CreatePress(PP); - BrakeRes.CreatePress(8); - ValveRes.CreatePress(PP); - - EDFlag:=0; - - BrakeDelayFlag:=BDF; -end; - -procedure TLSt.SetLBP(P: real); -begin - LBP:=P; -end; - -function TLSt.GetEDBCP: real; -var CVP, BCP: real; -begin - CVP:=CntrlRes.P; - BCP:=ImplsRes.P; - GetEDBCP:=(CVP-BCP)*BVM; -end; - -procedure TLSt.SetED(EDstate: real); -begin - EDFlag:=EDstate; -end; - -procedure TLSt.SetRM(RMR: real); -begin - RM:=1-RMR; -end; - -function TLSt.GetHPFlow(HP, dt: real): real; -var dV: real; -begin - dV:=Min0R(PF(HP,BrakeRes.P,0.01*dt),0); - BrakeRes.Flow(-dV); - GetHPFlow:=dV; -end; - -//---EStED--- - -function TEStED.GetPF(PP, dt, Vel: real): real; -var dv, dv1, temp:real; - VVP, BVP, BCP, CVP, MPP, nastG: real; - i: byte; -begin - BVP:=BrakeRes.P; - VVP:=ValveRes.P; - BCP:=ImplsRes.P; - CVP:=CntrlRes.P-0.0; - MPP:=Miedzypoj.P; - dV1:=0; - - nastG:=(BrakeDelayFlag and bdelay_G); - -//sprawdzanie stanu - if(BCP<0.25)and(VVP+0.08>CVP)then Przys_blok:=false; - -//sprawdzanie stanu - if(VVP+0.002+BCP/BVMCVP-0.05) then - BrakeStatus:=(BrakeStatus and 252) //luzowanie - else if(VVP+BCP/BVM>CVP-0.05) then - BrakeStatus:=(BrakeStatus and 253) //zatrzymanie napelaniania - else if(VVP+(BCP-0.1)/BVM0.25)then //zatrzymanie luzowania - BrakeStatus:=(BrakeStatus or 1); - - if(VVP+0.100.5)then - Zamykajacy:=true - else if(VVP-0.6CVP-0.08)then - temp:=Nozzles[5] - else - temp:=Nozzles[6]; - dV:=dV+PF(MPP,CVP,temp); - - if(MPP-0.05>BVP)then - dV:=dV+PF(MPP-0.05,BVP,Nozzles[10]*nastG+(1-nastG)*Nozzles[9]); - if MPP>VVP then dV:=dV+PF(MPP,VVP,0.02); - Miedzypoj.Flow(dV*dt*0.15); - - - RapidTemp:=RapidTemp+(RM*Byte((Vel>55)and(BrakeDelayFlag=bdelay_R))-RapidTemp)*dt/2; - temp:=1-RapidTemp; -// if EDFlag then temp:=1000; -// temp:=temp/(1-); - -//powtarzacz — podwojny zawor zwrotny - temp:=Max0R(BCP/temp*Min0R(Max0R(1-EDFlag,0),1),LBP); - - if(BrakeCyl.P>temp)then - dV:=-PFVd(BrakeCyl.P,0,0.02,temp)*dt - else - if(BrakeCyl.P0 then - BrakeRes.Flow(-dV); - - -//przeplyw ZS <-> PG - if(MPPCVP-0.08)then - temp:=Nozzles[5] - else - temp:=Nozzles[6]; - dV:=PF(CVP,MPP,temp)*dt; - CntrlRes.Flow(+dV); - ValveRes.Flow(-0.02*dV); - dV1:=dV1+0.98*dV; - -//przeplyw ZP <-> MPJ - if(MPP-0.05>BVP)then - dV:=PF(BVP,MPP-0.05,Nozzles[10]*nastG+(1-nastG)*Nozzles[9])*dt - else dV:=0; - BrakeRes.Flow(dV); - dV1:=dV1+dV*0.98; - ValveRes.Flow(-0.02*dV); -//przeplyw PG <-> rozdzielacz - dV:=PF(PP,VVP,0.005)*dt; //0.01 - ValveRes.Flow(-dV); - - - ValveRes.Act; - BrakeCyl.Act; - BrakeRes.Act; - CntrlRes.Act; - Miedzypoj.Act; - ImplsRes.Act; - GetPF:=dV-dV1; -end; - -procedure TEStED.Init(PP, HPP, LPP, BP: real; BDF: byte); -var i:integer; -begin - inherited; - - ValveRes.CreatePress(1*PP); - BrakeCyl.CreatePress(1*BP); - -// CntrlRes:=TReservoir.Create; -// CntrlRes.CreateCap(15); -// CntrlRes.CreatePress(1*HPP); - - BrakeStatus:=Byte(BP>1)*1; - Miedzypoj:=TReservoir.Create; - Miedzypoj.CreateCap(5); - Miedzypoj.CreatePress(PP); - - ImplsRes.CreateCap(1); - ImplsRes.CreatePress(BP); - - BVM:=1/(HPP-0.05-LPP)*MaxBP; - - BrakeDelayFlag:=BDF; - Zamykajacy:=false; - EDFlag:=0; - - Nozzles[0]:=1.250/1.7; - Nozzles[1]:=0.907; - Nozzles[2]:=0.510/1.7; - Nozzles[3]:=0.524/1.17; - Nozzles[4]:=7.4; - Nozzles[7]:=5.3; - Nozzles[8]:=2.5; - Nozzles[9]:=7.28; - Nozzles[10]:=2.96; - Nozzles[5]:=1.1; - Nozzles[6]:=0.9; - - for i:=0 to 10 do - begin - Nozzles[i]:=Nozzles[i]*Nozzles[i]*3.14159/4000; - end; - -end; - -function TEStED.GetEDBCP: real; -begin - GetEDBCP:=ImplsRes.P; -end; - - - -//---DAKO CV1--- - -procedure TCV1.CheckState(BCP: real; var dV1: real); -var VVP, BVP, CVP: real; -begin - BVP:=BrakeRes.P; - VVP:=Min0R(ValveRes.P,BVP+0.05); - CVP:=CntrlRes.P-0.0; - -//odluzniacz - if(BrakeStatus and b_rls=b_rls)and(CVP-VVP<0)then - BrakeStatus:=BrakeStatus and 247; - -//sprawdzanie stanu - if (BrakeStatus and 1)=1 then - if(VVP+0.003+BCP/BVMCVP) then - BrakeStatus:=(BrakeStatus and 252) //luzowanie - else if(VVP+BCP/BVM>CVP) then - BrakeStatus:=(BrakeStatus and 253) //zatrzymanie napelaniania - else - else - if(VVP+0.100.25) then //zatrzymanie luzowanie - BrakeStatus:=(BrakeStatus or 1); -end; - -function TCV1.CVs(bp: real): real; -begin -//przeplyw ZS <-> PG - if(bp>0.05)then - CVs:=0 - else - CVs:=0.23 -end; - -function TCV1.BVs(BCP: real): real; -var VVP, BVP, CVP: real; -begin - BVP:=BrakeRes.P; - CVP:=CntrlRes.P; - VVP:=ValveRes.P; - -//przeplyw ZP <-> rozdzielacz - if(BVP0.05)then - BVs:=0 - else - BVs:=0.2*(1.5-Byte(BVP>VVP)); -end; - -function TCV1.GetPF(PP, dt, Vel: real): real; -var dv, dv1, temp:real; - VVP, BVP, BCP, CVP: real; -begin - BVP:=BrakeRes.P; - VVP:=Min0R(ValveRes.P,BVP+0.05); - BCP:=BrakeCyl.P; - CVP:=CntrlRes.P-0.0; - - dV:=0; dV1:=0; - -//sprawdzanie stanu - CheckState(BCP, dV1); - - VVP:=ValveRes.P; -//przeplyw ZS <-> PG - temp:=CVs(BCP); - dV:=PF(CVP,VVP,0.0015*temp)*dt; - CntrlRes.Flow(+dV); - ValveRes.Flow(-0.04*dV); - dV1:=dV1-0.96*dV; - - -//luzowanie - if(BrakeStatus and b_hld)=b_off then - dV:=PF(0,BCP,0.0042*(1.37-Byte(BrakeDelayFlag=bdelay_G))*sizeBC)*dt - else dV:=0; - BrakeCyl.Flow(-dV); - -//przeplyw ZP <-> silowniki - if(BrakeStatus and b_on)=b_on then - dV:=PF(BVP,BCP,0.017*(1+Byte((BCP<0.58)and(BrakeDelayFlag=bdelay_G)))*(1.13-Byte((BCP>0.6)and(BrakeDelayFlag=bdelay_G)))*sizeBC)*dt - else dV:=0; - BrakeRes.Flow(dV); - BrakeCyl.Flow(-dV); - -//przeplyw ZP <-> rozdzielacz - temp:=BVs(BCP); - if(VVP+0.05>BVP)then - dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt - else dV:=0; - BrakeRes.Flow(dV); - dV1:=dV1+dV*0.96; - ValveRes.Flow(-0.04*dV); -//przeplyw PG <-> rozdzielacz - dV:=PF(PP,VVP,0.01)*dt; - ValveRes.Flow(-dV); - - ValveRes.Act; - BrakeCyl.Act; - BrakeRes.Act; - CntrlRes.Act; - GetPF:=dV-dV1; -end; - -procedure TCV1.Init(PP, HPP, LPP, BP: real; BDF: byte); -begin - ValveRes.CreatePress(PP); - BrakeCyl.CreatePress(BP); - BrakeRes.CreatePress(PP); - CntrlRes:=TReservoir.Create; - CntrlRes.CreateCap(15); - CntrlRes.CreatePress(HPP); - BrakeStatus:=0; - - BVM:=1/(HPP-LPP)*MaxBP; - - BrakeDelayFlag:=BDF; -end; - -function TCV1.GetCRP: real; -begin - GetCRP:=CntrlRes.P; -end; - - -//---CV1-L-TR--- - -procedure TCV1L_TR.SetLBP(P: real); -begin - LBP:=P; -end; - -function TCV1L_TR.GetHPFlow(HP, dt: real): real; -var dV: real; -begin - dV:=PF(HP,BrakeRes.P,0.01)*dt; - dV:=Min0R(0,dV); - BrakeRes.Flow(-dV); - GetHPFlow:=dV; -end; - -procedure TCV1L_TR.Init(PP, HPP, LPP, BP: real; BDF: byte); -begin - inherited; - ImplsRes:=TReservoir.Create; - ImplsRes.CreateCap(2.5); - ImplsRes.CreatePress(BP); -end; - -function TCV1L_TR.GetPF(PP, dt, Vel: real): real; -var dv, dv1, temp:real; - VVP, BVP, BCP, CVP: real; -begin - BVP:=BrakeRes.P; - VVP:=Min0R(ValveRes.P,BVP+0.05); - BCP:=ImplsRes.P; - CVP:=CntrlRes.P-0.0; - - dV:=0; dV1:=0; - -//sprawdzanie stanu - CheckState(BCP, dV1); - - VVP:=ValveRes.P; -//przeplyw ZS <-> PG - temp:=CVs(BCP); - dV:=PF(CVP,VVP,0.0015*temp)*dt; - CntrlRes.Flow(+dV); - ValveRes.Flow(-0.04*dV); - dV1:=dV1-0.96*dV; - - -//luzowanie KI - if(BrakeStatus and b_hld)=b_off then - dV:=PF(0,BCP,0.000425*(1.37-Byte(BrakeDelayFlag=bdelay_G)))*dt - else dV:=0; - ImplsRes.Flow(-dV); -//przeplyw ZP <-> KI - if ((BrakeStatus and b_on)=b_on) and (BCP0.6)and(BrakeDelayFlag=bdelay_G))))*dt - else dV:=0; - BrakeRes.Flow(dV); - ImplsRes.Flow(-dV); - -//przeplyw ZP <-> rozdzielacz - temp:=BVs(BCP); - if(VVP+0.05>BVP)then - dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt - else dV:=0; - BrakeRes.Flow(dV); - dV1:=dV1+dV*0.96; - ValveRes.Flow(-0.04*dV); -//przeplyw PG <-> rozdzielacz - dV:=PF(PP,VVP,0.01)*dt; - GetPF:=dV-dV1; - - temp:=Max0R(BCP,LBP); - -//luzowanie CH - if(BrakeCyl.P>temp+0.005)or(Max0R(ImplsRes.P,8*LBP)<0.25) then - dV:=PF(0,BrakeCyl.P,0.015*sizeBC)*dt - else dV:=0; - BrakeCyl.Flow(-dV); - -//przeplyw ZP <-> CH - if(BrakeCyl.P0.3)and(Max0R(BCP,LBP)CVP) then - BrakeStatus:=(BrakeStatus and 252) //luzowanie - else if(VVP+BCP/BVM>CVP) then - BrakeStatus:=(BrakeStatus and 253) //zatrzymanie napelaniania - else - else - if(VVP+0.100.25) then //zatrzymanie luzowanie - BrakeStatus:=(BrakeStatus or 1); -end; - -function TKE.CVs(bp: real): real; -var VVP, BVP, CVP: real; -begin - BVP:=BrakeRes.P; - CVP:=CntrlRes.P; - VVP:=ValveRes.P; - -//przeplyw ZS <-> PG - if(bp>0.2)then - CVs:=0 - else - if(VVP>CVP+0.4)then - CVs:=0.05 - else - CVs:=0.23 -end; - -function TKE.BVs(BCP: real): real; -var VVP, BVP, CVP: real; -begin - BVP:=BrakeRes.P; - CVP:=CntrlRes.P; - VVP:=ValveRes.P; - -//przeplyw ZP <-> rozdzielacz - if (BVP>VVP) then - BVs:=0 - else - if(BVP PG - temp:=CVs(IMP); - dV:=PF(CVP,VVP,0.0015*temp)*dt; - CntrlRes.Flow(+dV); - ValveRes.Flow(-0.04*dV); - dV1:=dV1-0.96*dV; - -//luzowanie - if(BrakeStatus and b_hld)=b_off then - begin - if ((BrakeDelayFlag and bdelay_G)=0) then - temp:=0.283+0.139 - else - temp:=0.139; - dV:=PF(0,IMP,0.001*temp)*dt - end - else dV:=0; - ImplsRes.Flow(-dV); - -//przeplyw ZP <-> silowniki - if((BrakeStatus and b_on)=b_on)and(IMP50)and(RapidStatus))or(Vel>70)) - else //jesli tarczowki, to zostan - RapidStatus:=((BrakeDelayFlag and bdelay_R)=bdelay_R); - -// temp:=1.9-0.9*Byte(RapidStatus); - - if(RM*RM>0.1)then //jesli jest rapid - if(RM>0)then //jesli dodatni (naddatek); - temp:=1-RM*Byte(RapidStatus) - else - temp:=1-RM*(1-Byte(RapidStatus)) - else - temp:=1; - temp:=temp/LoadC; -//luzowanie CH -// temp:=Max0R(BCP,LBP); - IMP:=Max0R(IMP/temp,Max0R(LBP,ASBP*Byte((BrakeStatus and b_asb)=b_asb))); - -//luzowanie CH - if(BCP>IMP+0.005)or(Max0R(ImplsRes.P,8*LBP)<0.25) then - dV:=PFVd(BCP,0,0.05,IMP)*dt - else dV:=0; - BrakeCyl.Flow(-dV); - if(BCP0.3) then - dV:=PFVa(BVP,BCP,0.05,IMP)*dt - else dV:=0; - BrakeRes.Flow(-dV); - BrakeCyl.Flow(+dV); - -//przeplyw ZP <-> rozdzielacz - temp:=BVs(IMP); -// if(BrakeStatus and b_hld)=b_off then - if(IMP<0.25)or(VVP+0.05>BVP)then - dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt - else dV:=0; - BrakeRes.Flow(dV); - dV1:=dV1+dV*0.96; - ValveRes.Flow(-0.04*dV); -//przeplyw PG <-> rozdzielacz - dV:=PF(PP,VVP,0.01)*dt; - ValveRes.Flow(-dV); - - ValveRes.Act; - BrakeCyl.Act; - BrakeRes.Act; - CntrlRes.Act; - ImplsRes.Act; - GetPF:=dV-dV1; -end; - -procedure TKE.Init(PP, HPP, LPP, BP: real; BDF: byte); -begin - ValveRes.CreatePress(PP); - BrakeCyl.CreatePress(BP); - BrakeRes.CreatePress(PP); - - CntrlRes:=TReservoir.Create; //komora sterujaca - CntrlRes.CreateCap(5); - CntrlRes.CreatePress(HPP); - - ImplsRes:=TReservoir.Create; //komora zastepcza silownika - ImplsRes.CreateCap(1); - ImplsRes.CreatePress(BP); - - BrakeStatus:=0; - - BVM:=1/(HPP-LPP)*MaxBP; - - BrakeDelayFlag:=BDF; -end; - -function TKE.GetCRP: real; -begin - GetCRP:=CntrlRes.P; -end; - -function TKE.GetHPFlow(HP, dt: real): real; -var dV: real; -begin - dV:=PF(HP,BrakeRes.P,0.01)*dt; - dV:=Min0R(0,dV); - BrakeRes.Flow(-dV); - GetHPFlow:=dV; -end; - -procedure TKE.PLC(mass: real); -begin - LoadC:=1+Byte(Massrp+0.05)then - dpMainValve:=PF(Min0R(cp+0.1,HP),pp,1.1*(ActFlowSpeed)/(LBDelay))*dt; - if(cp0.1)then - begin - cp:=5+(tp-0.1)*0.08; - tp:=tp-dt/12/2; - end; - if(cp>rp+0.1)and(cp<=5)then - dpMainValve:=PF(Min0R(cp+0.25,HP),pp,2*(ActFlowSpeed)/(LBDelay))*dt - else - if cp>5 then - dpMainValve:=PF(Min0R(cp,HP),pp,2*(ActFlowSpeed)/(LBDelay))*dt - else - dpMainValve:=PF(dpPipe,pp,(ActFlowSpeed)/(LBDelay))*dt - end; - - if(Round(i_bcp)=i_bcpNo)then - begin - dpMainValve:=PF(0,pp,(ActFlowSpeed)/(LBDelay))*dt; - end; - - GetPF:=dpMainValve; -end; - -procedure TFV4a.Init(press: real); -begin - CP:= press; - TP:= 0; - RP:= press; - Time:= false; - TimeEP:=false; -end; - - -//---FV4a/M--- nowonapisany kran bez poprawki IC - -function TFV4aM.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; -function LPP_RP(pos: real): real; //cisnienie z zaokraglonej pozycji; -var i_pos: integer; -begin - i_pos:=Round(pos-0.5); //zaokraglone w dol - LPP_RP:=BPT[i_pos][1]+(BPT[i_pos+1][1]-BPT[i_pos][1])*(pos-i_pos); //interpolacja liniowa -end; -function EQ(pos: real; i_pos: real): boolean; -begin - EQ:=(pos<=i_pos+0.5)and(pos>i_pos-0.5); -end; -const - LBDelay = 100; - xpM = 0.3; //mnoznik membrany komory pod -var - LimPP, dpPipe, dpMainValve, ActFlowSpeed, dp: real; - pom: real; - i: byte; -begin - ep:=pp/2*1.5+ep/2*0.5; //SPKS!! -// ep:=pp; -// ep:=cp/3+pp/3+ep/3; -// ep:=cp; - - for i:=0 to 4 do - Sounds[i]:=0; - dp:=0; - - i_bcp:=Max0R(Min0R(i_bcp,5.999),-1.999); //na wszelki wypadek, zeby nie wyszlo poza zakres - - if(tp>0)then - begin //jesli czasowy jest niepusty -// dp:=0.07; //od cisnienia 5 do 0 w 60 sekund ((5-0)*dt/75) - dp:=0.045; //2.5 w 55 sekund (5,35->5,15 w PG) - tp:=tp-dp*dt; - Sounds[s_fv4a_t]:=dp; - end - else //.08 - begin - tp:=0; - end; - - if(xp>0)then //jesli komora pod niepusta jest niepusty - begin - dp:=2.5; - Sounds[s_fv4a_x]:=dp*xp; - xp:=xp-dt*dp*2; //od cisnienia 5 do 0 w 10 sekund ((5-0)*dt/10) - end - else //.75 - xp:=0; //jak pusty, to pusty - - Limpp:=Min0R(LPP_RP(i_bcp)+tp*0.08+RedAdj,HP); //pozycja + czasowy lub zasilanie - ActFlowSpeed:=BPT[Round(i_bcp)][0]; - - if(EQ(i_bcp,-1))then pom:=Min0R(HP,5.4+RedAdj) else pom:=Min0R(cp,HP); - - if(pom>rp+0.25)then Fala:=true; - if(Fala)then - if(pom>rp+0.3)then -// if(ep>rp+0.11)then - xp:=xp-20*PR(pom,xp)*dt -// else -// xp:=xp-16*(ep-(ep+0.01))/(0.1)*PR(ep,xp)*dt - else Fala:=false; - - if(Limpp>cp)then //podwyzszanie szybkie - cp:=cp+5*60*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt //zbiornik sterujacy - else - cp:=cp+13*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt; //zbiornik sterujacy - - Limpp:=pom; //cp - dpPipe:=Min0R(HP,Limpp+xp*xpM); - - if dpPipe>pp then - dpMainValve:=-PFVa(HP,pp,ActFlowSpeed/(LBDelay),dpPipe,0.4) - else - dpMainValve:=PFVd(pp,0,ActFlowSpeed/(LBDelay),dpPipe,0.4); - - if EQ(i_bcp,-1) then - begin - if(tp<5)then tp:=tp+dt; //5/10 - if(tp<1)then tp:=tp-0.5*dt; //5/10 -// dpMainValve:=dpMainValve*2;//+1*PF(dpPipe,pp,(ActFlowSpeed)/(LBDelay))//coby nie przeszkadzal przy ladowaniu z zaworu obok - end; - - if EQ(i_bcp,0) then - begin - if(tp>2)then - dpMainValve:=dpMainValve*1.5;//+0.5*PF(dpPipe,pp,(ActFlowSpeed)/(LBDelay))//coby nie przeszkadzal przy ladowaniu z zaworu obok - end; - - - - - - ep:=dpPipe; - if(EQ(i_bcp,0)or(rp>ep))then - rp:=rp+PF(rp,ep,0.0007)*dt //powolne wzrastanie, ale szybsze na jezdzie - else - rp:=rp+PF(rp,ep,0.000093/2*2)*dt; //powolne wzrastanie i to bardzo //jednak trzeba wydluzyc, bo obecnie zle dziala - if (rp0 then - Sounds[s_fv4a_b]:=dpMainValve - else - Sounds[s_fv4a_u]:=-dpMainValve; - end; - - GetPF:=dpMainValve*dt; -end; - -procedure TFV4aM.Init(press: real); -begin - CP:= press; - TP:= 0; - RP:= press; - XP:= 0; - Time:=false; - TimeEP:=false; -end; - -procedure TFV4aM.SetReductor(nAdj: real); -begin - RedAdj:= nAdj; -end; - -function TFV4aM.GetSound(i: byte): real; -begin - if i>4 then - GetSound:=0 - else - GetSound:=Sounds[i]; -end; - -function TFV4aM.GetPos(i: byte): real; -const - table: array[0..10] of real = (-2,6,-1,0,-2,1,4,6,0,0,0); -begin - GetPos:=table[i]; -end; - -//---M394--- Matrosow - -function TM394.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; -const - LBDelay = 65; -var - LimPP, dpPipe, dpMainValve, ActFlowSpeed: real; - bcp: integer; -begin - bcp:=Round(i_bcp); - if bcp<-1 then bcp:=1; - - Limpp:=Min0R(BPT_394[bcp][1],HP); - ActFlowSpeed:=BPT_394[bcp][0]; - if (bcp=1)or(bcp=i_bcpNo) then - Limpp:=pp; - if (bcp=0) then - Limpp:=Limpp+RedAdj; - if (bcp<>2) then - if cp3)+Byte(bcp>4))*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt; //zbiornik sterujacy - - Limpp:=cp; - dpPipe:=Min0R(HP,Limpp); - -// if(dpPipe>pp)then //napelnianie -// dpMainValve:=PF(dpPipe,pp,ActFlowSpeed/(LBDelay))*dt -// else //spuszczanie - dpMainValve:=PF(dpPipe,pp,ActFlowSpeed/(LBDelay))*dt; - - if bcp=-1 then -// begin - dpMainValve:=PF(HP,pp,(ActFlowSpeed)/(LBDelay))*dt; -// end; - - if bcp=i_bcpNo then -// begin - dpMainValve:=PF(0,pp,(ActFlowSpeed)/(LBDelay))*dt; -// end; - - GetPF:=dpMainValve; -end; - -procedure TM394.Init(press: real); -begin - CP:= press; - RedAdj:= 0; - Time:=true; - TimeEP:=false; -end; - -procedure TM394.SetReductor(nAdj: real); -begin - RedAdj:= nAdj; -end; - -function TM394.GetCP: real; -begin - GetCP:= CP; -end; - -function TM394.GetPos(i: byte): real; -const - table: array[0..10] of real = (-1,5,-1,0,1,2,4,5,0,0,0); -begin - GetPos:=table[i]; -end; - -//---H14K1-- Knorr - -function TH14K1.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; -const - LBDelay = 100; //szybkosc + zasilanie sterujacego - BPT_K: array[-1..4] of array [0..1] of real= ((10, 0), (4, 1), (0, 1), (4, 0), (4, -1), (15, -1)); - NomPress = 5.0; -var - LimPP, dpPipe, dpMainValve, ActFlowSpeed: real; - bcp: integer; -begin - bcp:=Round(i_bcp); - if i_bcp<-1 then bcp:=1; - Limpp:=BPT_K[bcp][1]; - if Limpp<0 then - Limpp:=0.5*pp - else if Limpp>0 then - Limpp:=pp - else - Limpp:=cp; - ActFlowSpeed:=BPT_K[bcp][0]; - - cp:=cp+6*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt; //zbiornik sterujacy - - dpMainValve:=0; - - if bcp=-1 then - dpMainValve:=PF(HP,pp,(ActFlowSpeed)/(LBDelay))*dt; - if(bcp=0)then - dpMainValve:=-PFVa(HP,pp,(ActFlowSpeed)/(LBDelay),NomPress+RedAdj)*dt; - if (bcp>1)and(pp>cp) then - dpMainValve:=PFVd(pp,0,(ActFlowSpeed)/(LBDelay),cp)*dt; - if bcp=i_bcpNo then - dpMainValve:=PF(0,pp,(ActFlowSpeed)/(LBDelay))*dt; - - GetPF:=dpMainValve; -end; - -procedure TH14K1.Init(press: real); -begin - CP:= press; - RedAdj:= 0; - Time:=true; - TimeEP:=true; -end; - -procedure TH14K1.SetReductor(nAdj: real); -begin - RedAdj:= nAdj; -end; - -function TH14K1.GetCP: real; -begin - GetCP:= CP; -end; - -function TH14K1.GetPos(i: byte): real; -const - table: array[0..10] of real = (-1,4,-1,0,1,2,3,4,0,0,0); -begin - GetPos:=table[i]; -end; - -//---St113-- Knorr EP - -function TSt113.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; -const - LBDelay = 100; //szybkosc + zasilanie sterujacego - BPT_K: array[-1..4] of array [0..1] of real= ((10, 0), (4, 1), (0, 1), (4, 0), (4, -1), (15, -1)); - BEP_K: array[-1..5] of real= (0, -1, 1, 0, 0, 0, 0); - NomPress = 5.0; -var - LimPP, dpPipe, dpMainValve, ActFlowSpeed: real; - bcp: integer; -begin - bcp:=Round(i_bcp); - - EPS:=BEP_K[bcp]; - - if bcp>0 then bcp:=bcp-1; - - if bcp<-1 then bcp:=1; - Limpp:=BPT_K[bcp][1]; - if Limpp<0 then - Limpp:=0.5*pp - else if Limpp>0 then - Limpp:=pp - else - Limpp:=cp; - ActFlowSpeed:=BPT_K[bcp][0]; - - cp:=cp+6*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt; //zbiornik sterujacy - - dpMainValve:=0; - - if bcp=-1 then - dpMainValve:=PF(HP,pp,(ActFlowSpeed)/(LBDelay))*dt; - if(bcp=0)then - dpMainValve:=-PFVa(HP,pp,(ActFlowSpeed)/(LBDelay),NomPress+RedAdj)*dt; - if (bcp>1)and(pp>cp) then - dpMainValve:=PFVd(pp,0,(ActFlowSpeed)/(LBDelay),cp)*dt; - if bcp=i_bcpNo then - dpMainValve:=PF(0,pp,(ActFlowSpeed)/(LBDelay))*dt; - - GetPF:=dpMainValve; -end; - -function TSt113.GetCP: real; -begin - GetCP:=EPS; -end; - -function TSt113.GetPos(i: byte): real; -const - table: array[0..10] of real = (-1,5,-1,0,2,3,4,5,0,0,1); -begin - GetPos:=table[i]; -end; - -procedure TSt113.Init(press: real); -begin - Time:=true; - TimeEP:=true; -end; - -//--- test --- - -function Ttest.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; -const - LBDelay = 100; -var - LimPP, dpPipe, dpMainValve, ActFlowSpeed: real; -begin - - Limpp:=BPT[Round(i_bcp)][1]; - ActFlowSpeed:=BPT[Round(i_bcp)][0]; - - if(i_bcp=i_bcpNo)then limpp:=0.0; - - if(i_bcp=-1)then limpp:=7; - - cp:=cp+20*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt/1; - - Limpp:=cp; - dpPipe:=Min0R(HP,Limpp); - - dpMainValve:=PF(dpPipe,pp,ActFlowSpeed/(LBDelay))*dt; - - if(Round(i_bcp)=i_bcpNo)then - begin - dpMainValve:=PF(0,pp,(ActFlowSpeed)/(LBDelay))*dt; - end; - - GetPF:=dpMainValve; -end; - -procedure Ttest.Init(press: real); -begin - CP:= press; -end; - - -//---FD1--- - -function TFD1.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; -var dp, temp: real; -begin -// MaxBP:=4; -// temp:=Min0R(i_bcp*MaxBP,Min0R(5.0,HP)); - temp:=Min0R(i_bcp*MaxBP,HP); //0011 - dp:=10*Min0R(abs(temp-BP),0.1)*PF(temp,BP,0.0006*(2+Byte(temp>BP)))*dt; - BP:=BP-dp; - GetPF:=-dp; -end; - -procedure TFD1.Init(press: real); -begin - BP:=0; - MaxBP:=press; - Time:=false; - TimeEP:=false; -end; - -function TFD1.GetCP: real; -begin - GetCP:=BP; -end; - - -//---KNORR--- - -function TH1405.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; -var dp, temp, A: real; -begin - pp:=Min0R(pp,MaxBP); - if i_bcp>0.5 then - begin - temp:=Min0R(MaxBP,HP); - A:=2*(i_bcp-0.5)*0.0011; - BP:=Max0R(BP,pp); - end - else - begin - temp:=0; - A:=0.2*(0.5-i_bcp)*0.0033; - BP:=Min0R(BP,pp); - end; - dp:=PF(temp,BP,A)*dt; - BP:=BP-dp; - GetPF:=-dp; -end; - -procedure TH1405.Init(press: real); -begin - BP:=0; - MaxBP:=press; - Time:=true; - TimeEP:=false; -end; - -function TH1405.GetCP: real; -begin - GetCP:=BP; -end; - - -//---FVel6--- - -function TFVel6.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; -const - LBDelay = 100; -var - LimPP, dpPipe, dpMainValve, ActFlowSpeed: real; -begin - Limpp:=Min0R(5*Byte(i_bcp<3.5),hp); - if (i_bcp>=3.5) and ((i_bcp<4.3)or(i_bcp>5.5)) then - ActFlowSpeed:=0 - else if (i_bcp>4.3) and (i_bcp<4.8) then - ActFlowSpeed:=4*(i_bcp-4.3) //konsultacje wawa1 - bylo 8 - else if (i_bcp<4) then - ActFlowSpeed:=2 - else - ActFlowSpeed:=4; - dpMainValve:=PF(Limpp,pp,ActFlowSpeed/(LBDelay))*dt; - - - Sounds[s_fv4a_e]:=0; - Sounds[s_fv4a_u]:=0; - Sounds[s_fv4a_b]:=0; - if(i_bcp<3.5)then Sounds[s_fv4a_u]:=-dpMainValve else - if(i_bcp<4.8)then Sounds[s_fv4a_b]:=dpMainValve else - if(i_bcp<5.5)then Sounds[s_fv4a_e]:=dpMainValve; - - GetPF:=dpMainValve; - if(i_bcp<-0.5)then - EPS:=-1 - else if(i_bcp>0.5)and(i_bcp<4.7)then - EPS:=1 - else - EPS:=0; -// EPS:=i_bcp*Byte(i_bcp<2) -end; - -function TFVel6.GetCP: real; -begin - GetCP:=EPS; -end; - -function TFVel6.GetPos(i: byte): real; -const - table: array[0..10] of real = (-1,6,-1,0,6,4,4.7,5,-1,0,1); -begin - GetPos:=table[i]; -end; - -function TFVel6.GetSound(i: byte): real; -begin - if i>2 then - GetSound:=0 - else - GetSound:=Sounds[i]; -end; - -procedure TFVel6.Init(press: real); -begin - Time:=true; - TimeEP:=true; -end; - -end. - - +unit hamulce; {fizyka hamulcow dla symulatora} + +(* +This Source Code Form is subject to the +terms of the Mozilla Public License, v. +2.0. If a copy of the MPL was not +distributed with this file, You can +obtain one at +http://mozilla.org/MPL/2.0/. +*) +(* + MaSzyna EU07 - SPKS + Brakes. + Copyright (C) 2007-2014 Maciej Cierniak +*) + + +(* +(C) youBy +Co brakuje: +moze jeszcze jakis SW +*) +(* +Zrobione: +ESt3, ESt3AL2, ESt4R, LSt, FV4a, FD1, EP2, prosty westinghouse +duzo wersji żeliwa +KE +Tarcze od 152A +Magnetyki (implementacja w mover.pas) +Matrosow 394 +H14K1 (zasadniczy), H1405 (pomocniczy), St113 (ep) +Knorr/West EP - żeby był +*) + +interface + +uses mctools,sysutils,friction; + +CONST + + LocalBrakePosNo=10; {ilosc nastaw hamulca recznego lub pomocniczego} + MainBrakeMaxPos=10; {max. ilosc nastaw hamulca zasadniczego} + + {nastawy hamulca} + bdelay_G=1; //G + bdelay_P=2; //P + bdelay_R=4; //R + bdelay_M=8; //Mg + bdelay_GR=128; //G-R + + + {stan hamulca} + b_off = 0; //luzowanie + b_hld = 1; //trzymanie + b_on = 2; //napelnianie + b_rfl = 4; //uzupelnianie + b_rls = 8; //odluzniacz + b_ep = 16; //elektropneumatyczny + b_asb = 32; //elektropneumatyczny + b_dmg =128; //wylaczony z dzialania + + {uszkodzenia hamulca} + df_on = 1; //napelnianie + df_off = 2; //luzowanie + df_br = 4; //wyplyw z ZP + df_vv = 8; //wyplyw z komory wstepnej + df_bc = 16; //wyplyw z silownika + df_cv = 32; //wyplyw z ZS + df_PP = 64; //zawsze niski stopien + df_RR =128; //zawsze wysoki stopien + + {indeksy dzwiekow FV4a} + s_fv4a_b = 0; //hamowanie + s_fv4a_u = 1; //luzowanie + s_fv4a_e = 2; //hamowanie nagle + s_fv4a_x = 3; //wyplyw sterujacego fala + s_fv4a_t = 4; //wyplyw z czasowego + + {pary cierne} + bp_P10 = 0; + bp_P10Bg = 2; //żeliwo fosforowe P10 + bp_P10Bgu = 1; + bp_LLBg = 4; //komp. b.n.t. + bp_LLBgu = 3; + bp_LBg = 6; //komp. n.t. + bp_LBgu = 5; + bp_KBg = 8; //komp. w.t. + bp_KBgu = 7; + bp_D1 = 9; //tarcze + bp_D2 = 10; + bp_FR513 = 11; //Frenoplast FR513 + bp_Cosid = 12; //jakistam kompozyt :D + bp_PKPBg = 13; //żeliwo PKP + bp_PKPBgu = 14; + bp_MHS = 128; //magnetyczny hamulec szynowy + bp_P10yBg = 15; //żeliwo fosforowe P10 + bp_P10yBgu= 16; + bp_FR510 = 17; //Frenoplast FR510 + + sf_Acc = 1; //przyspieszacz + sf_BR = 2; //przekladnia + sf_CylB = 4; //cylinder - napelnianie + sf_CylU = 8; //cylinder - oproznianie + sf_rel = 16; //odluzniacz + sf_ep = 32; //zawory ep + + bh_MIN= 0; //minimalna pozycja + bh_MAX= 1; //maksymalna pozycja + bh_FS = 2; //napelnianie uderzeniowe //jesli nie ma, to jazda + bh_RP = 3; //jazda + bh_NP = 4; //odciecie - podwojna trakcja + bh_MB = 5; //odciecie - utrzymanie stopnia hamowania/pierwszy 1 stopien hamowania + bh_FB = 6; //pelne + bh_EB = 7; //nagle + bh_EPR= 8; //ep - luzowanie //pelny luz dla ep kątowego + bh_EPN= 9; //ep - utrzymanie //jesli rowne luzowaniu, wtedy sterowanie przyciskiem + bh_EPB=10; //ep - hamowanie //pelne hamowanie dla ep kątowego + + + SpgD=0.7917; + SpO=0.5067; //przekroj przewodu 1" w l/m + //wyj: jednostka dosyc dziwna, ale wszystkie obliczenia + //i pojemnosci sa podane w litrach (rozsadne wielkosci) + //zas dlugosc pojazdow jest podana w metrach + //a predkosc przeplywu w m/s //3.5 + //7//1.5 +// BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (14, 5.4), (9, 5.0), (6, 4.6), (9, 4.5), (9, 4.0), (9, 3.5), (9, 2.8), (34, 2.8)); +// BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (7, 5.0), (2.0, 5.0), (4.5, 4.6), (4.5, 4.2), (4.5, 3.8), (4.5, 3.4), (4.5, 2.8), (8, 2.8)); + BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (7, 5.0), (2.0, 5.0), (4.5, 4.6), (4.5, 4.2), (4.5, 3.8), (4.5, 3.4), (4.5, 2.8), (8, 2.8)); + BPT_394: array[-1..5] of array [0..1] of real= ((13, 10.0), (5, 5.0), (0, -1), (5, -1), (5, 0.0), (5, 0.0), (18, 0.0)); +// BPT: array[-2..6] of array [0..1] of real= ((0, 5.0), (12, 5.4), (9, 5.0), (9, 4.6), (9, 4.2), (9, 3.8), (9, 3.4), (9, 2.8), (34, 2.8)); +// BPT: array[-2..6] of array [0..1] of real= ((0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0),(0, 0)); + i_bcpno= 6; + +TYPE + //klasa obejmujaca pojedyncze zbiorniki + TReservoir= class + protected + Cap: real; + Vol: real; + dVol: real; + public + constructor Create; + procedure CreateCap(Capacity: real); + procedure CreatePress(Press: real); + function pa: real; virtual; + function P: real; virtual; + procedure Flow(dv: real); + procedure Act; + end; + + PReservoir=^TReservoir; + + TBrakeCyl= class(TReservoir) + public + function pa: real; override; + function P: real; override; + end; + + //klasa obejmujaca uklad hamulca zespolonego pojazdu + TBrake= class + protected + BrakeCyl: TReservoir; //silownik + BrakeRes: TReservoir; //ZP + ValveRes: TReservoir; //komora wstepna + BCN: byte; //ilosc silownikow + BCM: real; //przekladnia hamulcowa + BCA: real; //laczny przekroj silownikow + BrakeDelays: byte; //dostepne opoznienia + BrakeDelayFlag: byte; //aktualna nastawa + FM: TFricMat; //material cierny + MaxBP: real; //najwyzsze cisnienie + BA: byte; //osie hamowane + NBpA: byte; //klocki na os + SizeBR: real; //rozmiar^2 ZP (w stosunku do 14") + SizeBC: real; //rozmiar^2 CH (w stosunku do 14") + DCV: boolean; //podwojny zawor zwrotny + ASBP: real; //cisnienie hamulca pp + + BrakeStatus: byte; //flaga stanu + SoundFlag: byte; + public + constructor Create(i_mbp, i_bcr, i_bcd, i_brc: real; + i_bcn, i_BD, i_mat, i_ba, i_nbpa: byte); + //maksymalne cisnienie, promien, skok roboczy, pojemnosc ZP; + //ilosc cylindrow, opoznienia hamulca, material klockow, osie hamowane, klocki na os; + + function GetFC(Vel, N: real): real; virtual; //wspolczynnik tarcia - hamulec wie lepiej + function GetPF(PP, dt, Vel: real): real; virtual; //przeplyw miedzy komora wstepna i PG + function GetBCF: real; //sila tlokowa z tloka + function GetHPFlow(HP, dt: real): real; virtual; //przeplyw - 8 bar + function GetBCP: real; virtual; //cisnienie cylindrow hamulcowych + function GetBRP: real; //cisnienie zbiornika pomocniczego + function GetVRP: real; //cisnienie komory wstepnej rozdzielacza + function GetCRP: real; virtual; //cisnienie zbiornika sterujacego + procedure Init(PP, HPP, LPP, BP: real; BDF: byte); virtual; //inicjalizacja hamulca + function SetBDF(nBDF: byte): boolean; //nastawiacz GPRM + procedure Releaser(state: byte); //odluzniacz + procedure SetEPS(nEPS:real); virtual;//hamulec EP + procedure ASB(state: byte); //hamulec przeciwposlizgowy + function GetStatus(): byte; //flaga statusu, moze sie przydac do odglosow + procedure SetASBP(press: real); //ustalenie cisnienia pp + procedure ForceEmptiness(); virtual; + function GetSoundFlag: byte; +// procedure + end; + + TWest= class(TBrake) + private + LBP: real; //cisnienie hamulca pomocniczego + dVP: real; //pobor powietrza wysokiego cisnienia + EPS: real; //stan elektropneumatyka + TareM, LoadM: real; //masa proznego i pelnego + TareBP: real; //cisnienie dla proznego + LoadC: real; //wspolczynnik przystawki wazacej + public + procedure SetLBP(P: real); //cisnienie z hamulca pomocniczego + function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG + procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; + function GetHPFlow(HP, dt: real): real; override; + procedure PLC(mass: real); //wspolczynnik cisnienia przystawki wazacej + procedure SetEPS(nEPS: real); override; //stan hamulca EP + procedure SetLP(TM, LM, TBP: real); //parametry przystawki wazacej + end; + + TESt= class(TBrake) + private + CntrlRes: TReservoir; //zbiornik sterujący + BVM: real; //przelozenie PG-CH + public + function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG + procedure EStParams(i_crc: real); //parametry charakterystyczne dla ESt + procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; + function GetCRP: real; override; + procedure CheckState(BCP: real; var dV1: real); //glowny przyrzad rozrzadczy + procedure CheckReleaser(dt: real); //odluzniacz + function CVs(bp: real): real; //napelniacz sterujacego + function BVs(BCP: real): real; //napelniacz pomocniczego + end; + + TESt3= class(TESt) + private + CylFlowSpeed: array[0..1] of array [0..1] of real; + public + function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG + end; + + TESt3AL2= class(TESt3) + private + TareM, LoadM: real; //masa proznego i pelnego + TareBP: real; //cisnienie dla proznego + LoadC: real; + public + ImplsRes: TReservoir; //komora impulsowa + function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG + procedure PLC(mass: real); //wspolczynnik cisnienia przystawki wazacej + procedure SetLP(TM, LM, TBP: real); //parametry przystawki wazacej + procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; + end; + + TESt4R= class(TESt) + private + RapidStatus: boolean; + RapidTemp: real; //akrualne, zmienne przelozenie + public + ImplsRes: TReservoir; //komora impulsowa + function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG + procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; + end; + + TLSt= class(TESt4R) + private + CylFlowSpeed: array[0..1] of array [0..1] of real; + LBP: real; //cisnienie hamulca pomocniczego + RM: real; //przelozenie rapida + EDFlag: real; //luzowanie hamulca z powodu zalaczonego ED + public + procedure SetLBP(P: real); //cisnienie z hamulca pomocniczego + procedure SetRM(RMR: real); //ustalenie przelozenia rapida + function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG + function GetHPFlow(HP, dt: real): real; override; //przeplyw - 8 bar + procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; + function GetEDBCP: real; virtual; //cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED w EP09 + procedure SetED(EDstate: real); //stan hamulca ED do luzowania + end; + + TEStED= class(TLSt) //zawor z EP09 - Est4 z oddzielnym przekladnikiem, kontrola rapidu i takie tam + private + Nozzles: array[0..10] of real; //dysze + Zamykajacy: boolean; //pamiec zaworka zamykajacego + Przys_blok: boolean; //blokada przyspieszacza + Miedzypoj: TReservoir; //pojemnosc posrednia (urojona) do napelniania ZP i ZS + TareM, LoadM: real; //masa proznego i pelnego + TareBP: real; //cisnienie dla proznego + LoadC: real; + public + procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; + function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG + function GetEDBCP: real; override; //cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED + procedure PLC(mass: real); //wspolczynnik cisnienia przystawki wazacej + procedure SetLP(TM, LM, TBP: real); //parametry przystawki wazacej + end; + + TEStEP2= class(TLSt) + private + TareM, LoadM: real; //masa proznego i pelnego + TareBP: real; //cisnienie dla proznego + LoadC: real; + EPS: real; + public + function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG + procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; //inicjalizacja + procedure PLC(mass: real); //wspolczynnik cisnienia przystawki wazacej + procedure SetEPS(nEPS: real); override; //stan hamulca EP + procedure SetLP(TM, LM, TBP: real); //parametry przystawki wazacej + end; + + TCV1= class(TBrake) + private + CntrlRes: TReservoir; //zbiornik sterujący + BVM: real; //przelozenie PG-CH + public + function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG + procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; + function GetCRP: real; override; + procedure CheckState(BCP: real; var dV1: real); + function CVs(bp: real): real; + function BVs(BCP: real): real; + public + end; + + TCV1R= class(TCV1) + private + ImplsRes: TReservoir; //komora impulsowa + RapidStatus: boolean; + public +// function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG +// procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; + end; + + TCV1L_TR= class(TCV1) + private + ImplsRes: TReservoir; //komora impulsowa + LBP: real; //cisnienie hamulca pomocniczego + public + function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG + procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; + procedure SetLBP(P: real); //cisnienie z hamulca pomocniczego + function GetHPFlow(HP, dt: real): real; override; //przeplyw - 8 bar + end; + + TKE= class(TBrake) //Knorr Einheitsbauart — jeden do wszystkiego + private + RapidStatus: boolean; + ImplsRes: TReservoir; //komora impulsowa + CntrlRes: TReservoir; //zbiornik sterujący + Brak2Res: TReservoir; //zbiornik pomocniczy 2 + BVM: real; //przelozenie PG-CH + TareM, LoadM: real; //masa proznego i pelnego + TareBP: real; //cisnienie dla proznego + LoadC: real; //wspolczynnik zaladowania + RM: real; //przelozenie rapida + LBP: real; //cisnienie hamulca pomocniczego + public + procedure SetRM(RMR: real); //ustalenie przelozenia rapida + function GetPF(PP, dt, Vel: real): real; override; //przeplyw miedzy komora wstepna i PG + procedure Init(PP, HPP, LPP, BP: real; BDF: byte); override; + function GetHPFlow(HP, dt: real): real; override; //przeplyw - 8 bar + function GetCRP: real; override; + procedure CheckState(BCP: real; var dV1: real); + procedure CheckReleaser(dt: real); //odluzniacz + function CVs(bp: real): real; //napelniacz sterujacego + function BVs(BCP: real): real; //napelniacz pomocniczego + procedure PLC(mass: real); //wspolczynnik cisnienia przystawki wazacej + procedure SetLP(TM, LM, TBP: real); //parametry przystawki wazacej + procedure SetLBP(P: real); //cisnienie z hamulca pomocniczego + end; + + + + + //klasa obejmujaca krany + THandle= class + private +// BCP: integer; + public + Time: boolean; + TimeEP: boolean; + Sounds: array[0..4] of real; //wielkosci przeplywow dla dzwiekow + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; virtual; + procedure Init(press: real); virtual; + function GetCP(): real; virtual; + procedure SetReductor(nAdj: real); virtual; + function GetSound(i: byte): real; virtual; + function GetPos(i: byte): real; virtual; + end; + + TFV4a= class(THandle) + private + CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny + public + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + procedure Init(press: real); override; + end; + + TFV4aM= class(THandle) + private + CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny + XP: real; //komora powietrzna w reduktorze — jest potrzebna do odwzorowania fali + RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem) +// Sounds: array[0..4] of real; //wielkosci przeplywow dla dzwiekow + Fala: boolean; + public + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + procedure Init(press: real); override; + procedure SetReductor(nAdj: real); override; + function GetSound(i: byte): real; override; + function GetPos(i: byte): real; override; + end; + + TMHZ_EN57= class(THandle) + private + CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny + RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem) + Fala: boolean; + public + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + procedure Init(press: real); override; + procedure SetReductor(nAdj: real); override; + function GetSound(i: byte): real; override; + function GetPos(i: byte): real; override; + function GetCP: real; override; + function GetEP(pos: real): real; + end; + + +{ FBS2= class(THandle) + private + CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny + XP: real; //komora powietrzna w reduktorze — jest potrzebna do odwzorowania fali + RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem) +// Sounds: array[0..4] of real; //wielkosci przeplywow dla dzwiekow + Fala: boolean; + public + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + procedure Init(press: real); override; + procedure SetReductor(nAdj: real); override; + function GetSound(i: byte): real; override; + function GetPos(i: byte): real; override; + end; } + +{ TD2= class(THandle) + private + CP, TP, RP: real; //zbiornik sterujący, czasowy, redukcyjny + XP: real; //komora powietrzna w reduktorze — jest potrzebna do odwzorowania fali + RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem) +// Sounds: array[0..4] of real; //wielkosci przeplywow dla dzwiekow + Fala: boolean; + public + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + procedure Init(press: real); override; + procedure SetReductor(nAdj: real); override; + function GetSound(i: byte): real; override; + function GetPos(i: byte): real; override; + end;} + + TM394= class(THandle) + private + CP: real; //zbiornik sterujący, czasowy, redukcyjny + RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem) + public + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + procedure Init(press: real); override; + procedure SetReductor(nAdj: real); override; + function GetCP: real; override; + function GetPos(i: byte): real; override; + end; + + TH14K1= class(THandle) + private + CP: real; //zbiornik sterujący, czasowy, redukcyjny + RedAdj: real; //dostosowanie reduktora cisnienia (krecenie kapturkiem) + public + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + procedure Init(press: real); override; + procedure SetReductor(nAdj: real); override; + function GetCP: real; override; + function GetPos(i: byte): real; override; + end; + + TSt113= class(TH14K1) + private + EPS: real; + public + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + function GetCP: real; override; + function GetPos(i: byte): real; override; + procedure Init(press: real); override; + end; + + Ttest= class(THandle) + private + CP: real; + public + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + procedure Init(press: real); override; + end; + + TFD1= class(THandle) + private + MaxBP: real; //najwyzsze cisnienie + BP: real; //aktualne cisnienie + public + Speed: real; //szybkosc dzialania + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + procedure Init(press: real); override; + function GetCP(): real; override; + procedure SetSpeed(nSpeed: real); +// procedure Init(press: real; MaxBP: real); overload; + end; + + TH1405= class(THandle) + private + MaxBP: real; //najwyzsze cisnienie + BP: real; //aktualne cisnienie + public + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + procedure Init(press: real); override; + function GetCP(): real; override; +// procedure Init(press: real; MaxBP: real); overload; + end; + + + TFVel6= class(THandle) + private + EPS: real; + public + function GetPF(i_bcp:real; pp, hp, dt, ep: real): real; override; + function GetCP(): real; override; + function GetPos(i: byte): real; override; + function GetSound(i: byte): real; override; + procedure Init(press: real); override; + end; + +function PF(P1,P2,S:real;DP:real = 0.25):real; +function PF1(P1,P2,S:real):real; + +function PFVa(PH,PL,S,LIM:real;DP:real = 0.1):real; //zawor napelniajacy z PH do PL, PL do LIM +function PFVd(PH,PL,S,LIM:real;DP:real = 0.1):real; //zawor wypuszczajacy z PH do PL, PH do LIM + +implementation + +uses _mover; +//---FUNKCJE OGOLNE--- + +const DPL=0.25; + +function PR(p1,p2:real):real; +var ph,pl: real; +begin + ph:=Max0R(p1,p2)+0.1; + pl:=p1+p2-ph+0.2; + PR:=(p2-p1)/(1.13*ph-pl); +end; + +function PF_old(P1,P2,S:real):real; +var ph,pl: real; +begin + PH:=Max0R(P1,P2)+1; + PL:=P1+P2-PH+2; + if PH-PL<0.0001 then PF_old:=0 else + if (PH-PL)<0.05 then + PF_old:=20*(PH-PL)*(PH+1)*222*S*(P2-P1)/(1.13*ph-pl) + else + PF_old:=(PH+1)*222*S*(P2-P1)/(1.13*ph-pl); +end; + +function PF(P1,P2,S:real;DP:real = 0.25):real; +var ph,pl,sg,fm: real; +begin + PH:=Max0R(P1,P2)+1; //wyzsze cisnienie absolutne + PL:=P1+P2-PH+2; //nizsze cisnienie absolutne + sg:=PL/PH; //bezwymiarowy stosunek cisnien + fm:=PH*197*S*sign(P2-P1); //najwyzszy mozliwy przeplyw, wraz z kierunkiem + if (SG>0.5) then //jesli ponizej stosunku krytycznego + if (PH-PL)0.5) then //jesli ponizej stosunku krytycznego + if (SGPL then + begin + LIM:=LIM+1; + PH:=PH+1; //wyzsze cisnienie absolutne + PL:=PL+1; //nizsze cisnienie absolutne + sg:=PL/PH; //bezwymiarowy stosunek cisnien + fm:=PH*197*S; //najwyzszy mozliwy przeplyw, wraz z kierunkiem + if (LIM-PL)0.5) then //jesli ponizej stosunku krytycznego + if (PH-PL)0.5) then //jesli ponizej stosunku krytycznego + if (PH-PL)0.88 then P:=0.5+(VtoC-0.88)*1.043-0.064*(VtoC-0.88)*(VtoC-0.88) + else P:=0.15+0.35/0.82*(VtoC-0.06); +end; *) + +//(* STARA WERSJA +function TBrakeCyl.P:real; +var VtoC: real; //stosunek cisnienia do objetosci +const + VS = 0.005; + pS = 0.05; + VD = 1.10; + cD = 1; + pD = VD-cD; +begin + VtoC:=Vol/Cap; +// P:=VtoC; + if VtoCVD then P:=VtoC-cD //caly silownik + else P:=pS+(VtoC-VS)/(VD-VS)*(pD-pS); //wysuwanie tloka +end; //*) + + +//---HAMULEC--- +(* +constructor TBrake.Create(i_mbp, i_bcr, i_bcd, i_brc: real; i_bcn, i_BD, i_mat, i_ba, i_nbpa: byte); +begin + inherited Create; + MaxBP:=i_mbp; + BCN:=i_bcn; + BCA:=i_bcn*i_bcr*i_bcr*pi; + BA:=i_ba; + NBpA:=i_nbpa; + BrakeDelays:=i_BD; + +//tworzenie zbiornikow + BrakeCyl.CreateCap(i_bcd*BCA*1000); + BrakeRes.CreateCap(i_brc); + ValveRes.CreateCap(0.2); + +// FM.Free; +//materialy cierne + case i_mat of + bp_P10Bg: FM:=TP10Bg.Create; + bp_P10Bgu: FM:=TP10Bgu.Create; + else //domyslnie + FM:=TP10.Create; + end; + + +end ; *) + +constructor TBrake.Create(i_mbp, i_bcr, i_bcd, i_brc: real; i_bcn, i_BD, i_mat, i_ba, i_nbpa: byte); +begin + inherited Create; + MaxBP:=i_mbp; + BCN:=i_bcn; + BCA:=i_bcn*i_bcr*i_bcr*pi; + BA:=i_ba; + NBpA:=i_nbpa; + BrakeDelays:=i_BD; + //210.88 +// SizeBR:=i_bcn*i_bcr*i_bcr*i_bcd*40.17*MaxBP/(5-MaxBP); //objetosc ZP w stosunku do cylindra 14" i cisnienia 4.2 atm + SizeBR:=i_brc*0.0128; + SizeBC:=i_bcn*i_bcr*i_bcr*i_bcd*210.88*MaxBP/4.2; //objetosc CH w stosunku do cylindra 14" i cisnienia 4.2 atm + +// BrakeCyl:=TReservoir.Create; + BrakeCyl:=TBrakeCyl.Create; + BrakeRes:=TReservoir.Create; + ValveRes:=TReservoir.Create; + +//tworzenie zbiornikow + BrakeCyl.CreateCap(i_bcd*BCA*1000); + BrakeRes.CreateCap(i_brc); + ValveRes.CreateCap(0.25); + +// FM.Free; +//materialy cierne + i_mat:=i_mat and (255-bp_MHS); + case i_mat of + bp_P10Bg: FM:=TP10Bg.Create; + bp_P10Bgu: FM:=TP10Bgu.Create; + bp_FR513: FM:=TFR513.Create; + bp_FR510: FM:=TFR510.Create; + bp_Cosid: FM:=TCosid.Create; + bp_P10yBg: FM:=TP10yBg.Create; + bp_P10yBgu: FM:=TP10yBgu.Create; + bp_D1: FM:=TDisk1.Create; + bp_D2: FM:=TDisk2.Create; + else //domyslnie + FM:=TP10.Create; + end; +end; + +//inicjalizacja hamulca (stan poczatkowy) +procedure TBrake.Init(PP, HPP, LPP, BP: real; BDF: byte); +begin + +end; + +//pobranie wspolczynnika tarcia materialu +function TBrake.GetFC(Vel, N: real): real; +begin + GetFC:=FM.GetFC(N, Vel); +end; + +//cisnienie cylindra hamulcowego +function TBrake.GetBCP: real; +begin + GetBCP:=BrakeCyl.P; +end; + +//cisnienie zbiornika pomocniczego +function TBrake.GetBRP: real; +begin + GetBRP:=BrakeRes.P; +end; + +//cisnienie komory wstepnej +function TBrake.GetVRP: real; +begin + GetVRP:=ValveRes.P; +end; + +//cisnienie zbiornika sterujacego +function TBrake.GetCRP: real; +begin + GetCRP:=0; +end; + +//przeplyw z przewodu glowneg +function TBrake.GetPF(PP, dt, Vel: real): real; +begin + ValveRes.Act; + BrakeCyl.Act; + BrakeRes.Act; + GetPF:=0; +end; + +//przeplyw z przewodu zasilajacego +function TBrake.GetHPFlow(HP, dt: real): real; +begin + GetHPFlow:=0; +end; + +function TBrake.GetBCF: real; +begin + GetBCF:=BCA*100*BrakeCyl.P; +end; + +function TBrake.SetBDF(nBDF: byte): boolean; +begin + if ((nBDF and BrakeDelays)=nBDF)and(nBDF<>BrakeDelayFlag) then + begin + BrakeDelayFlag:=nBDF; + SetBDF:=true; + end + else + SetBDF:=false; +end; + +procedure TBrake.Releaser(state: byte); +begin + BrakeStatus:=(BrakeStatus and 247) or state*b_rls; +end; + +procedure TBrake.SetEPS(nEPS: real); +begin + +end; + +procedure TBrake.ASB(state: byte); +begin //255-b_asb(32) + BrakeStatus:=(BrakeStatus and 223) or state*b_asb; +end; + +function TBrake.GetStatus(): byte; +begin + GetStatus:=BrakeStatus; +end; + +function TBrake.GetSoundFlag: byte; +begin + GetSoundFlag:=SoundFlag; + SoundFlag:=0; +end; + +procedure TBrake.SetASBP(press: real); +begin + ASBP:=press; +end; + +procedure TBrake.ForceEmptiness(); +begin + ValveRes.CreatePress(0); + BrakeRes.CreatePress(0); + ValveRes.Act(); + BrakeRes.Act(); +end; + + +//---WESTINGHOUSE--- + +procedure TWest.Init(PP, HPP, LPP, BP: real; BDF: byte); +begin + ValveRes.CreatePress(PP); + BrakeCyl.CreatePress(BP); + BrakeRes.CreatePress(PP/2+HPP/2); +// BrakeStatus:=3*Byte(BP>0.1); +end; + +function TWest.GetPF(PP, dt, Vel: real): real; +var dv, dv1:real; + VVP, BVP, CVP, BCP: real; + temp: real; +begin + + BVP:=BrakeRes.P; + VVP:=ValveRes.P; + CVP:=BrakeCyl.P; + BCP:=BrakeCyl.P; + + if (BrakeStatus and 1)=1 then + if(VVP+0.03BVP+0.1) then + BrakeStatus:=(BrakeStatus and 252) + else if(VVP>BVP) then + BrakeStatus:=(BrakeStatus and 253) + else + else + if(VVP+0.25LBP+0.01) and (DCV) then + dV:=PF(0,CVP,0.1*sizeBC)*dt + else dV:=0; + BrakeCyl.Flow(-dV); + +//hamulec EP + temp:=BVP*Byte(EPS>0); + dV:=PF(temp,LBP,0.0015)*dt*EPS*EPS*Byte(LBP*EPS silowniki + if((BrakeStatus and b_on)=b_on)and((TareBP<0.1)or(BCPLBP)then + begin + DCV:=false; + dV:=PF(BVP,CVP,0.017*sizeBC)*dt; + end + else dV:=0 + else dV:=0; + BrakeRes.Flow(dV); + BrakeCyl.Flow(-dV); + if(DCV)then + dVP:=PF(LBP,BCP,0.01*sizeBC)*dt + else dVP:=0; + BrakeCyl.Flow(-dVP); + if(dVP>0)then dVP:=0; +//przeplyw ZP <-> rozdzielacz + if((BrakeStatus and b_hld)=b_off)then + dV:=PF(BVP,VVP,0.0011*sizeBR)*dt + else dV:=0; + BrakeRes.Flow(dV); + dV1:=dV*0.95; + ValveRes.Flow(-0.05*dV); +//przeplyw PG <-> rozdzielacz + dV:=PF(PP,VVP,0.01*sizeBR)*dt; + ValveRes.Flow(-dV); + + ValveRes.Act; + BrakeCyl.Act; + BrakeRes.Act; + GetPF:=dV-dV1; +end; + +function TWest.GetHPFlow(HP, dt: real): real; +begin + GetHPFlow:=dVP; +end; + +procedure TWest.SetLBP(P: real); +begin + LBP:=P; + if P>BrakeCyl.P then +// begin + DCV:=true; +// end +// else +// LBP:=P; +end; + +procedure TWest.SetEPS(nEPS: real); +var + BCP: real; +begin + BCP:=BrakeCyl.P; + if nEPS>0 then + DCV:=true + else if nEPS=0 then + begin + if(EPS<>0)then + begin + if(LBP>0.4)then + LBP:=BrakeCyl.P; + if(LBP<0.15)then + LBP:=0; + end; + end; + EPS:=nEPS; +end; + +procedure TWest.PLC(mass: real); +begin + LoadC:=1+Byte(Mass0.25)then + if(VVP+0.003+BCP/BVMCVP) then + BrakeStatus:=(BrakeStatus and 252) //luzowanie + else if(VVP+BCP/BVM>CVP) then + BrakeStatus:=(BrakeStatus and 253) //zatrzymanie napelaniania + else + else + if(VVP+0.100.25)and(BCP>0.25)then //zatrzymanie luzowanie + BrakeStatus:=(BrakeStatus or 1); + + if (BrakeStatus and 1)=0 then + SoundFlag:=SoundFlag or sf_CylU; +end; + +function TESt.CVs(bp: real): real; +var VVP, BVP, CVP: real; +begin + BVP:=BrakeRes.P; + CVP:=CntrlRes.P; + VVP:=ValveRes.P; + +//przeplyw ZS <-> PG + if(VVP0.4)then + CVs:=0 + else + if(VVP>CVP+0.4)then + if(BVP>CVP+0.2)then + CVs:=0.23 + else + CVs:=0.05 + else + if(BVP>CVP-0.1)then + CVs:=1 + else + CVs:=0.3; +end; + +function TESt.BVs(BCP: real): real; +var VVP, BVP, CVP: real; +begin + BVP:=BrakeRes.P; + CVP:=CntrlRes.P; + VVP:=ValveRes.P; + +//przeplyw ZP <-> rozdzielacz + if(BVPCVP+0.4)then + BVs:=0.1 + else + BVs:=0.3 + else + BVs:=0; +end; + + + + + +function TESt.GetPF(PP, dt, Vel: real): real; +var dv, dv1, temp:real; + VVP, BVP, BCP, CVP: real; +begin + BVP:=BrakeRes.P; + VVP:=ValveRes.P; + BCP:=BrakeCyl.P; + CVP:=CntrlRes.P-0.0; + + dV:=0; dV1:=0; + +//sprawdzanie stanu + CheckState(BCP, dV1); + CheckReleaser(dt); + + CVP:=CntrlRes.P; + VVP:=ValveRes.P; +//przeplyw ZS <-> PG + temp:=CVs(BCP); + dV:=PF(CVP,VVP,0.0015*temp)*dt; + CntrlRes.Flow(+dV); + ValveRes.Flow(-0.04*dV); + dV1:=dV1-0.96*dV; + + +//luzowanie + if(BrakeStatus and b_hld)=b_off then + dV:=PF(0,BCP,0.0058*sizeBC)*dt + else dV:=0; + BrakeCyl.Flow(-dV); + +//przeplyw ZP <-> silowniki + if(BrakeStatus and b_on)=b_on then + dV:=PF(BVP,BCP,0.016*sizeBC)*dt + else dV:=0; + BrakeRes.Flow(dV); + BrakeCyl.Flow(-dV); + +//przeplyw ZP <-> rozdzielacz + temp:=BVs(BCP); +// if(BrakeStatus and b_hld)=b_off then + if(VVP-0.05>BVP)then + dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt + else dV:=0; + BrakeRes.Flow(dV); + dV1:=dV1+dV*0.96; + ValveRes.Flow(-0.04*dV); +//przeplyw PG <-> rozdzielacz + dV:=PF(PP,VVP,0.01)*dt; + ValveRes.Flow(-dV); + + ValveRes.Act; + BrakeCyl.Act; + BrakeRes.Act; + CntrlRes.Act; + GetPF:=dV-dV1; +end; + +procedure TESt.Init(PP, HPP, LPP, BP: real; BDF: byte); +begin + ValveRes.CreatePress(PP); + BrakeCyl.CreatePress(BP); + BrakeRes.CreatePress(PP); + CntrlRes:=TReservoir.Create; + CntrlRes.CreateCap(15); + CntrlRes.CreatePress(HPP); + BrakeStatus:=0; + + BVM:=1/(HPP-LPP)*MaxBP; + + BrakeDelayFlag:=BDF; +end; + + +procedure TESt.EStParams(i_crc: real); +begin + +end; + + +function TESt.GetCRP: real; +begin + GetCRP:=CntrlRes.P; +end; + +//---EP2--- + +procedure TEStEP2.Init(PP, HPP, LPP, BP: real; BDF: byte); +begin + inherited; + ImplsRes.CreateCap(1); + ImplsRes.CreatePress(BP); + + BrakeRes.CreatePress(PP); + + BrakeDelayFlag:=bdelay_P; + BrakeDelays:=bdelay_P; +end; + + +function TEStEP2.GetPF(PP, dt, Vel: real): real; +var dv, dv1, temp:real; + VVP, BVP, BCP, CVP: real; +begin + BVP:=BrakeRes.P; + VVP:=ValveRes.P; + BCP:=ImplsRes.P; + CVP:=CntrlRes.P; //110115 - konsultacje warszawa1 + + dV:=0; dV1:=0; + +//odluzniacz + CheckReleaser(dt); + +//sprawdzanie stanu + if ((BrakeStatus and 1)=1)and(BCP>0.25) then + if(VVP+0.003+BCP/BVMCVP-0.12) then + BrakeStatus:=(BrakeStatus and 252) //luzowanie + else if(VVP+BCP/BVM>CVP-0.12) then + BrakeStatus:=(BrakeStatus and 253) //zatrzymanie napelaniania + else + else + if(VVP+0.100.25) then //zatrzymanie luzowanie + BrakeStatus:=(BrakeStatus or 1); + +//przeplyw ZS <-> PG + if(BVP0)or(BCP>0.25)then + temp:=0 + else + if(VVP>CVP+0.4)then + temp:=0.1 + else + temp:=0.5; + + dV:=PF(CVP,VVP,0.0015*temp/1.8)*dt; + CntrlRes.Flow(+dV); + ValveRes.Flow(-0.04*dV); + dV1:=dV1-0.96*dV; + +//hamulec EP + temp:=BVP*Byte(EPS>0); + dV:=PF(temp,LBP,0.00053+0.00060*Byte(EPS<0))*dt*EPS*EPS*Byte(LBP*EPS KI + if ((BrakeStatus and b_on)=b_on) and (BCP rozdzielacz + dV:=PF(PP,VVP,0.01*sizeBR)*dt; + ValveRes.Flow(-dV); + + GetPF:=dV-dV1; + + temp:=Max0R(BCP,LBP); + + if(ImplsRes.P>LBP+0.01)then + LBP:=0; + +//luzowanie CH + if(BrakeCyl.P>temp+0.005)or(Max0R(ImplsRes.P,8*LBP)<0.05) then + dV:=PF(0,BrakeCyl.P,0.25*sizeBC*(0.01+(BrakeCyl.P-temp)))*dt + else dV:=0; + BrakeCyl.Flow(-dV); +//przeplyw ZP <-> CH + if(BrakeCyl.P0.10)and(Max0R(BCP,LBP)0) and (LBP+0.01 PG + temp:=CVs(BCP); + dV:=PF(CVP,VVP,0.0015*temp)*dt; + CntrlRes.Flow(+dV); + ValveRes.Flow(-0.04*dV); + dV1:=dV1-0.96*dV; + + +//luzowanie + if(BrakeStatus and b_hld)=b_off then + dV:=PF(0,BCP,0.0042*(1.37-Byte(BrakeDelayFlag=bdelay_G))*sizeBC)*dt + else dV:=0; + BrakeCyl.Flow(-dV); +//przeplyw ZP <-> silowniki + if(BrakeStatus and b_on)=b_on then + dV:=PF(BVP,BCP,0.017*(1+Byte((BCP<0.58)and(BrakeDelayFlag=bdelay_G)))*(1.13-Byte((BCP>0.6)and(BrakeDelayFlag=bdelay_G)))*sizeBC)*dt + else dV:=0; + BrakeRes.Flow(dV); + BrakeCyl.Flow(-dV); +//przeplyw ZP <-> rozdzielacz + temp:=BVs(BCP); + if(VVP-0.05>BVP)then + dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt + else dV:=0; + BrakeRes.Flow(dV); + dV1:=dV1+dV*0.96; + ValveRes.Flow(-0.04*dV); +//przeplyw PG <-> rozdzielacz + dV:=PF(PP,VVP,0.01)*dt; + ValveRes.Flow(-dV); + + ValveRes.Act; + BrakeCyl.Act; + BrakeRes.Act; + CntrlRes.Act; + GetPF:=dV-dV1; +end; + +//---EST4-RAPID--- + +function TESt4R.GetPF(PP, dt, Vel: real): real; +var dv, dv1, temp:real; + VVP, BVP, BCP, CVP: real; +begin + BVP:=BrakeRes.P; + VVP:=ValveRes.P; + BCP:=ImplsRes.P; + CVP:=CntrlRes.P-0.0; + + dV:=0; dV1:=0; + +//sprawdzanie stanu + CheckState(BCP, dV1); + CheckReleaser(dt); + + CVP:=CntrlRes.P; + VVP:=ValveRes.P; +//przeplyw ZS <-> PG + temp:=CVs(BCP); + dV:=PF(CVP,VVP,0.0015*temp/1.8)*dt; + CntrlRes.Flow(+dV); + ValveRes.Flow(-0.04*dV); + dV1:=dV1-0.96*dV; + + +//luzowanie KI + if(BrakeStatus and b_hld)=b_off then + dV:=PF(0,BCP,0.00037*1.14*15/19)*dt + else dV:=0; + ImplsRes.Flow(-dV); +//przeplyw ZP <-> KI + if(BrakeStatus and b_on)=b_on then + dV:=PF(BVP,BCP,0.0014)*dt + else dV:=0; +// BrakeRes.Flow(dV); + ImplsRes.Flow(-dV); +//przeplyw ZP <-> rozdzielacz + temp:=BVs(BCP); + if(BVP rozdzielacz + dV:=PF(PP,VVP,0.01*sizeBR)*dt; + ValveRes.Flow(-dV); + + GetPF:=dV-dV1; + + + + RapidStatus:=(BrakeDelayFlag=bdelay_R)and(((Vel>55)and(RapidStatus))or(Vel>70)); + + RapidTemp:=RapidTemp+(0.9*Byte(RapidStatus)-RapidTemp)*dt/2; + temp:=1.9-RapidTemp; + if((BrakeStatus and b_asb)=b_asb)then + temp:=1000; +//luzowanie CH + if(BrakeCyl.P*temp>ImplsRes.P+0.005)or(ImplsRes.P<0.25) then + if((BrakeStatus and b_asb)=b_asb)then + dV:=PFVd(BrakeCyl.P,0,0.115*sizeBC*4,ImplsRes.P/temp)*dt + else + dV:=PFVd(BrakeCyl.P,0,0.115*sizeBC,ImplsRes.P/temp)*dt +// dV:=PF(0,BrakeCyl.P,0.115*sizeBC/2)*dt +// dV:=PFVd(BrakeCyl.P,0,0.015*sizeBC/2,ImplsRes.P/temp)*dt + else dV:=0; + BrakeCyl.Flow(-dV); +//przeplyw ZP <-> CH + if(BrakeCyl.P*temp0.3) then +// dV:=PFVa(BVP,BrakeCyl.P,0.020*sizeBC,ImplsRes.P/temp)*dt + dV:=PFVa(BVP,BrakeCyl.P,0.60*sizeBC,ImplsRes.P/temp)*dt + else dV:=0; + BrakeRes.Flow(-dV); + BrakeCyl.Flow(+dV); + + ImplsRes.Act; + ValveRes.Act; + BrakeCyl.Act; + BrakeRes.Act; + CntrlRes.Act; +end; + +procedure TESt4R.Init(PP, HPP, LPP, BP: real; BDF: byte); +begin + inherited; + ImplsRes:=TReservoir.Create; + ImplsRes.CreateCap(1); + ImplsRes.CreatePress(BP); + + BrakeDelayFlag:=bdelay_R; +end; + + +//---EST3/AL2--- + +function TESt3AL2.GetPF(PP, dt, Vel: real): real; +var dv, dv1, temp:real; + VVP, BVP, BCP, CVP: real; +begin + BVP:=BrakeRes.P; + VVP:=ValveRes.P; + BCP:=ImplsRes.P; + CVP:=CntrlRes.P-0.0; + + dV:=0; dV1:=0; + +//sprawdzanie stanu + CheckState(BCP, dV1); + CheckReleaser(dt); + + VVP:=ValveRes.P; +//przeplyw ZS <-> PG + temp:=CVs(BCP); + dV:=PF(CVP,VVP,0.0015*temp)*dt; + CntrlRes.Flow(+dV); + ValveRes.Flow(-0.04*dV); + dV1:=dV1-0.96*dV; + +//luzowanie KI + if(BrakeStatus and b_hld)=b_off then + dV:=PF(0,BCP,0.00017*(1.37-Byte(BrakeDelayFlag=bdelay_G)))*dt + else dV:=0; + ImplsRes.Flow(-dV); +//przeplyw ZP <-> KI + if ((BrakeStatus and b_on)=b_on) and (BCP0.6)and(BrakeDelayFlag=bdelay_G))))*dt + else dV:=0; + BrakeRes.Flow(dV); + ImplsRes.Flow(-dV); +//przeplyw ZP <-> rozdzielacz + temp:=BVs(BCP); + if(VVP-0.05>BVP)then + dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt + else dV:=0; + BrakeRes.Flow(dV); + dV1:=dV1+dV*0.96; + ValveRes.Flow(-0.04*dV); +//przeplyw PG <-> rozdzielacz + dV:=PF(PP,VVP,0.01)*dt; + ValveRes.Flow(-dV); + GetPF:=dV-dV1; + +//luzowanie CH + if(BrakeCyl.P>ImplsRes.P*LoadC+0.005)or(ImplsRes.P<0.15) then + dV:=PF(0,BrakeCyl.P,0.015*sizeBC)*dt + else dV:=0; + BrakeCyl.Flow(-dV); + +//przeplyw ZP <-> CH + if(BrakeCyl.P0.15) then + dV:=PF(BVP,BrakeCyl.P,0.020*sizeBC)*dt + else dV:=0; + BrakeRes.Flow(dV); + BrakeCyl.Flow(-dV); + + ImplsRes.Act; + ValveRes.Act; + BrakeCyl.Act; + BrakeRes.Act; + CntrlRes.Act; +end; + +procedure TESt3AL2.PLC(mass: real); +begin + LoadC:=1+Byte(Mass PG + if((CVP-BCP)*BVM>0.5)then + temp:=0 + else + if(VVP>CVP+0.4)then + temp:=0.5 + else + temp:=0.5; + + dV:=PF1(CVP,VVP,0.0015*temp/1.8/2)*dt; + CntrlRes.Flow(+dV); + ValveRes.Flow(-0.04*dV); + dV1:=dV1-0.96*dV; + + +//luzowanie KI {G} +// if VVP>BCP then +// dV:=PF(VVP,BCP,0.00004)*dt +// else if (CVP-BCP)<1.5 then +// dV:=PF(VVP,BCP,0.00020*(1.33-Byte((CVP-BCP)*BVM>0.65)))*dt +// else dV:=0; 0.00025 P + {P} + if VVP>BCP then + dV:=PF(VVP,BCP,0.00043*(1.5-Byte(((CVP-BCP)*BVM>1)and(BrakeDelayFlag=bdelay_G))),0.1)*dt + else if (CVP-BCP)<1.5 then + dV:=PF(VVP,BCP,0.001472*(1.36-Byte(((CVP-BCP)*BVM>1)and(BrakeDelayFlag=bdelay_G))),0.1)*dt + else dV:=0; + + ImplsRes.Flow(-dV); + ValveRes.Flow(+dV); +//przeplyw PG <-> rozdzielacz + dV:=PF(PP,VVP,0.01,0.1)*dt; + ValveRes.Flow(-dV); + + GetPF:=dV-dV1; + +// if Vel>55 then temp:=0.72 else +// temp:=1;{R} +//cisnienie PP + RapidTemp:=RapidTemp+(RM*Byte((Vel>55)and(BrakeDelayFlag=bdelay_R))-RapidTemp)*dt/2; + temp:=1-RapidTemp; + if EDFlag>0.2 then temp:=10000; + +//powtarzacz — podwojny zawor zwrotny + temp:=Max0R(((CVP-BCP)*BVM+ASBP*Byte((BrakeStatus and b_asb)=b_asb))/temp,LBP); +//luzowanie CH + if(BrakeCyl.P>temp+0.005)or(temp<0.28) then +// dV:=PF(0,BrakeCyl.P,0.0015*3*sizeBC)*dt +// dV:=PF(0,BrakeCyl.P,0.005*3*sizeBC)*dt + dV:=PFVd(BrakeCyl.P,0,0.005*7*sizeBC,temp)*dt + else dV:=0; + BrakeCyl.Flow(-dV); +//przeplyw ZP <-> CH + if(BrakeCyl.P0.29) then +// dV:=PF(BVP,BrakeCyl.P,0.002*3*sizeBC*2)*dt + dV:=-PFVa(BVP,BrakeCyl.P,0.002*7*sizeBC*2,temp)*dt + else dV:=0; + BrakeRes.Flow(dV); + BrakeCyl.Flow(-dV); + + ImplsRes.Act; + ValveRes.Act; + BrakeCyl.Act; + BrakeRes.Act; + CntrlRes.Act; +// LBP:=ValveRes.P; +// ValveRes.CreatePress(ImplsRes.P); +end; + +procedure TLSt.Init(PP, HPP, LPP, BP: real; BDF: byte); +begin + inherited; + ValveRes.CreateCap(1); + ImplsRes.CreateCap(8); + ImplsRes.CreatePress(PP); + BrakeRes.CreatePress(8); + ValveRes.CreatePress(PP); + + EDFlag:=0; + + BrakeDelayFlag:=BDF; +end; + +procedure TLSt.SetLBP(P: real); +begin + LBP:=P; +end; + +function TLSt.GetEDBCP: real; +var CVP, BCP: real; +begin + CVP:=CntrlRes.P; + BCP:=ImplsRes.P; + GetEDBCP:=(CVP-BCP)*BVM; +end; + +procedure TLSt.SetED(EDstate: real); +begin + EDFlag:=EDstate; +end; + +procedure TLSt.SetRM(RMR: real); +begin + RM:=1-RMR; +end; + +function TLSt.GetHPFlow(HP, dt: real): real; +var dV: real; +begin + dV:=Min0R(PF(HP,BrakeRes.P,0.01*dt),0); + BrakeRes.Flow(-dV); + GetHPFlow:=dV; +end; + +//---EStED--- + +function TEStED.GetPF(PP, dt, Vel: real): real; +var dv, dv1, temp:real; + VVP, BVP, BCP, CVP, MPP, nastG: real; + i: byte; +begin + BVP:=BrakeRes.P; + VVP:=ValveRes.P; + BCP:=ImplsRes.P; + CVP:=CntrlRes.P-0.0; + MPP:=Miedzypoj.P; + dV1:=0; + + nastG:=(BrakeDelayFlag and bdelay_G); + +//sprawdzanie stanu + if(BCP<0.25)and(VVP+0.08>CVP)then Przys_blok:=false; + +//sprawdzanie stanu + if(VVP+0.002+BCP/BVMCVP-0.05) then + BrakeStatus:=(BrakeStatus and 252) //luzowanie + else if(VVP+BCP/BVM>CVP-0.05) then + BrakeStatus:=(BrakeStatus and 253) //zatrzymanie napelaniania + else if(VVP+(BCP-0.1)/BVM0.25)then //zatrzymanie luzowania + BrakeStatus:=(BrakeStatus or 1); + + if(VVP+0.100.5)then + Zamykajacy:=true + else if(VVP-0.6CVP-0.08)then + temp:=Nozzles[5] + else + temp:=Nozzles[6]; + dV:=dV+PF(MPP,CVP,temp); + + if(MPP-0.05>BVP)then + dV:=dV+PF(MPP-0.05,BVP,Nozzles[10]*nastG+(1-nastG)*Nozzles[9]); + if MPP>VVP then dV:=dV+PF(MPP,VVP,0.02); + Miedzypoj.Flow(dV*dt*0.15); + + + RapidTemp:=RapidTemp+(RM*Byte((Vel>55)and(BrakeDelayFlag=bdelay_R))-RapidTemp)*dt/2; + temp:=Max0R(1-RapidTemp,0.001); +// if EDFlag then temp:=1000; +// temp:=temp/(1-); + +//powtarzacz — podwojny zawor zwrotny + temp:=Max0R(LoadC*BCP/temp*Min0R(Max0R(1-EDFlag,0),1),LBP); + + if(BrakeCyl.P>temp)then + dV:=-PFVd(BrakeCyl.P,0,0.02*sizeBC,temp)*dt + else + if(BrakeCyl.P0 then + BrakeRes.Flow(-dV); + + +//przeplyw ZS <-> PG + if(MPPCVP-0.08)then + temp:=Nozzles[5] + else + temp:=Nozzles[6]; + dV:=PF(CVP,MPP,temp)*dt; + CntrlRes.Flow(+dV); + ValveRes.Flow(-0.02*dV); + dV1:=dV1+0.98*dV; + +//przeplyw ZP <-> MPJ + if(MPP-0.05>BVP)then + dV:=PF(BVP,MPP-0.05,Nozzles[10]*nastG+(1-nastG)*Nozzles[9])*dt + else dV:=0; + BrakeRes.Flow(dV); + dV1:=dV1+dV*0.98; + ValveRes.Flow(-0.02*dV); +//przeplyw PG <-> rozdzielacz + dV:=PF(PP,VVP,0.005)*dt; //0.01 + ValveRes.Flow(-dV); + + + ValveRes.Act; + BrakeCyl.Act; + BrakeRes.Act; + CntrlRes.Act; + Miedzypoj.Act; + ImplsRes.Act; + GetPF:=dV-dV1; +end; + +procedure TEStED.Init(PP, HPP, LPP, BP: real; BDF: byte); +var i:integer; +begin + inherited; + + ValveRes.CreatePress(1*PP); + BrakeCyl.CreatePress(1*BP); + +// CntrlRes:=TReservoir.Create; +// CntrlRes.CreateCap(15); +// CntrlRes.CreatePress(1*HPP); + + BrakeStatus:=Byte(BP>1)*1; + Miedzypoj:=TReservoir.Create; + Miedzypoj.CreateCap(5); + Miedzypoj.CreatePress(PP); + + ImplsRes.CreateCap(1); + ImplsRes.CreatePress(BP); + + BVM:=1/(HPP-0.05-LPP)*MaxBP; + + BrakeDelayFlag:=BDF; + Zamykajacy:=false; + EDFlag:=0; + + Nozzles[0]:=1.250/1.7; + Nozzles[1]:=0.907; + Nozzles[2]:=0.510/1.7; + Nozzles[3]:=0.524/1.17; + Nozzles[4]:=7.4; + Nozzles[7]:=5.3; + Nozzles[8]:=2.5; + Nozzles[9]:=7.28; + Nozzles[10]:=2.96; + Nozzles[5]:=1.1; + Nozzles[6]:=0.9; + + for i:=0 to 10 do + begin + Nozzles[i]:=Nozzles[i]*Nozzles[i]*3.14159/4000; + end; + +end; + +function TEStED.GetEDBCP: real; +begin + GetEDBCP:=ImplsRes.P*LoadC; +end; + +procedure TEStED.PLC(mass: real); +begin + LoadC:=1+Byte(MassCVP) then + BrakeStatus:=(BrakeStatus and 252) //luzowanie + else if(VVP+BCP/BVM>CVP) then + BrakeStatus:=(BrakeStatus and 253) //zatrzymanie napelaniania + else + else + if(VVP+0.100.25) then //zatrzymanie luzowanie + BrakeStatus:=(BrakeStatus or 1); +end; + +function TCV1.CVs(bp: real): real; +begin +//przeplyw ZS <-> PG + if(bp>0.05)then + CVs:=0 + else + CVs:=0.23 +end; + +function TCV1.BVs(BCP: real): real; +var VVP, BVP, CVP: real; +begin + BVP:=BrakeRes.P; + CVP:=CntrlRes.P; + VVP:=ValveRes.P; + +//przeplyw ZP <-> rozdzielacz + if(BVP0.05)then + BVs:=0 + else + BVs:=0.2*(1.5-Byte(BVP>VVP)); +end; + +function TCV1.GetPF(PP, dt, Vel: real): real; +var dv, dv1, temp:real; + VVP, BVP, BCP, CVP: real; +begin + BVP:=BrakeRes.P; + VVP:=Min0R(ValveRes.P,BVP+0.05); + BCP:=BrakeCyl.P; + CVP:=CntrlRes.P-0.0; + + dV:=0; dV1:=0; + +//sprawdzanie stanu + CheckState(BCP, dV1); + + VVP:=ValveRes.P; +//przeplyw ZS <-> PG + temp:=CVs(BCP); + dV:=PF(CVP,VVP,0.0015*temp)*dt; + CntrlRes.Flow(+dV); + ValveRes.Flow(-0.04*dV); + dV1:=dV1-0.96*dV; + + +//luzowanie + if(BrakeStatus and b_hld)=b_off then + dV:=PF(0,BCP,0.0042*(1.37-Byte(BrakeDelayFlag=bdelay_G))*sizeBC)*dt + else dV:=0; + BrakeCyl.Flow(-dV); + +//przeplyw ZP <-> silowniki + if(BrakeStatus and b_on)=b_on then + dV:=PF(BVP,BCP,0.017*(1+Byte((BCP<0.58)and(BrakeDelayFlag=bdelay_G)))*(1.13-Byte((BCP>0.6)and(BrakeDelayFlag=bdelay_G)))*sizeBC)*dt + else dV:=0; + BrakeRes.Flow(dV); + BrakeCyl.Flow(-dV); + +//przeplyw ZP <-> rozdzielacz + temp:=BVs(BCP); + if(VVP+0.05>BVP)then + dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt + else dV:=0; + BrakeRes.Flow(dV); + dV1:=dV1+dV*0.96; + ValveRes.Flow(-0.04*dV); +//przeplyw PG <-> rozdzielacz + dV:=PF(PP,VVP,0.01)*dt; + ValveRes.Flow(-dV); + + ValveRes.Act; + BrakeCyl.Act; + BrakeRes.Act; + CntrlRes.Act; + GetPF:=dV-dV1; +end; + +procedure TCV1.Init(PP, HPP, LPP, BP: real; BDF: byte); +begin + ValveRes.CreatePress(PP); + BrakeCyl.CreatePress(BP); + BrakeRes.CreatePress(PP); + CntrlRes:=TReservoir.Create; + CntrlRes.CreateCap(15); + CntrlRes.CreatePress(HPP); + BrakeStatus:=0; + + BVM:=1/(HPP-LPP)*MaxBP; + + BrakeDelayFlag:=BDF; +end; + +function TCV1.GetCRP: real; +begin + GetCRP:=CntrlRes.P; +end; + + +//---CV1-L-TR--- + +procedure TCV1L_TR.SetLBP(P: real); +begin + LBP:=P; +end; + +function TCV1L_TR.GetHPFlow(HP, dt: real): real; +var dV: real; +begin + dV:=PF(HP,BrakeRes.P,0.01)*dt; + dV:=Min0R(0,dV); + BrakeRes.Flow(-dV); + GetHPFlow:=dV; +end; + +procedure TCV1L_TR.Init(PP, HPP, LPP, BP: real; BDF: byte); +begin + inherited; + ImplsRes:=TReservoir.Create; + ImplsRes.CreateCap(2.5); + ImplsRes.CreatePress(BP); +end; + +function TCV1L_TR.GetPF(PP, dt, Vel: real): real; +var dv, dv1, temp:real; + VVP, BVP, BCP, CVP: real; +begin + BVP:=BrakeRes.P; + VVP:=Min0R(ValveRes.P,BVP+0.05); + BCP:=ImplsRes.P; + CVP:=CntrlRes.P-0.0; + + dV:=0; dV1:=0; + +//sprawdzanie stanu + CheckState(BCP, dV1); + + VVP:=ValveRes.P; +//przeplyw ZS <-> PG + temp:=CVs(BCP); + dV:=PF(CVP,VVP,0.0015*temp)*dt; + CntrlRes.Flow(+dV); + ValveRes.Flow(-0.04*dV); + dV1:=dV1-0.96*dV; + + +//luzowanie KI + if(BrakeStatus and b_hld)=b_off then + dV:=PF(0,BCP,0.000425*(1.37-Byte(BrakeDelayFlag=bdelay_G)))*dt + else dV:=0; + ImplsRes.Flow(-dV); +//przeplyw ZP <-> KI + if ((BrakeStatus and b_on)=b_on) and (BCP0.6)and(BrakeDelayFlag=bdelay_G))))*dt + else dV:=0; + BrakeRes.Flow(dV); + ImplsRes.Flow(-dV); + +//przeplyw ZP <-> rozdzielacz + temp:=BVs(BCP); + if(VVP+0.05>BVP)then + dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt + else dV:=0; + BrakeRes.Flow(dV); + dV1:=dV1+dV*0.96; + ValveRes.Flow(-0.04*dV); +//przeplyw PG <-> rozdzielacz + dV:=PF(PP,VVP,0.01)*dt; + GetPF:=dV-dV1; + + temp:=Max0R(BCP,LBP); + +//luzowanie CH + if(BrakeCyl.P>temp+0.005)or(Max0R(ImplsRes.P,8*LBP)<0.25) then + dV:=PF(0,BrakeCyl.P,0.015*sizeBC)*dt + else dV:=0; + BrakeCyl.Flow(-dV); + +//przeplyw ZP <-> CH + if(BrakeCyl.P0.3)and(Max0R(BCP,LBP)CVP) then + BrakeStatus:=(BrakeStatus and 252) //luzowanie + else if(VVP+BCP/BVM>CVP) then + BrakeStatus:=(BrakeStatus and 253) //zatrzymanie napelaniania + else + else + if(VVP+0.100.25) then //zatrzymanie luzowanie + BrakeStatus:=(BrakeStatus or 1); +end; + +function TKE.CVs(bp: real): real; +var VVP, BVP, CVP: real; +begin + BVP:=BrakeRes.P; + CVP:=CntrlRes.P; + VVP:=ValveRes.P; + +//przeplyw ZS <-> PG + if(bp>0.2)then + CVs:=0 + else + if(VVP>CVP+0.4)then + CVs:=0.05 + else + CVs:=0.23 +end; + +function TKE.BVs(BCP: real): real; +var VVP, BVP, CVP: real; +begin + BVP:=BrakeRes.P; + CVP:=CntrlRes.P; + VVP:=ValveRes.P; + +//przeplyw ZP <-> rozdzielacz + if (BVP>VVP) then + BVs:=0 + else + if(BVP PG + temp:=CVs(IMP); + dV:=PF(CVP,VVP,0.0015*temp)*dt; + CntrlRes.Flow(+dV); + ValveRes.Flow(-0.04*dV); + dV1:=dV1-0.96*dV; + +//luzowanie + if(BrakeStatus and b_hld)=b_off then + begin + if ((BrakeDelayFlag and bdelay_G)=0) then + temp:=0.283+0.139 + else + temp:=0.139; + dV:=PF(0,IMP,0.001*temp)*dt + end + else dV:=0; + ImplsRes.Flow(-dV); + +//przeplyw ZP <-> silowniki + if((BrakeStatus and b_on)=b_on)and(IMP50)and(RapidStatus))or(Vel>70)) + else //jesli tarczowki, to zostan + RapidStatus:=((BrakeDelayFlag and bdelay_R)=bdelay_R); + +// temp:=1.9-0.9*Byte(RapidStatus); + + if(RM*RM>0.1)then //jesli jest rapid + if(RM>0)then //jesli dodatni (naddatek); + temp:=1-RM*Byte(RapidStatus) + else + temp:=1-RM*(1-Byte(RapidStatus)) + else + temp:=1; + temp:=temp/LoadC; +//luzowanie CH +// temp:=Max0R(BCP,LBP); + IMP:=Max0R(IMP/temp,Max0R(LBP,ASBP*Byte((BrakeStatus and b_asb)=b_asb))); + +//luzowanie CH + if(BCP>IMP+0.005)or(Max0R(ImplsRes.P,8*LBP)<0.25) then + dV:=PFVd(BCP,0,0.05,IMP)*dt + else dV:=0; + BrakeCyl.Flow(-dV); + if(BCP0.3) then + dV:=PFVa(BVP,BCP,0.05,IMP)*dt + else dV:=0; + BrakeRes.Flow(-dV); + BrakeCyl.Flow(+dV); + +//przeplyw ZP <-> rozdzielacz + temp:=BVs(IMP); +// if(BrakeStatus and b_hld)=b_off then + if(IMP<0.25)or(VVP+0.05>BVP)then + dV:=PF(BVP,VVP,0.02*sizeBR*temp/1.87)*dt + else dV:=0; + BrakeRes.Flow(dV); + dV1:=dV1+dV*0.96; + ValveRes.Flow(-0.04*dV); +//przeplyw PG <-> rozdzielacz + dV:=PF(PP,VVP,0.01)*dt; + ValveRes.Flow(-dV); + + ValveRes.Act; + BrakeCyl.Act; + BrakeRes.Act; + CntrlRes.Act; + ImplsRes.Act; + GetPF:=dV-dV1; +end; + +procedure TKE.Init(PP, HPP, LPP, BP: real; BDF: byte); +begin + ValveRes.CreatePress(PP); + BrakeCyl.CreatePress(BP); + BrakeRes.CreatePress(PP); + + CntrlRes:=TReservoir.Create; //komora sterujaca + CntrlRes.CreateCap(5); + CntrlRes.CreatePress(HPP); + + ImplsRes:=TReservoir.Create; //komora zastepcza silownika + ImplsRes.CreateCap(1); + ImplsRes.CreatePress(BP); + + BrakeStatus:=0; + + BVM:=1/(HPP-LPP)*MaxBP; + + BrakeDelayFlag:=BDF; +end; + +function TKE.GetCRP: real; +begin + GetCRP:=CntrlRes.P; +end; + +function TKE.GetHPFlow(HP, dt: real): real; +var dV: real; +begin + dV:=PF(HP,BrakeRes.P,0.01)*dt; + dV:=Min0R(0,dV); + BrakeRes.Flow(-dV); + GetHPFlow:=dV; +end; + +procedure TKE.PLC(mass: real); +begin + LoadC:=1+Byte(Massrp+0.05)then + dpMainValve:=PF(Min0R(cp+0.1,HP),pp,1.1*(ActFlowSpeed)/(LBDelay))*dt; + if(cp0.1)then + begin + cp:=5+(tp-0.1)*0.08; + tp:=tp-dt/12/2; + end; + if(cp>rp+0.1)and(cp<=5)then + dpMainValve:=PF(Min0R(cp+0.25,HP),pp,2*(ActFlowSpeed)/(LBDelay))*dt + else + if cp>5 then + dpMainValve:=PF(Min0R(cp,HP),pp,2*(ActFlowSpeed)/(LBDelay))*dt + else + dpMainValve:=PF(dpPipe,pp,(ActFlowSpeed)/(LBDelay))*dt + end; + + if(Round(i_bcp)=i_bcpNo)then + begin + dpMainValve:=PF(0,pp,(ActFlowSpeed)/(LBDelay))*dt; + end; + + GetPF:=dpMainValve; +end; + +procedure TFV4a.Init(press: real); +begin + CP:= press; + TP:= 0; + RP:= press; + Time:= false; + TimeEP:=false; +end; + + +//---FV4a/M--- nowonapisany kran bez poprawki IC + +function TFV4aM.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; +function LPP_RP(pos: real): real; //cisnienie z zaokraglonej pozycji; +var i_pos: integer; +begin + i_pos:=Round(pos-0.5); //zaokraglone w dol + LPP_RP:=BPT[i_pos][1]+(BPT[i_pos+1][1]-BPT[i_pos][1])*(pos-i_pos); //interpolacja liniowa +end; +function EQ(pos: real; i_pos: real): boolean; +begin + EQ:=(pos<=i_pos+0.5)and(pos>i_pos-0.5); +end; +const + LBDelay = 100; + xpM = 0.3; //mnoznik membrany komory pod +var + LimPP, dpPipe, dpMainValve, ActFlowSpeed, dp: real; + pom: real; + i: byte; +begin + ep:=pp/2*1.5+ep/2*0.5; //SPKS!! +// ep:=pp; +// ep:=cp/3+pp/3+ep/3; +// ep:=cp; + + for i:=0 to 4 do + Sounds[i]:=0; + dp:=0; + + i_bcp:=Max0R(Min0R(i_bcp,5.999),-1.999); //na wszelki wypadek, zeby nie wyszlo poza zakres + + if(tp>0)then + begin //jesli czasowy jest niepusty +// dp:=0.07; //od cisnienia 5 do 0 w 60 sekund ((5-0)*dt/75) + dp:=0.045; //2.5 w 55 sekund (5,35->5,15 w PG) + tp:=tp-dp*dt; + Sounds[s_fv4a_t]:=dp; + end + else //.08 + begin + tp:=0; + end; + + if(xp>0)then //jesli komora pod niepusta jest niepusty + begin + dp:=2.5; + Sounds[s_fv4a_x]:=dp*xp; + xp:=xp-dt*dp*2; //od cisnienia 5 do 0 w 10 sekund ((5-0)*dt/10) + end + else //.75 + xp:=0; //jak pusty, to pusty + + Limpp:=Min0R(LPP_RP(i_bcp)+tp*0.08+RedAdj,HP); //pozycja + czasowy lub zasilanie + ActFlowSpeed:=BPT[Round(i_bcp)][0]; + + if(EQ(i_bcp,-1))then pom:=Min0R(HP,5.4+RedAdj) else pom:=Min0R(cp,HP); + + if(pom>rp+0.25)then Fala:=true; + if(Fala)then + if(pom>rp+0.3)then +// if(ep>rp+0.11)then + xp:=xp-20*PR(pom,xp)*dt +// else +// xp:=xp-16*(ep-(ep+0.01))/(0.1)*PR(ep,xp)*dt + else Fala:=false; + + if(Limpp>cp)then //podwyzszanie szybkie + cp:=cp+5*60*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt //zbiornik sterujacy + else + cp:=cp+13*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt; //zbiornik sterujacy + + Limpp:=pom; //cp + dpPipe:=Min0R(HP,Limpp+xp*xpM); + + if dpPipe>pp then + dpMainValve:=-PFVa(HP,pp,ActFlowSpeed/(LBDelay),dpPipe,0.4) + else + dpMainValve:=PFVd(pp,0,ActFlowSpeed/(LBDelay),dpPipe,0.4); + + if EQ(i_bcp,-1) then + begin + if(tp<5)then tp:=tp+dt; //5/10 + if(tp<1)then tp:=tp-0.5*dt; //5/10 +// dpMainValve:=dpMainValve*2;//+1*PF(dpPipe,pp,(ActFlowSpeed)/(LBDelay))//coby nie przeszkadzal przy ladowaniu z zaworu obok + end; + + if EQ(i_bcp,0) then + begin + if(tp>2)then + dpMainValve:=dpMainValve*1.5;//+0.5*PF(dpPipe,pp,(ActFlowSpeed)/(LBDelay))//coby nie przeszkadzal przy ladowaniu z zaworu obok + end; + + + + + + ep:=dpPipe; + if(EQ(i_bcp,0)or(rp>ep))then + rp:=rp+PF(rp,ep,0.0007)*dt //powolne wzrastanie, ale szybsze na jezdzie + else + rp:=rp+PF(rp,ep,0.000093/2*2)*dt; //powolne wzrastanie i to bardzo //jednak trzeba wydluzyc, bo obecnie zle dziala + if (rp0 then + Sounds[s_fv4a_b]:=dpMainValve + else + Sounds[s_fv4a_u]:=-dpMainValve; + end; + + GetPF:=dpMainValve*dt; +end; + +procedure TFV4aM.Init(press: real); +begin + CP:= press; + TP:= 0; + RP:= press; + XP:= 0; + Time:=false; + TimeEP:=false; +end; + +procedure TFV4aM.SetReductor(nAdj: real); +begin + RedAdj:= nAdj; +end; + +function TFV4aM.GetSound(i: byte): real; +begin + if i>4 then + GetSound:=0 + else + GetSound:=Sounds[i]; +end; + +function TFV4aM.GetPos(i: byte): real; +const + table: array[0..10] of real = (-2,6,-1,0,-2,1,4,6,0,0,0); +begin + GetPos:=table[i]; +end; + +//---FV4a/M--- nowonapisany kran bez poprawki IC + +function TMHZ_EN57.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; +function LPP_RP(pos: real): real; //cisnienie z zaokraglonej pozycji; +begin + if pos>8.5 then + LPP_RP:=5.0-0.15*pos-0.35 + else if pos>0.5 then + LPP_RP:=5.0-0.15*pos-0.1 + else + LPP_RP:=5.0 +end; +function EQ(pos: real; i_pos: real): boolean; +begin + EQ:=(pos<=i_pos+0.5)and(pos>i_pos-0.5); +end; +const + LBDelay = 100; +var + LimPP, dpPipe, dpMainValve, ActFlowSpeed, dp: real; + pom: real; + i: byte; +begin + + for i:=0 to 4 do + Sounds[i]:=0; + dp:=0; + + i_bcp:=Max0R(Min0R(i_bcp,9.999),-0.999); //na wszelki wypadek, zeby nie wyszlo poza zakres + + if(tp>0)then + begin + dp:=0.045; + if EQ(i_bcp,0) then + tp:=tp-dp*dt; + Sounds[s_fv4a_t]:=dp; + end + else + begin + tp:=0; + end; + + Limpp:=Min0R(LPP_RP(i_bcp)+tp*0.08+RedAdj,HP); //pozycja + czasowy lub zasilanie + ActFlowSpeed:=4; + + if(EQ(i_bcp,-1))then pom:=Min0R(HP,5.4+RedAdj) else pom:=Min0R(cp,HP); + + if(Limpp>cp)then //podwyzszanie szybkie + cp:=cp+60*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt //zbiornik sterujacy + else + cp:=cp+13*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt; //zbiornik sterujacy + + Limpp:=pom; //cp + if EQ(i_bcp,-1) then + dpPipe:=HP + else + dpPipe:=Min0R(HP,Limpp); + + if dpPipe>pp then + dpMainValve:=-PFVa(HP,pp,ActFlowSpeed/(LBDelay),dpPipe,0.4) + else + dpMainValve:=PFVd(pp,0,ActFlowSpeed/(LBDelay),dpPipe,0.4); + + if EQ(i_bcp,-1) then + begin + if(tp<5)then tp:=tp+dt; //5/10 + if(tp<1)then tp:=tp-0.5*dt; //5/10 + end; + + if(EQ(i_bcp,10))or(EQ(i_bcp,-2))then + begin + dp:=PF(0,pp,2*(ActFlowSpeed)/(LBDelay)); + dpMainValve:=dp; + Sounds[s_fv4a_e]:=dp; + Sounds[s_fv4a_u]:=0; + Sounds[s_fv4a_b]:=0; + Sounds[s_fv4a_x]:=0; + end + else + begin + if dpMainValve>0 then + Sounds[s_fv4a_b]:=dpMainValve + else + Sounds[s_fv4a_u]:=-dpMainValve; + end; + + if (i_bcp<1.5) then + RP:=Max0R(0,0.125*i_bcp) + else + RP:=Min0R(1,0.125*i_bcp-0.125); + + GetPF:=dpMainValve*dt; +end; + +procedure TMHZ_EN57.Init(press: real); +begin + CP:= press; + TP:= 0; + RP:= 0; + Time:=false; + TimeEP:=false; +end; + +procedure TMHZ_EN57.SetReductor(nAdj: real); +begin + RedAdj:= nAdj; +end; + +function TMHZ_EN57.GetSound(i: byte): real; +begin + if i>4 then + GetSound:=0 + else + GetSound:=Sounds[i]; +end; + +function TMHZ_EN57.GetPos(i: byte): real; +const + table: array[0..10] of real = (-2,10,-1,0,0,2,9,10,0,0,0); +begin + GetPos:=table[i]; +end; + +function TMHZ_EN57.GetCP: real; +begin + GetCP:=RP; +end; + +function TMHZ_EN57.GetEP(pos: real): real; +begin + if pos<9.5 then + GetEP:=Min0R(Max0R(0,0.125*pos),1) + else + GetEP:=0; +end; + +//---M394--- Matrosow + +function TM394.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; +const + LBDelay = 65; +var + LimPP, dpPipe, dpMainValve, ActFlowSpeed: real; + bcp: integer; +begin + bcp:=Round(i_bcp); + if bcp<-1 then bcp:=1; + + Limpp:=Min0R(BPT_394[bcp][1],HP); + ActFlowSpeed:=BPT_394[bcp][0]; + if (bcp=1)or(bcp=i_bcpNo) then + Limpp:=pp; + if (bcp=0) then + Limpp:=Limpp+RedAdj; + if (bcp<>2) then + if cp3)+Byte(bcp>4))*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt; //zbiornik sterujacy + + Limpp:=cp; + dpPipe:=Min0R(HP,Limpp); + +// if(dpPipe>pp)then //napelnianie +// dpMainValve:=PF(dpPipe,pp,ActFlowSpeed/(LBDelay))*dt +// else //spuszczanie + dpMainValve:=PF(dpPipe,pp,ActFlowSpeed/(LBDelay))*dt; + + if bcp=-1 then +// begin + dpMainValve:=PF(HP,pp,(ActFlowSpeed)/(LBDelay))*dt; +// end; + + if bcp=i_bcpNo then +// begin + dpMainValve:=PF(0,pp,(ActFlowSpeed)/(LBDelay))*dt; +// end; + + GetPF:=dpMainValve; +end; + +procedure TM394.Init(press: real); +begin + CP:= press; + RedAdj:= 0; + Time:=true; + TimeEP:=false; +end; + +procedure TM394.SetReductor(nAdj: real); +begin + RedAdj:= nAdj; +end; + +function TM394.GetCP: real; +begin + GetCP:= CP; +end; + +function TM394.GetPos(i: byte): real; +const + table: array[0..10] of real = (-1,5,-1,0,1,2,4,5,0,0,0); +begin + GetPos:=table[i]; +end; + +//---H14K1-- Knorr + +function TH14K1.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; +const + LBDelay = 100; //szybkosc + zasilanie sterujacego + BPT_K: array[-1..4] of array [0..1] of real= ((10, 0), (4, 1), (0, 1), (4, 0), (4, -1), (15, -1)); + NomPress = 5.0; +var + LimPP, dpPipe, dpMainValve, ActFlowSpeed: real; + bcp: integer; +begin + bcp:=Round(i_bcp); + if i_bcp<-1 then bcp:=1; + Limpp:=BPT_K[bcp][1]; + if Limpp<0 then + Limpp:=0.5*pp + else if Limpp>0 then + Limpp:=pp + else + Limpp:=cp; + ActFlowSpeed:=BPT_K[bcp][0]; + + cp:=cp+6*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt; //zbiornik sterujacy + + dpMainValve:=0; + + if bcp=-1 then + dpMainValve:=PF(HP,pp,(ActFlowSpeed)/(LBDelay))*dt; + if(bcp=0)then + dpMainValve:=-PFVa(HP,pp,(ActFlowSpeed)/(LBDelay),NomPress+RedAdj)*dt; + if (bcp>1)and(pp>cp) then + dpMainValve:=PFVd(pp,0,(ActFlowSpeed)/(LBDelay),cp)*dt; + if bcp=i_bcpNo then + dpMainValve:=PF(0,pp,(ActFlowSpeed)/(LBDelay))*dt; + + GetPF:=dpMainValve; +end; + +procedure TH14K1.Init(press: real); +begin + CP:= press; + RedAdj:= 0; + Time:=true; + TimeEP:=true; +end; + +procedure TH14K1.SetReductor(nAdj: real); +begin + RedAdj:= nAdj; +end; + +function TH14K1.GetCP: real; +begin + GetCP:= CP; +end; + +function TH14K1.GetPos(i: byte): real; +const + table: array[0..10] of real = (-1,4,-1,0,1,2,3,4,0,0,0); +begin + GetPos:=table[i]; +end; + +//---St113-- Knorr EP + +function TSt113.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; +const + LBDelay = 100; //szybkosc + zasilanie sterujacego + BPT_K: array[-1..4] of array [0..1] of real= ((10, 0), (4, 1), (0, 1), (4, 0), (4, -1), (15, -1)); + BEP_K: array[-1..5] of real= (0, -1, 1, 0, 0, 0, 0); + NomPress = 5.0; +var + LimPP, dpPipe, dpMainValve, ActFlowSpeed: real; + bcp: integer; +begin + bcp:=Round(i_bcp); + + EPS:=BEP_K[bcp]; + + if bcp>0 then bcp:=bcp-1; + + if bcp<-1 then bcp:=1; + Limpp:=BPT_K[bcp][1]; + if Limpp<0 then + Limpp:=0.5*pp + else if Limpp>0 then + Limpp:=pp + else + Limpp:=cp; + ActFlowSpeed:=BPT_K[bcp][0]; + + cp:=cp+6*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt; //zbiornik sterujacy + + dpMainValve:=0; + + if bcp=-1 then + dpMainValve:=PF(HP,pp,(ActFlowSpeed)/(LBDelay))*dt; + if(bcp=0)then + dpMainValve:=-PFVa(HP,pp,(ActFlowSpeed)/(LBDelay),NomPress+RedAdj)*dt; + if (bcp>1)and(pp>cp) then + dpMainValve:=PFVd(pp,0,(ActFlowSpeed)/(LBDelay),cp)*dt; + if bcp=i_bcpNo then + dpMainValve:=PF(0,pp,(ActFlowSpeed)/(LBDelay))*dt; + + GetPF:=dpMainValve; +end; + +function TSt113.GetCP: real; +begin + GetCP:=EPS; +end; + +function TSt113.GetPos(i: byte): real; +const + table: array[0..10] of real = (-1,5,-1,0,2,3,4,5,0,0,1); +begin + GetPos:=table[i]; +end; + +procedure TSt113.Init(press: real); +begin + Time:=true; + TimeEP:=true; +end; + +//--- test --- + +function Ttest.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; +const + LBDelay = 100; +var + LimPP, dpPipe, dpMainValve, ActFlowSpeed: real; +begin + + Limpp:=BPT[Round(i_bcp)][1]; + ActFlowSpeed:=BPT[Round(i_bcp)][0]; + + if(i_bcp=i_bcpNo)then limpp:=0.0; + + if(i_bcp=-1)then limpp:=7; + + cp:=cp+20*Min0R(abs(Limpp-cp),0.05)*PR(cp,Limpp)*dt/1; + + Limpp:=cp; + dpPipe:=Min0R(HP,Limpp); + + dpMainValve:=PF(dpPipe,pp,ActFlowSpeed/(LBDelay))*dt; + + if(Round(i_bcp)=i_bcpNo)then + begin + dpMainValve:=PF(0,pp,(ActFlowSpeed)/(LBDelay))*dt; + end; + + GetPF:=dpMainValve; +end; + +procedure Ttest.Init(press: real); +begin + CP:= press; +end; + + +//---FD1--- + +function TFD1.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; +var dp, temp: real; +begin +// MaxBP:=4; +// temp:=Min0R(i_bcp*MaxBP,Min0R(5.0,HP)); + temp:=Min0R(i_bcp*MaxBP,HP); //0011 + dp:=10*Min0R(abs(temp-BP),0.1)*PF(temp,BP,0.0006*(2+Byte(temp>BP)))*dt*Speed; + BP:=BP-dp; + GetPF:=-dp; +end; + +procedure TFD1.Init(press: real); +begin + BP:=0; + MaxBP:=press; + Time:=false; + TimeEP:=false; + Speed:=1; +end; + +function TFD1.GetCP: real; +begin + GetCP:=BP; +end; + +procedure TFD1.SetSpeed(nSpeed: real); +begin + Speed:=nSpeed; +end; + + +//---KNORR--- + +function TH1405.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; +var dp, temp, A: real; +begin + pp:=Min0R(pp,MaxBP); + if i_bcp>0.5 then + begin + temp:=Min0R(MaxBP,HP); + A:=2*(i_bcp-0.5)*0.0011; + BP:=Max0R(BP,pp); + end + else + begin + temp:=0; + A:=0.2*(0.5-i_bcp)*0.0033; + BP:=Min0R(BP,pp); + end; + dp:=PF(temp,BP,A)*dt; + BP:=BP-dp; + GetPF:=-dp; +end; + +procedure TH1405.Init(press: real); +begin + BP:=0; + MaxBP:=press; + Time:=true; + TimeEP:=false; +end; + +function TH1405.GetCP: real; +begin + GetCP:=BP; +end; + + +//---FVel6--- + +function TFVel6.GetPF(i_bcp:real; pp, hp, dt, ep: real): real; +const + LBDelay = 100; +var + LimPP, dpPipe, dpMainValve, ActFlowSpeed: real; +begin + Limpp:=Min0R(5*Byte(i_bcp<3.5),hp); + if (i_bcp>=3.5) and ((i_bcp<4.3)or(i_bcp>5.5)) then + ActFlowSpeed:=0 + else if (i_bcp>4.3) and (i_bcp<4.8) then + ActFlowSpeed:=4*(i_bcp-4.3) //konsultacje wawa1 - bylo 8 + else if (i_bcp<4) then + ActFlowSpeed:=2 + else + ActFlowSpeed:=4; + dpMainValve:=PF(Limpp,pp,ActFlowSpeed/(LBDelay))*dt; + + + Sounds[s_fv4a_e]:=0; + Sounds[s_fv4a_u]:=0; + Sounds[s_fv4a_b]:=0; + if(i_bcp<3.5)then Sounds[s_fv4a_u]:=-dpMainValve else + if(i_bcp<4.8)then Sounds[s_fv4a_b]:=dpMainValve else + if(i_bcp<5.5)then Sounds[s_fv4a_e]:=dpMainValve; + + GetPF:=dpMainValve; + if(i_bcp<-0.5)then + EPS:=-1 + else if(i_bcp>0.5)and(i_bcp<4.7)then + EPS:=1 + else + EPS:=0; +// EPS:=i_bcp*Byte(i_bcp<2) +end; + +function TFVel6.GetCP: real; +begin + GetCP:=EPS; +end; + +function TFVel6.GetPos(i: byte): real; +const + table: array[0..10] of real = (-1,6,-1,0,6,4,4.7,5,-1,0,1); +begin + GetPos:=table[i]; +end; + +function TFVel6.GetSound(i: byte): real; +begin + if i>2 then + GetSound:=0 + else + GetSound:=Sounds[i]; +end; + +procedure TFVel6.Init(press: real); +begin + Time:=true; + TimeEP:=true; +end; + +end. + + diff --git a/MdlMngr.cpp b/MdlMngr.cpp index 9e1914241..1a97380ff 100644 --- a/MdlMngr.cpp +++ b/MdlMngr.cpp @@ -23,7 +23,7 @@ obtain one at #define SeekFiles AnsiString("*.t3d") -TModel3d *__fastcall TMdlContainer::LoadModel(char *newName, bool dynamic) +TModel3d * TMdlContainer::LoadModel(char *newName, bool dynamic) { // wczytanie modelu do kontenerka SafeDeleteArray(Name); SafeDelete(Model); @@ -45,14 +45,14 @@ void TModelsManager::Init() Count = 0; } /* -__fastcall TModelsManager::TModelsManager() + TModelsManager::TModelsManager() { // Models= NULL; Models= new TMdlContainer[MAX_MODELS]; Count= 0; }; -__fastcall TModelsManager::~TModelsManager() + TModelsManager::~TModelsManager() { Free(); }; @@ -62,7 +62,7 @@ void TModelsManager::Free() SafeDeleteArray(Models); } -TModel3d *__fastcall TModelsManager::LoadModel(char *Name, bool dynamic) +TModel3d * TModelsManager::LoadModel(char *Name, bool dynamic) { // wczytanie modelu do tablicy TModel3d *mdl = NULL; if (Count >= MAX_MODELS) @@ -76,7 +76,7 @@ TModel3d *__fastcall TModelsManager::LoadModel(char *Name, bool dynamic) return mdl; } -TModel3d *__fastcall TModelsManager::GetModel(const char *Name, bool dynamic) +TModel3d * TModelsManager::GetModel(const char *Name, bool dynamic) { // model może być we wpisie "node...model" albo "node...dynamic", a także być dodatkowym w dynamic // (kabina, wnętrze, ładunek) // dla "node...dynamic" mamy podaną ścieżkę w "\dynamic\" i musi być co najmniej 1 poziom, zwkle diff --git a/MdlMngr.h b/MdlMngr.h index 25665aca1..9ff23adf1 100644 --- a/MdlMngr.h +++ b/MdlMngr.h @@ -25,7 +25,7 @@ class TMdlContainer SafeDeleteArray(Name); SafeDelete(Model); }; - TModel3d *__fastcall LoadModel(char *newName, bool dynamic); + TModel3d * LoadModel(char *newName, bool dynamic); TModel3d *Model; char *Name; }; @@ -35,7 +35,7 @@ class TModelsManager private: static TMdlContainer *Models; static int Count; - static TModel3d *__fastcall LoadModel(char *Name, bool dynamic); + static TModel3d * LoadModel(char *Name, bool dynamic); public: // TModelsManager(); @@ -43,7 +43,7 @@ class TModelsManager static void Init(); static void Free(); // McZapkie: dodalem sciezke, notabene Path!=Patch :) - static TModel3d *__fastcall GetModel(const char *Name, bool dynamic = false); + static TModel3d * GetModel(const char *Name, bool dynamic = false); }; //--------------------------------------------------------------------------- #endif diff --git a/MemCell.h b/MemCell.h index caef4d94c..8a6bc4f2a 100644 --- a/MemCell.h +++ b/MemCell.h @@ -35,7 +35,7 @@ class TMemCell void PutCommand(TController *Mech, vector3 *Loc); bool Compare(char *szTestText, double fTestValue1, double fTestValue2, int CheckMask); bool Render(); - inline char *__fastcall Text() + inline char * Text() { return szText; }; diff --git a/Model3d.cpp b/Model3d.cpp index 435b6fddd..0b61040d1 100644 --- a/Model3d.cpp +++ b/Model3d.cpp @@ -91,7 +91,8 @@ void TSubModel::FirstInit() Child = NULL; TextureID = 0; // TexAlpha=false; - iFlags = 0x0200; // bit 9=1: submodel został utworzony a nie ustawiony na wczytany plik + iFlags = 0x0200; // bit 9=1: submodel został utworzony a nie ustawiony na + // wczytany plik // TexHash=false; // Hits=NULL; // CollisionPts=NULL; @@ -137,15 +138,17 @@ TSubModel::~TSubModel() delete[] pName; } /* - else - {//wczytano z pliku binarnego (nie jest właścicielem tablic) - } + else + {//wczytano z pliku binarnego (nie jest właścicielem tablic) + } */ - delete[] smLetter; // używany tylko roboczo dla TP_TEXT, do przyspieszenia wyświetlania + delete[] smLetter; // używany tylko roboczo dla TP_TEXT, do przyspieszenia + // wyświetlania }; void TSubModel::TextureNameSet(const char *n) -{ // ustawienie nazwy submodelu, o ile nie jest wczytany z E3D +{ // ustawienie nazwy submodelu, o + // ile nie jest wczytany z E3D if (iFlags & 0x0200) { // tylko jeżeli submodel zosta utworzony przez new delete[] pTexture; // usunięcie poprzedniej @@ -161,7 +164,8 @@ void TSubModel::TextureNameSet(const char *n) }; void TSubModel::NameSet(const char *n) -{ // ustawienie nazwy submodelu, o ile nie jest wczytany z E3D +{ // ustawienie nazwy submodelu, o ile + // nie jest wczytany z E3D if (iFlags & 0x0200) { // tylko jeżeli submodel zosta utworzony przez new delete[] pName; // usunięcie poprzedniej @@ -176,10 +180,13 @@ void TSubModel::NameSet(const char *n) } }; -// int TSubModel::SeekFaceNormal(DWORD *Masks, int f,DWORD dwMask,vector3 *pt,GLVERTEX +// int TSubModel::SeekFaceNormal(DWORD *Masks, int f,DWORD dwMask,vector3 +// *pt,GLVERTEX // *Vertices) int TSubModel::SeekFaceNormal(DWORD *Masks, int f, DWORD dwMask, float3 *pt, float8 *Vertices) -{ // szukanie punktu stycznego do (pt), zwraca numer wierzchołka, a nie trójkąta +{ // szukanie punktu stycznego + // do (pt), zwraca numer + // wierzchołka, a nie trójkąta int iNumFaces = iNumVerts / 3; // bo maska powierzchni jest jedna na trójkąt // GLVERTEX *p; //roboczy wskaźnik float8 *p; // roboczy wskaźnik @@ -269,13 +276,16 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) parser >> token; NameSet(token.c_str()); if (dynamic) - { // dla pojazdu, blokujemy załączone submodele, które mogą być nieobsługiwane + { // dla pojazdu, blokujemy załączone submodele, które mogą być + // nieobsługiwane if (token.find("_on") + 3 == token.length()) // jeśli nazwa kończy się na "_on" iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z obiektem "_off" } - else // dla pozostałych modeli blokujemy zapalone światła, które mogą być nieobsługiwane + else // dla pozostałych modeli blokujemy zapalone światła, które mogą być + // nieobsługiwane if (token.find("Light_On") == 0) // jeśli nazwa zaczyna się od "Light_On" - iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z obiektem "Light_Off" + iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z obiektem + // "Light_Off" if (parser.expectToken("anim:")) // Ra: ta informacja by się przydała! { // rodzaj animacji @@ -358,7 +368,8 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) parser.getToken(fCosHotspotAngle); // kąt liczony dla średnicy, a nie promienia fCosHotspotAngle = cos(DegToRad(0.5 * fCosHotspotAngle)); iNumVerts = 1; - iFlags |= 0x4010; // rysowane w cyklu nieprzezroczystych, macierz musi zostać bez zmiany + iFlags |= 0x4010; // rysowane w cyklu nieprzezroczystych, macierz musi + // zostać bez zmiany } else if (eType < TP_ROTATOR) { @@ -417,7 +428,8 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) szTexturePath, Global::asCurrentTexturePath.c_str(), texture); // TexAlpha=TTexturesManager::GetAlpha(TextureID); // iFlags|=TexAlpha?0x20:0x10; //0x10-nieprzezroczysta, 0x20-przezroczysta - if (Opacity < 1.0) // przezroczystość z tekstury brana tylko dla Opacity 0! + if (Opacity < 1.0) // przezroczystość z tekstury brana tylko dla Opacity + // 0! iFlags |= TTexturesManager::GetAlpha(TextureID) ? 0x20 : 0x10; // 0x10-nieprzezroczysta, 0x20-przezroczysta @@ -449,15 +461,17 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) if (eType < TP_ROTATOR) { // wczytywanie wierzchołków parser.ignoreToken(); - // Ra 15-01: to wczytać jako tekst - jeśli pierwszy znak zawiera "*", to dalej będzie nazwa - // wcześniejszego submodelu, z którego należy wziąć wierzchołki - // zapewni to jakąś zgodność wstecz, bo zamiast liczby będzie ciąg, którego wartość powinna - // być uznana jako zerowa + // Ra 15-01: to wczytać jako tekst - jeśli pierwszy znak zawiera "*", to + // dalej będzie nazwa wcześniejszego submodelu, z którego należy wziąć + // wierzchołki + // zapewni to jakąś zgodność wstecz, bo zamiast liczby będzie ciąg, którego + // wartość powinna być uznana jako zerowa // parser.getToken(iNumVerts); parser.getToken(token); if (token[0] == '*') - { // jeśli pierwszy znak jest gwiazdką, poszukać submodelu o nazwie bez tej gwiazdki i wziąć - // z niego wierzchołki + { // jeśli pierwszy znak jest gwiazdką, poszukać + // submodelu o nazwie bez tej gwiazdki i wziąć z + // niego wierzchołki Error("Verticles reference not yet supported!"); } else @@ -474,19 +488,23 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) { Vertices = new float8[iNumVerts]; iNumFaces = iNumVerts / 3; - sg = new DWORD[iNumFaces]; // maski powierzchni: 0 oznacza brak użredniania wektorów - // normalnych - int *wsp = new int[iNumVerts]; // z którego wierzchołka kopiować wektor normalny + sg = new DWORD[iNumFaces]; // maski powierzchni: 0 oznacza brak + // użredniania wektorów normalnych + int *wsp = new int[iNumVerts]; // z którego wierzchołka kopiować wektor + // normalny int maska = 0; for (int i = 0; i < iNumVerts; i++) - { // Ra: z konwersją na układ scenerii - będzie wydajniejsze wyświetlanie + { // Ra: z konwersją na układ scenerii - będzie wydajniejsze + // wyświetlanie wsp[i] = -1; // wektory normalne nie są policzone dla tego wierzchołka if ((i % 3) == 0) - { // jeśli będzie maska -1, to dalej będą wierzchołki z wektorami normalnymi, - // podanymi jawnie + { // jeśli będzie maska -1, to dalej będą + // wierzchołki z wektorami normalnymi, podanymi + // jawnie parser.getToken(maska); // maska powierzchni trójkąta - sg[i / 3] = (maska == -1) ? 0 : maska; // dla maski -1 będzie 0, czyli nie - // ma wspólnych wektorów normalnych + sg[i / 3] = (maska == -1) ? 0 : maska; // dla maski -1 będzie 0, + // czyli nie ma wspólnych + // wektorów normalnych } parser.getToken(Vertices[i].Point.x); parser.getToken(Vertices[i].Point.y); @@ -512,15 +530,15 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) WriteLog(AnsiString("Degenerated triangle ignored in: \"") + AnsiString(pName) + "\", verticle " + AnsiString(i)); } - if (i > 0) // jeśli pierwszy trójkąt będzie zdegenerowany, to zostanie - // usunięty i nie ma co sprawdzać + if (i > 0) // jeśli pierwszy trójkąt będzie zdegenerowany, to + // zostanie usunięty i nie ma co sprawdzać if (((Vertices[i].Point - Vertices[i - 1].Point).Length() > 1000.0) || ((Vertices[i - 1].Point - Vertices[i - 2].Point).Length() > 1000.0) || ((Vertices[i - 2].Point - Vertices[i].Point).Length() > 1000.0)) - { // jeżeli są dalej niż 2km od siebie //Ra 15-01: obiekt wstawiany nie - // powinien być większy niż 300m (trójkąty terenu w E3D mogą mieć - // 1.5km) + { // jeżeli są dalej niż 2km od siebie //Ra 15-01: + // obiekt wstawiany nie powinien być większy niż + // 300m (trójkąty terenu w E3D mogą mieć 1.5km) --iNumFaces; // o jeden trójkąt mniej iNumVerts -= 3; // czyli o 3 wierzchołki i -= 3; // wczytanie kolejnego w to miejsce @@ -531,8 +549,9 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) } int i; // indeks dla trójkątów float3 *n = new float3[iNumFaces]; // tablica wektorów normalnych dla trójkątów - for (i = 0; i < iNumFaces; i++) // pętla po trójkątach - będzie szybciej, jak - // wstępnie przeliczymy normalne trójkątów + for (i = 0; i < iNumFaces; i++) // pętla po trójkątach - będzie + // szybciej, jak wstępnie przeliczymy + // normalne trójkątów n[i] = SafeNormalize( CrossProduct(Vertices[i * 3].Point - Vertices[i * 3 + 1].Point, Vertices[i * 3].Point - Vertices[i * 3 + 2].Point)); @@ -541,8 +560,8 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) float3 norm; // roboczy wektor normalny for (v = 0; v < iNumVerts; v++) { // pętla po wierzchołkach trójkątów - if (wsp[v] >= - 0) // jeśli już był liczony wektor normalny z użyciem tego wierzchołka + if (wsp[v] >= 0) // jeśli już był liczony wektor normalny z użyciem + // tego wierzchołka Vertices[v].Normal = Vertices[wsp[v]].Normal; // to wystarczy skopiować policzony wcześniej else @@ -551,15 +570,16 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) norm = float3(0, 0, 0); // liczenie zaczynamy od zera f = v; // zaczynamy dodawanie wektorów normalnych od własnego while (f >= 0) - { // sumowanie z wektorem normalnym sąsiada (włącznie ze sobą) + { // sumowanie z wektorem normalnym sąsiada (włącznie + // ze sobą) wsp[f] = v; // informacja, że w tym wierzchołku jest już policzony // wektor normalny norm += n[f / 3]; f = SeekFaceNormal(sg, f / 3 + 1, sg[i], &Vertices[v].Point, Vertices); // i szukanie od kolejnego trójkąta } - // Ra 15-01: należało by jeszcze uwzględnić skalowanie wprowadzane przez - // transformy, aby normalne po przeskalowaniu były jednostkowe + // Ra 15-01: należało by jeszcze uwzględnić skalowanie wprowadzane + // przez transformy, aby normalne po przeskalowaniu były jednostkowe Vertices[v].Normal = SafeNormalize(norm); // przepisanie do wierzchołka trójkąta } @@ -576,7 +596,8 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) } // obsługa submodelu z własną listą wierzchołków } else if (eType == TP_STARS) - { // punkty świecące dookólnie - składnia jak dla smt_Mesh + { // punkty świecące dookólnie - składnia jak + // dla smt_Mesh parser.ignoreToken(); parser.getToken(iNumVerts); // Vertices=new GLVERTEX[iNumVerts]; @@ -604,7 +625,8 @@ int TSubModel::Load(cParser &parser, TModel3d *Model, int Pos, bool dynamic) }; int TSubModel::TriangleAdd(TModel3d *m, int tex, int tri) -{ // dodanie trójkątów do submodelu, używane przy tworzeniu E3D terenu +{ // dodanie trójkątów do submodelu, używane + // przy tworzeniu E3D terenu TSubModel *s = this; while (s ? (s->TextureID != tex) : false) { // szukanie submodelu o danej teksturze @@ -635,8 +657,9 @@ int TSubModel::TriangleAdd(TModel3d *m, int tex, int tri) return s->iNumVerts - tri; // zwraca pozycję tych trójkątów w submodelu }; -float8 *__fastcall TSubModel::TrianglePtr(int tex, int pos, int *la, int *ld, int *ls) -{ // zwraca wskaźnik do wypełnienia tabeli wierzchołków, używane przy tworzeniu E3D terenu +float8 * TSubModel::TrianglePtr(int tex, int pos, int *la, int *ld, int *ls) +{ // zwraca wskaźnik do wypełnienia tabeli wierzchołków, używane + // przy tworzeniu E3D terenu TSubModel *s = this; while (s ? s->TextureID != tex : false) { // szukanie submodelu o danej teksturze @@ -660,7 +683,8 @@ float8 *__fastcall TSubModel::TrianglePtr(int tex, int pos, int *la, int *ld, in }; void TSubModel::DisplayLists() -{ // utworznie po jednej skompilowanej liście dla każdego submodelu +{ // utworznie po jednej skompilowanej liście dla + // każdego submodelu if (Global::bUseVBO) return; // Ra: przy VBO to się nie przyda // iFlags|=0x4000; //wyłączenie przeliczania wierzchołków, bo nie są zachowane @@ -682,9 +706,9 @@ void TSubModel::DisplayLists() for (int i = 0; i < iNumVerts; i++) { /* - glNormal3dv(&Vertices[i].Normal.x); - glTexCoord2f(Vertices[i].tu,Vertices[i].tv); - glVertex3dv(&Vertices[i].Point.x); + glNormal3dv(&Vertices[i].Normal.x); + glTexCoord2f(Vertices[i].tu,Vertices[i].tv); + glVertex3dv(&Vertices[i].Point.x); */ glNormal3fv(&Vertices[i].Normal.x); glTexCoord2f(Vertices[i].tu, Vertices[i].tv); @@ -738,7 +762,8 @@ void TSubModel::DisplayLists() glMaterialfv(GL_FRONT, GL_EMISSION, emm2); glEndList(); } - // SafeDeleteArray(Vertices); //przy VBO muszą zostać do załadowania całego modelu + // SafeDeleteArray(Vertices); //przy VBO muszą zostać do załadowania całego + // modelu if (Child) Child->DisplayLists(); if (Next) @@ -762,11 +787,12 @@ void TSubModel::InitialRotate(bool doit) iFlags &= ~0x8000; // jednak jednostkowa po obróceniu } if (Child) - Child->InitialRotate( - false); // potomnych nie obracamy już, tylko ewentualnie optymalizujemy + Child->InitialRotate(false); // potomnych nie obracamy już, tylko + // ewentualnie optymalizujemy else if (Global::iConvertModels & 2) // optymalizacja jest opcjonalna if ((iFlags & 0xC000) == 0x8000) // o ile nie ma animacji - { // jak nie ma potomnych, można wymnożyć przez transform i wyjedynkować go + { // jak nie ma potomnych, można wymnożyć przez transform i wyjedynkować + // go float4x4 *mat = GetMatrix(); // transform submodelu if (Vertices) { @@ -774,8 +800,8 @@ void TSubModel::InitialRotate(bool doit) Vertices[i].Point = (*mat) * Vertices[i].Point; (*mat)(3)[0] = (*mat)(3)[1] = (*mat)(3)[2] = 0.0; // zerujemy przesunięcie przed obracaniem normalnych - if (eType != TP_STARS) // gwiazdki mają kolory zamiast normalnych, to ich wtedy - // nie ruszamy + if (eType != TP_STARS) // gwiazdki mają kolory zamiast normalnych, to + // ich wtedy nie ruszamy for (int i = 0; i < iNumVerts; ++i) Vertices[i].Normal = SafeNormalize((*mat) * Vertices[i].Normal); } @@ -785,7 +811,8 @@ void TSubModel::InitialRotate(bool doit) } else // jak jest jednostkowy i nie ma animacji if (doit) - { // jeśli jest jednostkowy transform, to przeliczamy wierzchołki, a mnożenie podajemy dalej + { // jeśli jest jednostkowy transform, to przeliczamy + // wierzchołki, a mnożenie podajemy dalej double t; if (Vertices) for (int i = 0; i < iNumVerts; ++i) @@ -809,7 +836,8 @@ void TSubModel::InitialRotate(bool doit) void TSubModel::ChildAdd(TSubModel *SubModel) { // dodanie submodelu potemnego (uzależnionego) - // Ra: zmiana kolejności, żeby kolejne móc renderować po aktualnym (było przed) + // Ra: zmiana kolejności, żeby kolejne móc renderować po aktualnym (było + // przed) if (SubModel) SubModel->NextAdd(Child); // Ra: zmiana kolejności renderowania Child = SubModel; @@ -826,7 +854,8 @@ void TSubModel::NextAdd(TSubModel *SubModel) int TSubModel::FlagsCheck() { // analiza koniecznych zmian pomiędzy submodelami // samo pomijanie glBindTexture() nie poprawi wydajności - // ale można sprawdzić, czy można w ogóle pominąć kod do tekstur (sprawdzanie replaceskin) + // ale można sprawdzić, czy można w ogóle pominąć kod do tekstur (sprawdzanie + // replaceskin) int i; if (Child) { // Child jest renderowany po danym submodelu @@ -836,7 +865,8 @@ int TSubModel::FlagsCheck() i = Child->FlagsCheck(); iFlags |= 0x00FF0000 & ((i << 16) | (i) | (i >> 8)); // potomny, rodzeństwo i dzieci if (eType == TP_TEXT) - { // wyłączenie renderowania Next dla znaków wyświetlacza tekstowego + { // wyłączenie renderowania Next dla znaków + // wyświetlacza tekstowego TSubModel *p = Child; while (p) { @@ -846,21 +876,23 @@ int TSubModel::FlagsCheck() } } if (Next) - { // Next jest renderowany po danym submodelu (kolejność odwrócona po wczytaniu T3D) + { // Next jest renderowany po danym submodelu (kolejność odwrócona + // po wczytaniu T3D) if (TextureID) // o ile dany ma teksturę if ((TextureID != Next->TextureID) || (i & 0x00800000)) // a ma inną albo dzieci zmieniają iFlags |= 0x80; // to dany submodel musi sobie ją ustawiać i = Next->FlagsCheck(); iFlags |= 0xFF000000 & ((i << 24) | (i << 8) | (i)); // następny, kolejne i ich dzieci - // tekstury nie ustawiamy tylko wtedy, gdy jest taka sama jak Next i jego dzieci nie - // zmieniają + // tekstury nie ustawiamy tylko wtedy, gdy jest taka sama jak Next i jego + // dzieci nie zmieniają } return iFlags; }; void TSubModel::SetRotate(float3 vNewRotateAxis, float fNewAngle) -{ // obrócenie submodelu wg podanej osi (np. wskazówki w kabinie) +{ // obrócenie submodelu wg podanej + // osi (np. wskazówki w kabinie) v_RotateAxis = vNewRotateAxis; f_Angle = fNewAngle; if (fNewAngle != 0.0) @@ -872,7 +904,9 @@ void TSubModel::SetRotate(float3 vNewRotateAxis, float fNewAngle) } void TSubModel::SetRotateXYZ(float3 vNewAngles) -{ // obrócenie submodelu o podane kąty wokół osi lokalnego układu +{ // obrócenie submodelu o + // podane kąty wokół osi + // lokalnego układu v_Angles = vNewAngles; b_Anim = at_RotateXYZ; b_aAnim = at_RotateXYZ; @@ -880,7 +914,9 @@ void TSubModel::SetRotateXYZ(float3 vNewAngles) } void TSubModel::SetRotateXYZ(vector3 vNewAngles) -{ // obrócenie submodelu o podane kąty wokół osi lokalnego układu +{ // obrócenie submodelu o + // podane kąty wokół osi + // lokalnego układu v_Angles.x = vNewAngles.x; v_Angles.y = vNewAngles.y; v_Angles.z = vNewAngles.z; @@ -908,7 +944,9 @@ void TSubModel::SetTranslate(vector3 vNewTransVector) } void TSubModel::SetRotateIK1(float3 vNewAngles) -{ // obrócenie submodelu o podane kąty wokół osi lokalnego układu +{ // obrócenie submodelu o + // podane kąty wokół osi + // lokalnego układu v_Angles = vNewAngles; iAnimOwner = iInstance; // zapamiętanie czyja jest animacja } @@ -921,12 +959,12 @@ struct ToLower } }; -TSubModel *__fastcall TSubModel::GetFromName(AnsiString search, bool i) +TSubModel * TSubModel::GetFromName(AnsiString search, bool i) { return GetFromName(search.c_str(), i); }; -TSubModel *__fastcall TSubModel::GetFromName(char *search, bool i) +TSubModel * TSubModel::GetFromName(char *search, bool i) { TSubModel *result; // std::transform(search.begin(),search.end(),search.begin(),ToLower()); @@ -1004,13 +1042,14 @@ void TSubModel::RaAnimation(TAnimType a) break; case at_Billboard: // obrót w pionie do kamery { - matrix4x4 mat; // potrzebujemy współrzędne przesunięcia środka układu współrzędnych - // submodelu + matrix4x4 mat; // potrzebujemy współrzędne przesunięcia środka układu + // współrzędnych submodelu glGetDoublev(GL_MODELVIEW_MATRIX, mat.getArray()); // pobranie aktualnej matrycy float3 gdzie = float3(mat[3][0], mat[3][1], mat[3][2]); // początek układu współrzędnych submodelu względem kamery glLoadIdentity(); // macierz jedynkowa - glTranslatef(gdzie.x, gdzie.y, gdzie.z); // początek układu zostaje bez zmian + glTranslatef(gdzie.x, gdzie.y, gdzie.z); // początek układu zostaje bez + // zmian glRotated(atan2(gdzie.x, gdzie.z) * 180.0 / M_PI, 0.0, 1.0, 0.0); // jedynie obracamy w pionie o kąt } @@ -1024,7 +1063,8 @@ void TSubModel::RaAnimation(TAnimType a) glRotated(-fmod(Global::fTimeAngleDeg, 360.0), 0.0, 1.0, 0.0); // obrót dobowy osi OX break; case at_IK11: // ostatni element animacji szkieletowej (podudzie, stopa) - glRotatef(v_Angles.z, 0.0, 1.0, 0.0); // obrót względem osi pionowej (azymut) + glRotatef(v_Angles.z, 0.0, 1.0, 0.0); // obrót względem osi pionowej + // (azymut) glRotatef(v_Angles.x, 1.0, 0.0, 0.0); // obrót względem poziomu (deklinacja) break; case at_DigiClk: // animacja zegara cyfrowego @@ -1034,9 +1074,10 @@ void TSubModel::RaAnimation(TAnimType a) { // pętla po submodelach potomnych i obracanie ich o kąt zależy od czasu if (sm->pName) { // musi mieć niepustą nazwę - if ((*sm->pName) >= '0') - if ((*sm->pName) <= '5') // zegarek ma 6 cyfr maksymalnie - sm->SetRotate(float3(0, 1, 0), -Global::fClockAngleDeg[(*sm->pName) - '0']); + if ((sm->pName[0]) >= '0') + if ((sm->pName[0]) <= '5') // zegarek ma 6 cyfr maksymalnie + sm->SetRotate(float3(0, 1, 0), + -Global::fClockAngleDeg[(sm->pName[0]) - '0']); } sm = sm->NextGet(); } while (sm); @@ -1093,8 +1134,8 @@ void TSubModel::RenderDL() if (fCosViewAngle > fCosFalloffAngle) // kąt większy niż maksymalny stożek swiatła { double Distdimm = 1.0; - if (fCosViewAngle < fCosHotspotAngle) // zmniejszona jasność między Hotspot a - // Falloff + if (fCosViewAngle < + fCosHotspotAngle) // zmniejszona jasność między Hotspot a Falloff if (fCosFalloffAngle < fCosHotspotAngle) Distdimm = 1.0 - (fCosHotspotAngle - fCosViewAngle) / @@ -1102,20 +1143,21 @@ void TSubModel::RenderDL() glColor3f(f4Diffuse[0] * Distdimm, f4Diffuse[1] * Distdimm, f4Diffuse[2] * Distdimm); /* TODO: poprawic to zeby dzialalo - if (iFarAttenDecay>0) - switch (iFarAttenDecay) - { - case 1: - Distdimm=fFarDecayRadius/(1+sqrt(fSquareDist)); //dorobic od - kata - break; - case 2: - Distdimm=fFarDecayRadius/(1+fSquareDist); //dorobic od kata - break; - } - if (Distdimm>1) - Distdimm=1; - glColor3f(Diffuse[0]*Distdimm,Diffuse[1]*Distdimm,Diffuse[2]*Distdimm); + if (iFarAttenDecay>0) + switch (iFarAttenDecay) + { + case 1: + Distdimm=fFarDecayRadius/(1+sqrt(fSquareDist)); + //dorobic od kata + break; + case 2: + Distdimm=fFarDecayRadius/(1+fSquareDist); + //dorobic od kata + break; + } + if (Distdimm>1) + Distdimm=1; + glColor3f(Diffuse[0]*Distdimm,Diffuse[1]*Distdimm,Diffuse[2]*Distdimm); */ // glPopMatrix(); // return; @@ -1124,7 +1166,8 @@ void TSubModel::RenderDL() } else if (eType == TP_STARS) { - // glDisable(GL_LIGHTING); //Tolaris-030603: bo mu punkty swiecace sie blendowaly + // glDisable(GL_LIGHTING); //Tolaris-030603: bo mu punkty swiecace sie + // blendowaly if (Global::fLuminance < fLight) { glMaterialfv(GL_FRONT, GL_EMISSION, f4Diffuse); // zeby swiecilo na kolorowo @@ -1184,12 +1227,14 @@ void TSubModel::RenderAlphaDL() } if (Child != NULL) if (eType == TP_TEXT) - { // tekst renderujemy w specjalny sposób, zamiast submodeli z łańcucha Child + { // tekst renderujemy w specjalny sposób, zamiast + // submodeli z łańcucha Child int i, j = pasText->Length(); TSubModel *p; char c; if (!smLetter) - { // jeśli nie ma tablicy, to ją stworzyć; miejsce nieodpowiednie, ale tymczasowo + { // jeśli nie ma tablicy, to ją stworzyć; miejsce + // nieodpowiednie, ale tymczasowo // może być smLetter = new TSubModel *[256]; // tablica wskaźników submodeli dla // wyświetlania tekstu @@ -1248,7 +1293,8 @@ void TSubModel::RenderVBO() else glBindTexture(GL_TEXTURE_2D, TextureID); // również 0 glColor3fv(f4Diffuse); // McZapkie-240702: zamiast ub - // glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,f4Diffuse); //to samo, co glColor + // glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,f4Diffuse); //to samo, + // co glColor if (Global::fLuminance < fLight) { glMaterialfv(GL_FRONT, GL_EMISSION, f4Diffuse); // zeby swiecilo na kolorowo @@ -1271,8 +1317,8 @@ void TSubModel::RenderVBO() if (fCosViewAngle > fCosFalloffAngle) // kąt większy niż maksymalny stożek swiatła { double Distdimm = 1.0; - if (fCosViewAngle < fCosHotspotAngle) // zmniejszona jasność między Hotspot a - // Falloff + if (fCosViewAngle < + fCosHotspotAngle) // zmniejszona jasność między Hotspot a Falloff if (fCosFalloffAngle < fCosHotspotAngle) Distdimm = 1.0 - (fCosHotspotAngle - fCosViewAngle) / @@ -1280,30 +1326,36 @@ void TSubModel::RenderVBO() /* TODO: poprawic to zeby dzialalo - 2- Inverse (Applies inverse decay. The formula is luminance=R0/R, where R0 is - the radial source of the light if no attenuation is used, or the Near End - value of the light if Attenuation is used. R is the radial distance of the - illuminated surface from R0.) + 2- Inverse (Applies inverse decay. The formula is luminance=R0/R, where + R0 is + the radial source of the light if no attenuation is + used, or the Near End + value of the light if Attenuation is used. R is the + radial distance of the + illuminated surface from R0.) - 3- Inverse Square (Applies inverse-square decay. The formula for this is (R0/R)^2. - This is actually the "real-world" decay of light, but you might find it too dim - in the world of computer graphics.) + 3- Inverse Square (Applies inverse-square decay. The formula for this is + (R0/R)^2. + This is actually the "real-world" decay of light, but + you might find it too dim + in the world of computer graphics.) .DecayRadius -- The distance over which the decay occurs. - if (iFarAttenDecay>0) - switch (iFarAttenDecay) - { - case 1: - Distdimm=fFarDecayRadius/(1+sqrt(fSquareDist)); //dorobic od - kata - break; - case 2: - Distdimm=fFarDecayRadius/(1+fSquareDist); //dorobic od kata - break; - } - if (Distdimm>1) - Distdimm=1; + if (iFarAttenDecay>0) + switch (iFarAttenDecay) + { + case 1: + Distdimm=fFarDecayRadius/(1+sqrt(fSquareDist)); + //dorobic od kata + break; + case 2: + Distdimm=fFarDecayRadius/(1+fSquareDist); + //dorobic od kata + break; + } + if (Distdimm>1) + Distdimm=1; */ glBindTexture(GL_TEXTURE_2D, 0); // nie teksturować @@ -1313,10 +1365,12 @@ void TSubModel::RenderVBO() f4Diffuse[2] * Distdimm, 0}; // glColor3f(f4Diffuse[0]*Distdimm,f4Diffuse[1]*Distdimm,f4Diffuse[2]*Distdimm); glColorMaterial(GL_FRONT, GL_EMISSION); - glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly + glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie + // blendowaly glColor3fv(color); // inaczej są białe glMaterialfv(GL_FRONT, GL_EMISSION, color); - glDrawArrays(GL_POINTS, iVboPtr, iNumVerts); // narysuj wierzchołek z VBO + glDrawArrays(GL_POINTS, iVboPtr, iNumVerts); // narysuj wierzchołek z + // VBO glEnable(GL_LIGHTING); glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // co ma ustawiać glColor glMaterialfv(GL_FRONT, GL_EMISSION, emm2); // bez tego słupy się świecą @@ -1324,16 +1378,21 @@ void TSubModel::RenderVBO() } else if (eType == TP_STARS) { - // glDisable(GL_LIGHTING); //Tolaris-030603: bo mu punkty swiecace sie blendowaly + // glDisable(GL_LIGHTING); //Tolaris-030603: bo mu punkty swiecace sie + // blendowaly if (Global::fLuminance < fLight) - { // Ra: pewnie można by to zrobić lepiej, bez powtarzania StartVBO() + { // Ra: pewnie można by to zrobić + // lepiej, bez powtarzania StartVBO() pRoot->EndVBO(); // Ra: to też nie jest zbyt ładne if (pRoot->StartColorVBO()) - { // wyświetlanie kolorowych punktów zamiast trójkątów + { // wyświetlanie kolorowych punktów zamiast + // trójkątów glBindTexture(GL_TEXTURE_2D, 0); // tekstury nie ma glColorMaterial(GL_FRONT, GL_EMISSION); - glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly - // glMaterialfv(GL_FRONT,GL_EMISSION,f4Diffuse); //zeby swiecilo na kolorowo + glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie + // blendowaly + // glMaterialfv(GL_FRONT,GL_EMISSION,f4Diffuse); //zeby swiecilo na + // kolorowo glDrawArrays(GL_POINTS, iVboPtr, iNumVerts); // narysuj naraz wszystkie punkty z VBO glEnable(GL_LIGHTING); @@ -1345,9 +1404,9 @@ void TSubModel::RenderVBO() } } /*Ra: tu coś jest bez sensu... - else - { - glBindTexture(GL_TEXTURE_2D, 0); + else + { + glBindTexture(GL_TEXTURE_2D, 0); // if (eType==smt_FreeSpotLight) // { // if (iFarAttenDecay==0) @@ -1355,18 +1414,20 @@ void TSubModel::RenderVBO() // } // else //TODO: poprawic zeby dzialalo - glColor3f(f4Diffuse[0],f4Diffuse[1],f4Diffuse[2]); - glColorMaterial(GL_FRONT,GL_EMISSION); - glDisable(GL_LIGHTING); //Tolaris-030603: bo mu punkty swiecace sie blendowaly - //glBegin(GL_POINTS); - glDrawArrays(GL_POINTS,iVboPtr,iNumVerts); //narysuj wierzchołek z VBO - // glVertex3f(0,0,0); - //glEnd(); - glEnable(GL_LIGHTING); - glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); - glMaterialfv(GL_FRONT,GL_EMISSION,emm2); - //glEndList(); - } + glColor3f(f4Diffuse[0],f4Diffuse[1],f4Diffuse[2]); + glColorMaterial(GL_FRONT,GL_EMISSION); + glDisable(GL_LIGHTING); //Tolaris-030603: bo mu punkty + swiecace sie blendowaly + //glBegin(GL_POINTS); + glDrawArrays(GL_POINTS,iVboPtr,iNumVerts); //narysuj + wierzchołek z VBO + // glVertex3f(0,0,0); + //glEnd(); + glEnable(GL_LIGHTING); + glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); + glMaterialfv(GL_FRONT,GL_EMISSION,emm2); + //glEndList(); + } */ if (Child != NULL) if (iAlpha & iFlags & 0x001F0000) @@ -1459,7 +1520,8 @@ void TSubModel::RaArrayFill(CVertNormTex *Vert) }; void TSubModel::Info() -{ // zapisanie informacji o submodelu do obiektu pomocniczego +{ // zapisanie informacji o submodelu do obiektu + // pomocniczego TSubModelInfo *info = TSubModelInfo::pTable + TSubModelInfo::iCurrent; info->pSubModel = this; if (fMatrix && (iFlags & 0x8000)) // ma matrycę i jest ona niejednostkowa @@ -1474,7 +1536,8 @@ void TSubModel::Info() } if (info->iTexture < 0) // jeśli nie znaleziono we wcześniejszych { - info->iTexture = ++info->iTotalTextures; // przydzielenie numeru tekstury w pliku (od 1) + info->iTexture = ++info->iTotalTextures; // przydzielenie numeru tekstury + // w pliku (od 1) AnsiString t = AnsiString(pTexture); if (t.SubString(t.Length() - 3, 4) == ".tga") t.Delete(t.Length() - 3, 4); @@ -1510,7 +1573,9 @@ void TSubModel::Info() }; void TSubModel::InfoSet(TSubModelInfo *info) -{ // ustawienie danych wg obiektu pomocniczego do zapisania w pliku +{ // ustawienie danych wg obiektu + // pomocniczego do zapisania w + // pliku int ile = (char *)&uiDisplayList - (char *)&eType; // ilość bajtów pomiędzy tymi zmiennymi ZeroMemory(this, sizeof(TSubModel)); // zerowaie całości CopyMemory(this, info->pSubModel, ile); // skopiowanie pamięci 1:1 @@ -1538,14 +1603,16 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, float8 *v, TStringPack *t, TS pName = n->String(iName); AnsiString s = AnsiString(pName); if (!s.IsEmpty()) - { // jeśli dany submodel jest zgaszonym światłem, to domyślnie go ukrywamy + { // jeśli dany submodel jest zgaszonym światłem, to + // domyślnie go ukrywamy if (s.SubString(1, 8) == "Light_On") // jeśli jest światłem numerowanym - iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z obiektem - // "Light_Off" + iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z + // obiektem "Light_Off" else if (dynamic) // inaczej wyłączało smugę w latarniach if (s.SubString(s.Length() - 2, 3) == "_on") // jeśli jest kontrolką w stanie zapalonym - iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z obiektem "_off" + iVisible = 0; // to domyślnie wyłączyć, żeby się nie nakładało z + // obiektem "_off" } } else @@ -1561,7 +1628,8 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, float8 *v, TStringPack *t, TS TextureID = TTexturesManager::GetTextureID(szTexturePath, Global::asCurrentTexturePath.c_str(), t.c_str()); // TexAlpha=TTexturesManager::GetAlpha(TextureID); //zmienna robocza - // ustawienie cyklu przezroczyste/nieprzezroczyste zależnie od własności stałej tekstury + // ustawienie cyklu przezroczyste/nieprzezroczyste zależnie od własności + // stałej tekstury // iFlags=(iFlags&~0x30)|(TTexturesManager::GetAlpha(TextureID)?0x20:0x10); // //0x10-nieprzezroczysta, 0x20-przezroczysta if (Opacity < 1.0) // przezroczystość z tekstury brana tylko dla Opacity 0! @@ -1572,12 +1640,15 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, float8 *v, TStringPack *t, TS iFlags |= 0x10; // normalnie nieprzezroczyste } b_aAnim = b_Anim; // skopiowanie animacji do drugiego cyklu - iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem tablic) + iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem + // tablic) Vertices = v + iVboPtr; - // if (!iNumVerts) eType=-1; //tymczasowo zmiana typu, żeby się nie renderowało na siłę + // if (!iNumVerts) eType=-1; //tymczasowo zmiana typu, żeby się nie + // renderowało na siłę }; void TSubModel::AdjustDist() -{ // aktualizacja odległości faz LoD, zależna od rozdzielczości pionowej oraz multisamplingu +{ // aktualizacja odległości faz LoD, zależna od + // rozdzielczości pionowej oraz multisamplingu if (fSquareMaxDist > 0.0) fSquareMaxDist *= Global::fDistanceFactor; if (fSquareMinDist > 0.0) @@ -1605,7 +1676,8 @@ void TSubModel::ColorsSet(int *a, int *d, int *s) }; void TSubModel::ParentMatrix(float4x4 *m) { // pobranie transformacji względem wstawienia modelu - // jeśli nie zostało wykonane Init() (tzn. zaraz po wczytaniu T3D), to dodatkowy obrót + // 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(3)[1]=m[3][1]+0.054; //w górę o wysokość ślizgu (na razie tak) @@ -1616,11 +1688,12 @@ void TSubModel::ParentMatrix(float4x4 *m) *m = *sm->Parent->GetMatrix() * *m; sm = sm->Parent; } - // dla ostatniego może być potrzebny dodatkowy obrót, jeśli wczytano z T3D, a nie obrócono - // jeszcze + // dla ostatniego może być potrzebny dodatkowy obrót, jeśli wczytano z T3D, a + // nie obrócono jeszcze }; float TSubModel::MaxY(const float4x4 &m) -{ // obliczenie maksymalnej wysokości, na początek ślizgu w pantografie +{ // obliczenie maksymalnej wysokości, + // na początek ślizgu w pantografie if (eType != 4) return 0; // tylko dla trójkątów liczymy if (iNumVerts < 1) @@ -1651,7 +1724,7 @@ TModel3d::TModel3d() iNumVerts = 0; // nie ma jeszcze wierzchołków }; /* -__fastcall TModel3d::TModel3d(char *FileName) + TModel3d::TModel3d(char *FileName) { // Root=NULL; // Materials=NULL; @@ -1666,7 +1739,8 @@ TModel3d::~TModel3d() { // SafeDeleteArray(Materials); if (iFlags & 0x0200) - { // wczytany z pliku tekstowego, submodele sprzątają same + { // wczytany z pliku tekstowego, submodele sprzątają + // same SafeDelete(Root); // submodele się usuną rekurencyjnie } else @@ -1678,7 +1752,7 @@ TModel3d::~TModel3d() // później się jeszcze usuwa obiekt z którego dziedziczymy tabelę VBO }; -TSubModel *__fastcall TModel3d::AddToNamed(const char *Name, TSubModel *SubModel) +TSubModel * TModel3d::AddToNamed(const char *Name, TSubModel *SubModel) { TSubModel *sm = Name ? GetFromName(Name) : NULL; AddTo(sm, SubModel); // szukanie nadrzędnego @@ -1686,7 +1760,9 @@ TSubModel *__fastcall TModel3d::AddToNamed(const char *Name, TSubModel *SubModel }; void TModel3d::AddTo(TSubModel *tmp, TSubModel *SubModel) -{ // jedyny poprawny sposób dodawania submodeli, inaczej mogą zginąć przy zapisie E3D +{ // jedyny poprawny sposób dodawania + // submodeli, inaczej mogą zginąć + // przy zapisie E3D if (tmp) { // jeśli znaleziony, podłączamy mu jako potomny tmp->ChildAdd(SubModel); @@ -1700,7 +1776,7 @@ void TModel3d::AddTo(TSubModel *tmp, TSubModel *SubModel) iFlags |= 0x0200; // submodele są oddzielne }; -TSubModel *__fastcall TModel3d::GetFromName(const char *sName) +TSubModel * TModel3d::GetFromName(const char *sName) { // wyszukanie submodelu po nazwie if (!sName) return Root; // potrzebne do terenu z E3D @@ -1784,13 +1860,13 @@ void TModel3d::LoadFromBinFile(char *FileName, bool dynamic) break; case 'SUB0': // submodele: 'SUB0',len,(256 bajtów na submodel) iSubModelsCount = (k - 2) / 64; - Root = (TSubModel *)(iModel + i + 2); // numery na wskaźniki przetworzymy - // później + Root = + (TSubModel *)(iModel + i + 2); // numery na wskaźniki przetworzymy później break; case 'SUB1': // submodele: 'SUB1',len,(320 bajtów na submodel) iSubModelsCount = (k - 2) / 80; - Root = (TSubModel *)(iModel + i + 2); // numery na wskaźniki przetworzymy - // później + Root = + (TSubModel *)(iModel + i + 2); // numery na wskaźniki przetworzymy później for (ch = 1; ch < iSubModelsCount; ++ch) // trzeba przesunąć bliżej, bo 256 wystarczy MoveMemory(((char *)Root) + 256 * ch, ((char *)Root) + 320 * ch, 256); @@ -1809,13 +1885,15 @@ void TModel3d::LoadFromBinFile(char *FileName, bool dynamic) break; case 'IDX4': // indeksy 4B: 'IDX4',len,(po 4 bajty na numer wierzchołka) break; - case 'TEX0': // tekstury: 'TEX0',len,(łańcuchy zakończone zerem - pliki tekstur) + case 'TEX0': // tekstury: 'TEX0',len,(łańcuchy zakończone zerem - pliki + // tekstur) Textures.Init((char *)(iModel + i)); //łącznie z nagłówkiem break; case 'TIX0': // indeks nazw tekstur Textures.InitIndex((int *)(iModel + i)); //łącznie z nagłówkiem break; - case 'NAM0': // nazwy: 'NAM0',len,(łańcuchy zakończone zerem - nazwy submodeli) + case 'NAM0': // nazwy: 'NAM0',len,(łańcuchy zakończone zerem - nazwy + // submodeli) Names.Init((char *)(iModel + i)); //łącznie z nagłówkiem break; case 'NIX0': // indeks nazw submodeli @@ -1853,25 +1931,30 @@ void TModel3d::LoadFromTextFile(char *FileName, bool dynamic) { std::string parent; // parser.getToken(parent); - parser.getTokens(1, false); // nazwa submodelu nadrzędnego bez zmieny na małe + parser.getTokens(1, false); // nazwa submodelu nadrzędnego bez zmieny na + // małe parser >> parent; if (parent == "") break; SubModel = new TSubModel(); iNumVerts += SubModel->Load(parser, this, iNumVerts, dynamic); - SubModel->Parent = AddToNamed( - parent.c_str(), SubModel); // będzie potrzebne do wyliczenia pozycji, np. pantografu + SubModel->Parent = + AddToNamed(parent.c_str(), + SubModel); // będzie potrzebne do wyliczenia pozycji, np. pantografu // iSubModelsCount++; parser.getToken(token); } - // Ra: od wersji 334 przechylany jest cały model, a nie tylko pierwszy submodel - // ale bujanie kabiny nadal używa bananów :( od 393 przywrócone, ale z dodatkowym warunkiem + // Ra: od wersji 334 przechylany jest cały model, a nie tylko pierwszy + // submodel + // ale bujanie kabiny nadal używa bananów :( od 393 przywrócone, ale z + // dodatkowym warunkiem if (Global::iConvertModels & 4) { // automatyczne banany czasem psuły przechylanie kabin... if (dynamic && Root) { if (Root->NextGet()) // jeśli ma jakiekolwiek kolejne - { // dynamic musi mieć "banana", bo tylko pierwszy obiekt jest animowany, a następne nie + { // dynamic musi mieć "banana", bo tylko pierwszy obiekt jest animowany, + // a następne nie SubModel = new TSubModel(); // utworzenie pustego SubModel->ChildAdd(Root); Root = SubModel; @@ -1883,16 +1966,19 @@ void TModel3d::LoadFromTextFile(char *FileName, bool dynamic) } void TModel3d::Init() -{ // obrócenie początkowe układu współrzędnych, dla pojazdów wykonywane po analizie animacji +{ // obrócenie początkowe układu współrzędnych, dla + // pojazdów wykonywane po analizie animacji if (iFlags & 0x8000) return; // operacje zostały już wykonane if (Root) { if (iFlags & 0x0200) // jeśli wczytano z pliku tekstowego - { // jest jakiś dziwny błąd, że obkręcany ma być tylko ostatni submodel głównego łańcucha + { // jest jakiś dziwny błąd, że obkręcany ma być tylko ostatni submodel + // głównego łańcucha // TSubModel *p=Root; // do - //{p->InitialRotate(true); //ostatniemu należy się konwersja układu współrzędnych + //{p->InitialRotate(true); //ostatniemu należy się konwersja układu + // współrzędnych // p=p->NextGet(); //} // while (p->NextGet()) @@ -1910,11 +1996,12 @@ void TModel3d::Init() { if (Global::fDistanceFactor != 1.0) // trochę zaoszczędzi czasu na modelach z wieloma submocelami - Root->AdjustDist(); // aktualizacja odległości faz LoD, zależnie od rozdzielczości - // pionowej oraz multisamplingu + Root->AdjustDist(); // aktualizacja odległości faz LoD, zależnie od + // rozdzielczości pionowej oraz multisamplingu if (Global::bUseVBO) { - if (!m_pVNT) // jeśli nie ma jeszcze tablicy (wczytano z pliku tekstowego) + if (!m_pVNT) // jeśli nie ma jeszcze tablicy (wczytano z pliku + // tekstowego) { // tworzenie tymczasowej tablicy z wierzchołkami całego modelu MakeArray(iNumVerts); // tworzenie tablic dla VBO Root->RaArrayFill(m_pVNT); // wypełnianie tablicy @@ -2027,7 +2114,8 @@ void TModel3d::BreakHierarhy() }; /* -void TModel3d::Render(vector3 pPosition,double fAngle,GLuint ReplacableSkinId,int iAlpha) +void TModel3d::Render(vector3 pPosition,double fAngle,GLuint +ReplacableSkinId,int iAlpha) { // glColor3f(1.0f,1.0f,1.0f); // glColor3f(0.0f,0.0f,0.0f); @@ -2080,7 +2168,8 @@ void TModel3d::RenderAlpha(double fSquareDistance, GLuint *ReplacableSkinId, int }; /* -void TModel3d::RaRender(vector3 pPosition,double fAngle,GLuint *ReplacableSkinId,int +void TModel3d::RaRender(vector3 pPosition,double fAngle,GLuint +*ReplacableSkinId,int iAlpha) { // glColor3f(1.0f,1.0f,1.0f); @@ -2100,7 +2189,8 @@ iAlpha) fSquareDist=SquareMagnitude(pos); */ /* - fSquareDist=SquareMagnitude(pPosition-Global::GetCameraPosition()); //zmienna globalna! + fSquareDist=SquareMagnitude(pPosition-Global::GetCameraPosition()); //zmienna +globalna! if (StartVBO()) {//odwrócenie flag, aby wyłapać nieprzezroczyste Root->ReplacableSet(ReplacableSkinId,iAlpha^0x0F0F000F); @@ -2142,14 +2232,16 @@ void TModel3d::RaRenderAlpha(double fSquareDistance, GLuint *ReplacableSkinId, i }; /* -void TModel3d::RaRenderAlpha(vector3 pPosition,double fAngle,GLuint *ReplacableSkinId,int +void TModel3d::RaRenderAlpha(vector3 pPosition,double fAngle,GLuint +*ReplacableSkinId,int iAlpha) { glPushMatrix(); glTranslatef(pPosition.x,pPosition.y,pPosition.z); if (fAngle!=0) glRotatef(fAngle,0,1,0); - fSquareDist=SquareMagnitude(pPosition-Global::GetCameraPosition()); //zmienna globalna! + fSquareDist=SquareMagnitude(pPosition-Global::GetCameraPosition()); //zmienna +globalna! if (StartVBO()) {Root->ReplacableSet(ReplacableSkinId,iAlpha); Root->RaRenderAlpha(); @@ -2244,7 +2336,8 @@ void TModel3d::RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, GLuint *Replac //----------------------------------------------------------------------------- int TModel3d::TerrainCount() -{ // zliczanie kwadratów kilometrowych (główna linia po Next) do tworznia tablicy +{ // zliczanie kwadratów kilometrowych (główna + // linia po Next) do tworznia tablicy int i = 0; TSubModel *r = Root; while (r) @@ -2254,7 +2347,7 @@ int TModel3d::TerrainCount() } return i; }; -TSubModel *__fastcall TModel3d::TerrainSquare(int n) +TSubModel * TModel3d::TerrainSquare(int n) { // pobieranie wskaźnika do submodelu (n) int i = 0; TSubModel *r = Root; @@ -2273,16 +2366,16 @@ void TModel3d::TerrainRenderVBO(int n) // if (vAngle->y!=0.0) glRotated(vAngle->y,0.0,1.0,0.0); // if (vAngle->x!=0.0) glRotated(vAngle->x,1.0,0.0,0.0); // if (vAngle->z!=0.0) glRotated(vAngle->z,0.0,0.0,1.0); - // TSubModel::fSquareDist=SquareMagnitude(*vPosition-Global::GetCameraPosition()); //zmienna - // globalna! + // TSubModel::fSquareDist=SquareMagnitude(*vPosition-Global::GetCameraPosition()); + // //zmienna globalna! if (StartVBO()) { // odwrócenie flag, aby wyłapać nieprzezroczyste // Root->ReplacableSet(ReplacableSkinId,iAlpha^0x0F0F000F); TSubModel *r = Root; while (r) { - if (r->iVisible == n) // tylko jeśli ma być widoczny w danej ramce (problem dla - // 0==false) + if (r->iVisible == + n) // tylko jeśli ma być widoczny w danej ramce (problem dla 0==false) r->RenderVBO(); // sub kolejne (Next) się nie wyrenderują r = r->NextGet(); } diff --git a/Model3d.h b/Model3d.h index b724d4c05..9ffa52d0e 100644 --- a/Model3d.h +++ b/Model3d.h @@ -262,16 +262,16 @@ class TSubModel int Load(cParser &Parser, TModel3d *Model, int Pos, bool dynamic); void ChildAdd(TSubModel *SubModel); void NextAdd(TSubModel *SubModel); - TSubModel *__fastcall NextGet() + TSubModel * NextGet() { return Next; }; - TSubModel *__fastcall ChildGet() + TSubModel * ChildGet() { return Child; }; int TriangleAdd(TModel3d *m, int tex, int tri); - float8 *__fastcall TrianglePtr(int tex, int pos, int *la, int *ld, int *ls); + float8 * TrianglePtr(int tex, int pos, int *la, int *ld, int *ls); // float8* TrianglePtr(const char *tex,int tri); // void SetRotate(vector3 vNewRotateAxis,float fNewAngle); void SetRotate(float3 vNewRotateAxis, float fNewAngle); @@ -280,14 +280,14 @@ class TSubModel void SetTranslate(vector3 vNewTransVector); void SetTranslate(float3 vNewTransVector); void SetRotateIK1(float3 vNewAngles); - TSubModel *__fastcall GetFromName(AnsiString search, bool i = true); - TSubModel *__fastcall GetFromName(char *search, bool i = true); + TSubModel * GetFromName(AnsiString search, bool i = true); + TSubModel * GetFromName(char *search, bool i = true); void RenderDL(); void RenderAlphaDL(); void RenderVBO(); void RenderAlphaVBO(); // inline matrix4x4* GetMatrix() {return dMatrix;}; - inline float4x4 *__fastcall GetMatrix() + inline float4x4 * GetMatrix() { return fMatrix; }; @@ -335,6 +335,10 @@ class TSubModel { return *(fMatrix->TranslationGet()) + Child->Translation1Get(); } + int GetTextureId() + { + return TextureID; + } void ParentMatrix(float4x4 *m); float MaxY(const float4x4 &m); void AdjustDist(); @@ -386,7 +390,7 @@ class TModel3d : public CMesh int iSubModelsCount; // Ra: używane do tworzenia binarnych AnsiString asBinary; // nazwa pod którą zapisać model binarny public: - inline TSubModel *__fastcall GetSMRoot() + inline TSubModel * GetSMRoot() { return (Root); }; @@ -394,9 +398,9 @@ class TModel3d : public CMesh TModel3d(); TModel3d(char *FileName); ~TModel3d(); - TSubModel *__fastcall GetFromName(const char *sName); + TSubModel * GetFromName(const char *sName); // TMaterial* GetMaterialFromName(char *sName); - TSubModel *__fastcall AddToNamed(const char *Name, TSubModel *SubModel); + TSubModel * AddToNamed(const char *Name, TSubModel *SubModel); void AddTo(TSubModel *tmp, TSubModel *SubModel); void LoadFromTextFile(char *FileName, bool dynamic); void LoadFromBinFile(char *FileName, bool dynamic); @@ -434,12 +438,12 @@ class TModel3d : public CMesh return iFlags; }; void Init(); - char *__fastcall NameGet() + char * NameGet() { return Root ? Root->pName : NULL; }; int TerrainCount(); - TSubModel *__fastcall TerrainSquare(int n); + TSubModel * TerrainSquare(int n); void TerrainRenderVBO(int n); }; diff --git a/Mover.cpp b/Mover.cpp index 259e1a2db..1b65e4787 100644 --- a/Mover.cpp +++ b/Mover.cpp @@ -235,9 +235,9 @@ bool TMoverParameters::IncBrakeLevel() }; bool TMoverParameters::DecBrakeLevel() -{ +{ // nowa wersja na użytek AI, false gdy osiągnięto pozycję -1 return BrakeLevelAdd(-1.0); -}; // nowa wersja na użytek AI, false gdy osiągnięto pozycję -1 +}; bool TMoverParameters::ChangeCab(int direction) { // zmiana kabiny i resetowanie ustawien @@ -625,8 +625,8 @@ double TMoverParameters::ShowEngineRotation(int VehN) void TMoverParameters::ConverterCheck() { // sprawdzanie przetwornicy - if (ConverterAllow && Mains) - ConverterFlag = true; + if (ConverterAllow && Mains && !ConvOvldFlag) + ConverterFlag = true; else ConverterFlag = false; }; diff --git a/Mover.h b/Mover.h index f92b3eb1d..519098934 100644 --- a/Mover.h +++ b/Mover.h @@ -169,7 +169,7 @@ class TMoverParameters : public T_MoverParameters // &Track, const // TLocation &NewLoc, TRotation &NewRot); // bool ChangeOffsetH(double DeltaOffset); - //__fastcall T_MoverParameters(double VelInitial, AnsiString TypeNameInit, AnsiString NameInit, + // T_MoverParameters(double VelInitial, AnsiString TypeNameInit, AnsiString NameInit, // int LoadInitial // , AnsiString LoadTypeInitial, int Cab); // bool LoadChkFile(AnsiString chkpath); diff --git a/Names.cpp b/Names.cpp index 331da6f9d..6c673e085 100644 --- a/Names.cpp +++ b/Names.cpp @@ -69,13 +69,13 @@ void ItemRecord::ListGet(ItemRecord *r, int *&n) rNext->ListGet(r, n); // dodanie wszystkich późniejszych }; -void *__fastcall ItemRecord::TreeFind(const char *n) +void * ItemRecord::TreeFind(const char *n) { // wyszukanie ciągu (n) ItemRecord *r = TreeFindRecord(n); return r ? r->pData : NULL; }; -ItemRecord *__fastcall ItemRecord::TreeFindRecord(const char *n) +ItemRecord * ItemRecord::TreeFindRecord(const char *n) { // wyszukanie ciągu (n) ItemRecord *r = this; //żeby nie robić rekurencji int i = 0; @@ -147,7 +147,7 @@ bool TNames::Update(int t, const char *n, void *d) return false; // został dodany nowy }; -ItemRecord *__fastcall TNames::TreeSet(int *n, int d, int u) +ItemRecord * TNames::TreeSet(int *n, int d, int u) { // rekurencyjne wypełnianie drzewa pozycjami od (d) do (u) if (d == u) { @@ -177,7 +177,7 @@ void TNames::Sort(int t) return; }; -ItemRecord *__fastcall TNames::FindRecord(const int t, const char *n) +ItemRecord * TNames::FindRecord(const int t, const char *n) { // poszukiwanie rekordu w celu np. zmiany wskaźnika return rTypes[t] ? rTypes[t]->TreeFindRecord(n) : NULL; }; diff --git a/Names.h b/Names.h index 3ddcaf859..de38a6370 100644 --- a/Names.h +++ b/Names.h @@ -34,8 +34,8 @@ class ItemRecord { pData = (void *)x; }; - void *__fastcall TreeFind(const char *n); - ItemRecord *__fastcall TreeFindRecord(const char *n); + void * TreeFind(const char *n); + ItemRecord * TreeFindRecord(const char *n); }; class TNames @@ -54,14 +54,14 @@ class TNames int Add(int t, const char *n, int d); // dodanie obiektu z numerem bool Update(int t, const char *n, void *d); // dodanie jeśli nie ma, wymiana (d), gdy jest void TreeSet(); - ItemRecord *__fastcall TreeSet(int *n, int d, int u); + ItemRecord * TreeSet(int *n, int d, int u); void Sort(int t); // przebudowa drzewa typu (t) - ItemRecord *__fastcall Item(int n); // rekord o numerze (n) + ItemRecord * Item(int n); // rekord o numerze (n) inline void *Find(const int t, const char *n) { return rTypes[t] ? rTypes[t]->TreeFind(n) : NULL; }; - ItemRecord *__fastcall FindRecord(const int t, const char *n); + ItemRecord * FindRecord(const int t, const char *n); // template inline TOut* Find(const int t,const char *n) //{return (TOut*)(rTypes[t]->TreeFind(n));}; }; diff --git a/PyInt.cpp b/PyInt.cpp new file mode 100644 index 000000000..542ecd378 --- /dev/null +++ b/PyInt.cpp @@ -0,0 +1,601 @@ +#include "PyInt.h" +#include "Train.h" +#include "Logs.h" +#include +#include +#include + +TPythonInterpreter *TPythonInterpreter::_instance = NULL; + +//#define _PY_INT_MORE_LOG + +TPythonInterpreter::TPythonInterpreter() +{ + WriteLog("Loading Python ..."); + Py_SetPythonHome("python"); + Py_Initialize(); + _main = PyImport_ImportModule("__main__"); + if (_main == NULL) + { + WriteLog("Cannot import Python module __main__"); + } + _screenRendererPriority = THREAD_PRIORITY_NORMAL; // domyslny priorytet normalny + PyObject *cStringModule = PyImport_ImportModule("cStringIO"); + _stdErr = NULL; + if (cStringModule == NULL) + return; + PyObject *cStringClassName = PyObject_GetAttrString(cStringModule, "StringIO"); + if (cStringClassName == NULL) + return; + PyObject *cString = PyObject_CallObject(cStringClassName, NULL); + if (cString == NULL) + return; + if (PySys_SetObject("stderr", cString) != 0) + return; + _stdErr = cString; +} + +TPythonInterpreter *TPythonInterpreter::getInstance() +{ + if (!_instance) + { + _instance = new TPythonInterpreter(); + } + return _instance; +} + +bool TPythonInterpreter::loadClassFile(const char *lookupPath, const char *className) +{ + std::set::const_iterator it = _classes.find(className); + if (it == _classes.end()) + { + FILE *sourceFile = _getFile(lookupPath, className); + if (sourceFile != NULL) + { + fseek(sourceFile, 0, SEEK_END); + long fsize = ftell(sourceFile); + char *buffer = (char *)calloc(fsize + 1, sizeof(char)); + fseek(sourceFile, 0, SEEK_SET); + long freaded = fread(buffer, sizeof(char), fsize, sourceFile); + buffer[freaded] = 0; // z jakiegos powodu czytamy troche mniej i trzczeba dodac konczace +// zero do bufora (mimo ze calloc teoretycznie powiniene zwrocic +// wyzerowana pamiec) +#ifdef _PY_INT_MORE_LOG + char buf[255]; + sprintf(buf, "readed %d / %d characters for %s", freaded, fsize, className); + WriteLog(buf); +#endif // _PY_INT_MORE_LOG + fclose(sourceFile); + if (PyRun_SimpleString(buffer) != 0) + { + handleError(); + return false; + } + char *classNameToRemember = (char *)calloc(strlen(className) + 1, sizeof(char)); + strcpy(classNameToRemember, className); + _classes.insert(classNameToRemember); + free(buffer); + return true; + } + return false; + } + return true; +} + +PyObject *TPythonInterpreter::newClass(const char *className) +{ + return newClass(className, NULL); +} + +FILE *TPythonInterpreter::_getFile(const char *lookupPath, const char *className) +{ + char *sourceFilePath; + if (lookupPath != NULL) + { + sourceFilePath = (char *)calloc(strlen(lookupPath) + strlen(className) + 4, sizeof(char)); + strcat(sourceFilePath, lookupPath); + strcat(sourceFilePath, className); + strcat(sourceFilePath, ".py"); + + FILE *file = fopen(sourceFilePath, "r"); +#ifdef _PY_INT_MORE_LOG + WriteLog(sourceFilePath); +#endif // _PY_INT_MORE_LOG + free(sourceFilePath); + if (file != NULL) + { + return file; + } + } + char *basePath = "python\\local\\"; + sourceFilePath = (char *)calloc(strlen(basePath) + strlen(className) + 4, sizeof(char)); + strcat(sourceFilePath, basePath); + strcat(sourceFilePath, className); + strcat(sourceFilePath, ".py"); + + FILE *file = fopen(sourceFilePath, "r"); +#ifdef _PY_INT_MORE_LOG + WriteLog(sourceFilePath); +#endif // _PY_INT_MORE_LOG + free(sourceFilePath); + if (file != NULL) + { + return file; + } + return NULL; +} + +void TPythonInterpreter::handleError() +{ +#ifdef _PY_INT_MORE_LOG + WriteLog("Python Error occured"); +#endif // _PY_INT_MORE_LOG + if (_stdErr != NULL) + { // std err pythona jest buforowane + PyErr_Print(); + PyObject *bufferContent = PyObject_CallMethod(_stdErr, "getvalue", NULL); + PyObject_CallMethod(_stdErr, "truncate", "i", 0); // czyscimy bufor na kolejne bledy + WriteLog(PyString_AsString(bufferContent)); + } + else + { // nie dziala buffor pythona + if (PyErr_Occurred() != NULL) + { + PyObject *ptype, *pvalue, *ptraceback; + PyErr_Fetch(&ptype, &pvalue, &ptraceback); + if (ptype == NULL) + { + WriteLog("Don't konw how to handle NULL exception"); + } + PyErr_NormalizeException(&ptype, &pvalue, &ptraceback); + if (ptype == NULL) + { + WriteLog("Don't konw how to handle NULL exception"); + } + PyObject *pStrType = PyObject_Str(ptype); + if (pStrType != NULL) + { + WriteLog(PyString_AsString(pStrType)); + } + WriteLog(PyString_AsString(pvalue)); + PyObject *pStrTraceback = PyObject_Str(ptraceback); + if (pStrTraceback != NULL) + { + WriteLog(PyString_AsString(pStrTraceback)); + } + else + { + WriteLog("Python Traceback cannot be shown"); + } + } + else + { +#ifdef _PY_INT_MORE_LOG + WriteLog("Called python error handler when no error occured!"); +#endif // _PY_INT_MORE_LOG + } + } +} +PyObject *TPythonInterpreter::newClass(const char *className, PyObject *argsTuple) +{ + if (_main == NULL) + { + WriteLog("main turned into null"); + return NULL; + } + PyObject *classNameObj = PyObject_GetAttrString(_main, className); + if (classNameObj == NULL) + { +#ifdef _PY_INT_MORE_LOG + char buf[255]; + sprintf(buf, "Python class %s not defined!", className); + WriteLog(buf); +#endif // _PY_INT_MORE_LOG + return NULL; + } + PyObject *object = PyObject_CallObject(classNameObj, argsTuple); + + if (PyErr_Occurred() != NULL) + { + handleError(); + return NULL; + } + return object; +} + +void TPythonInterpreter::setScreenRendererPriority(const char *priority) +{ + if (strncmp(priority, "normal", 6) == 0) + { + _screenRendererPriority = THREAD_PRIORITY_NORMAL; +#ifdef _PY_INT_MORE_LOG + WriteLog("Python screen renderer priority: Normal"); +#endif // _PY_INT_MORE_LOG + } + else if (strncmp(priority, "lower", 5) == 0) + { + _screenRendererPriority = THREAD_PRIORITY_BELOW_NORMAL; +#ifdef _PY_INT_MORE_LOG + WriteLog("Python screen renderer priority: Lower"); +#endif // _PY_INT_MORE_LOG + } + else if (strncmp(priority, "lowest", 6) == 0) + { + _screenRendererPriority = THREAD_PRIORITY_LOWEST; +#ifdef _PY_INT_MORE_LOG + WriteLog("Python screen renderer priority: Lowest"); +#endif // _PY_INT_MORE_LOG + } + else if (strncmp(priority, "idle", 4) == 0) + { + _screenRendererPriority = THREAD_PRIORITY_IDLE; +#ifdef _PY_INT_MORE_LOG + WriteLog("Python screen renderer priority: Idle"); +#endif // _PY_INT_MORE_LOG + } +} + +TPythonScreenRenderer::TPythonScreenRenderer(int textureId, PyObject *renderer) +{ + _textureId = textureId; + _pyRenderer = renderer; +} + +void TPythonScreenRenderer::updateTexture() +{ + int width, height; + if (_pyWidth == NULL || _pyHeight == NULL) + { + WriteLog("Unknown python texture size!"); + return; + } + width = PyInt_AsLong(_pyWidth); + height = PyInt_AsLong(_pyHeight); + if (_pyTexture != NULL) + { + char *textureData = PyString_AsString(_pyTexture); + if (textureData != NULL) + { +#ifdef _PY_INT_MORE_LOG + char buff[255]; + sprintf(buff, "Sending texture id: %d w: %d h: %d", _textureId, width, height); + WriteLog(buff); +#endif // _PY_INT_MORE_LOG + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glBindTexture(GL_TEXTURE_2D, _textureId); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, + textureData); +#ifdef _PY_INT_MORE_LOG + GLenum status = glGetError(); + switch (status) + { + case GL_INVALID_ENUM: + WriteLog("An unacceptable value is specified for an enumerated argument. The " + "offending function is ignored, having no side effect other than to set " + "the error flag."); + break; + case GL_INVALID_VALUE: + WriteLog("A numeric argument is out of range. The offending function is ignored, " + "having no side effect other than to set the error flag."); + break; + case GL_INVALID_OPERATION: + WriteLog("The specified operation is not allowed in the current state. The " + "offending function is ignored, having no side effect other than to set " + "the error flag."); + break; + case GL_NO_ERROR: + WriteLog("No error has been recorded. The value of this symbolic constant is " + "guaranteed to be zero."); + break; + case GL_STACK_OVERFLOW: + WriteLog("This function would cause a stack overflow. The offending function is " + "ignored, having no side effect other than to set the error flag."); + break; + case GL_STACK_UNDERFLOW: + WriteLog("This function would cause a stack underflow. The offending function is " + "ignored, having no side effect other than to set the error flag."); + break; + case GL_OUT_OF_MEMORY: + WriteLog("There is not enough memory left to execute the function. The state of " + "OpenGL is undefined, except for the state of the error flags, after this " + "error is recorded."); + break; + }; +#endif // _PY_INT_MORE_LOG + } + else + { + WriteLog("RAW python texture data is NULL!"); + } + } + else + { + WriteLog("Python texture object is NULL!"); + } +} + +void TPythonScreenRenderer::render(PyObject *trainState) +{ +#ifdef _PY_INT_MORE_LOG + WriteLog("Python rendering texture ..."); +#endif // _PY_INT_MORE_LOG + _pyTexture = PyObject_CallMethod(_pyRenderer, "render", "O", trainState); + + if (_pyTexture == NULL) + { + TPythonInterpreter::getInstance()->handleError(); + } + else + { + _pyWidth = PyObject_CallMethod(_pyRenderer, "get_width", NULL); + if (_pyWidth == NULL) + { + TPythonInterpreter::getInstance()->handleError(); + } + _pyHeight = PyObject_CallMethod(_pyRenderer, "get_height", NULL); + if (_pyHeight == NULL) + { + TPythonInterpreter::getInstance()->handleError(); + } + } +} + +TPythonScreenRenderer::~TPythonScreenRenderer() +{ +#ifdef _PY_INT_MORE_LOG + WriteLog("PythonScreenRenderer descturctor called"); +#endif // _PY_INT_MORE_LOG + if (_pyRenderer != NULL) + { + Py_CLEAR(_pyRenderer); + } + cleanup(); +#ifdef _PY_INT_MORE_LOG + WriteLog("PythonScreenRenderer desctructor finished"); +#endif // _PY_INT_MORE_LOG +} + +void TPythonScreenRenderer::cleanup() +{ + if (_pyTexture != NULL) + { + Py_CLEAR(_pyTexture); + _pyTexture = NULL; + } + if (_pyWidth != NULL) + { + Py_CLEAR(_pyWidth); + _pyWidth = NULL; + } + if (_pyHeight != NULL) + { + Py_CLEAR(_pyHeight); + _pyHeight = NULL; + } +} + +void TPythonScreens::reset(void *train) +{ + _terminationFlag = true; + if (_thread != NULL) + { + WriteLog("Awaiting python thread to end"); + WaitForSingleObject(_thread, INFINITE); + _thread = NULL; + } + _terminationFlag = false; + _cleanupReadyFlag = false; + _renderReadyFlag = false; + for (std::vector::iterator i = _screens.begin(); i != _screens.end(); + ++i) + { + delete *i; + } +#ifdef _PY_INT_MORE_LOG + WriteLog("Clearing renderer vector"); +#endif // _PY_INT_MORE_LOG + _screens.clear(); + _train = train; +} + +void TPythonScreens::init(TQueryParserComp *parser, TModel3d *model, AnsiString name, int cab) +{ + char buff[255]; + AnsiString asSubModelName = parser->GetNextSymbol(); + AnsiString asPyClassName = parser->GetNextSymbol(); + char *subModelName = (char *)calloc(asSubModelName.Length() + 1, sizeof(char)); + strcpy(subModelName, asSubModelName.LowerCase().c_str()); + char *pyClassName = (char *)calloc(asPyClassName.Length() + 1, sizeof(char)); + strcpy(pyClassName, asPyClassName.LowerCase().c_str()); + TSubModel *subModel = model->GetFromName(subModelName); + if (subModel == NULL) + { + sprintf(buff, "Python Screen: submodel %s not found - Ignoring screen", subModelName); + WriteLog(buff); + free(subModelName); + free(pyClassName); + return; // nie ma takiego sub modelu w danej kabinie pomijamy + } + int textureId = subModel->GetTextureId(); + if (textureId <= 0) + { + sprintf(buff, "Python Screen: invalid texture id %d - Ignoring screen", textureId); + WriteLog(buff); + free(subModelName); + free(pyClassName); + return; // sub model nie posiada tekstury lub tekstura wymienna - nie obslugiwana + } + TPythonInterpreter *python = TPythonInterpreter::getInstance(); + python->loadClassFile(_lookupPath, pyClassName); + PyObject *args = Py_BuildValue("(ssi)", _lookupPath, name.c_str(), cab); + if (args == NULL) + { + WriteLog("Python Screen: cannot create __init__ arguments"); + free(subModelName); + free(pyClassName); + return; + } + PyObject *pyRenderer = python->newClass(pyClassName, args); + Py_CLEAR(args); + if (pyRenderer == NULL) + { + sprintf(buff, "Python Screen: null renderer for %s - Ignoring screen", pyClassName); + WriteLog(buff); + free(subModelName); + free(pyClassName); + return; // nie mozna utworzyc obiektu Pythonowego + } + TPythonScreenRenderer *renderer = new TPythonScreenRenderer(textureId, pyRenderer); + _screens.push_back(renderer); + sprintf(buff, "Created python screen %s on submodel %s (%d)", pyClassName, subModelName, + textureId); + WriteLog(buff); + free(subModelName); + free(pyClassName); +} + +void TPythonScreens::update() +{ + if (!_renderReadyFlag) + { + return; + } + _renderReadyFlag = false; + for (std::vector::iterator i = _screens.begin(); i != _screens.end(); + ++i) + { + (*i)->updateTexture(); + } + _cleanupReadyFlag = true; +} + +void TPythonScreens::setLookupPath(AnsiString path) +{ + if (_lookupPath != NULL) + { + free(_lookupPath); + } + _lookupPath = (char *)calloc(path.Length() + 1, sizeof(char)); + strcpy(_lookupPath, path.c_str()); +} + +TPythonScreens::TPythonScreens() +{ + _lookupPath = NULL; + TPythonInterpreter::getInstance()->loadClassFile(NULL, "abstractscreenrenderer"); + _terminationFlag = false; + _renderReadyFlag = false; + _cleanupReadyFlag = false; + _thread = NULL; +} + +TPythonScreens::~TPythonScreens() +{ +#ifdef _PY_INT_MORE_LOG + WriteLog("Called python sceeens destructor"); +#endif // _PY_INT_MORE_LOG + reset(NULL); + if (_lookupPath != NULL) + { +#ifdef _PY_INT_MORE_LOG + WriteLog("Freeing lookup path"); +#endif // _PY_INT_MORE_LOG + free(_lookupPath); + } +} + +void TPythonScreens::run() +{ + while (1) + { + if (_terminationFlag) + { + return; + } + TTrain *train = (TTrain *)_train; + _trainState = train->GetTrainState(); + if (_terminationFlag) + { + _freeTrainState(); + return; + } + for (std::vector::iterator i = _screens.begin(); + i != _screens.end(); ++i) + { + (*i)->render(_trainState); + } + _freeTrainState(); + if (_terminationFlag) + { + _cleanup(); + return; + } + _renderReadyFlag = true; + while (!_cleanupReadyFlag && !_terminationFlag) + { + Sleep(100); + } + if (_terminationFlag) + { + return; + } + _cleanup(); + } +} + +void TPythonScreens::finish() +{ + _thread == NULL; +} + +DWORD WINAPI ScreenRendererThread(LPVOID lpParam) +{ + TPythonScreens *renderer = (TPythonScreens *)lpParam; + renderer->run(); + renderer->finish(); +#ifdef _PY_INT_MORE_LOG + WriteLog("Python Screen Renderer Thread Ends"); +#endif // _PY_INT_MORE_LOG + return true; +} + +void TPythonScreens::start() +{ + if (_screens.size() > 0) + { + _thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ScreenRendererThread, this, + CREATE_SUSPENDED, &_threadId); + if (_thread != NULL) + { + SetThreadPriority(_thread, + TPythonInterpreter::getInstance()->getScreenRendererPriotity()); + if (ResumeThread(_thread) != (DWORD)-1) + { + return; + } + } + WriteLog("Python Screen Renderer Thread Did Not Start"); + } +} + +void TPythonScreens::_cleanup() +{ + _cleanupReadyFlag = false; + for (std::vector::iterator i = _screens.begin(); i != _screens.end(); + ++i) + { + (*i)->cleanup(); + } +} + +void TPythonScreens::_freeTrainState() +{ + if (_trainState != NULL) + { + PyDict_Clear(_trainState); + Py_CLEAR(_trainState); + _trainState = NULL; + } +} diff --git a/PyInt.h b/PyInt.h new file mode 100644 index 000000000..97025c7ee --- /dev/null +++ b/PyInt.h @@ -0,0 +1,98 @@ +#ifndef PyIntH +#define PyIntH + +#undef _DEBUG // bez tego macra Py_DECREF powoduja problemy przy linkowaniu + +#include "Python.h" +#include "QueryParserComp.hpp" +#include "Model3d.h" +#include +#include + +#define PyGetFloat(param) PyFloat_FromDouble(param >= 0 ? param : -param) +#define PyGetFloatS(param) PyFloat_FromDouble(param) +#define PyGetInt(param) PyInt_FromLong(param) +#define PyGetFloatS(param) PyFloat_FromDouble(param) +#define PyGetBool(param) param ? Py_True : Py_False +#define PyGetString(param) PyString_FromString(param) + +struct ltstr +{ + bool operator()(const char *s1, const char *s2) const + { + return strcmp(s1, s2) < 0; + } +}; + +class TPythonInterpreter +{ + protected: + TPythonInterpreter(); + ~TPythonInterpreter() + { + } + static TPythonInterpreter *_instance; + int _screenRendererPriority; + std::set _classes; + PyObject *_main; + PyObject *_stdErr; + FILE *_getFile(const char *lookupPath, const char *className); + + public: + static TPythonInterpreter *getInstance(); + bool loadClassFile(const char *lookupPath, const char *className); + PyObject *newClass(const char *className); + PyObject *newClass(const char *className, PyObject *argsTuple); + int getScreenRendererPriotity() + { + return _screenRendererPriority; + }; + void setScreenRendererPriority(const char *priority); + void handleError(); +}; + +class TPythonScreenRenderer +{ + protected: + PyObject *_pyRenderer; + PyObject *_pyTexture; + int _textureId; + PyObject *_pyWidth; + PyObject *_pyHeight; + + public: + TPythonScreenRenderer(int textureId, PyObject *renderer); + ~TPythonScreenRenderer(); + void render(PyObject *trainState); + void cleanup(); + void updateTexture(); +}; + +class TPythonScreens +{ + protected: + bool _cleanupReadyFlag; + bool _renderReadyFlag; + bool _terminationFlag; + HANDLE _thread; + DWORD _threadId; + std::vector _screens; + char *_lookupPath; + void *_train; + void _cleanup(); + void _freeTrainState(); + PyObject *_trainState; + + public: + void reset(void *train); + void setLookupPath(AnsiString path); + void init(TQueryParserComp *parser, TModel3d *model, AnsiString name, int cab); + void update(); + TPythonScreens(); + ~TPythonScreens(); + void run(); + void start(); + void finish(); +}; + +#endif // PyIntH diff --git a/Sound.cpp b/Sound.cpp index 06b4cc0c0..27e1c50c9 100644 --- a/Sound.cpp +++ b/Sound.cpp @@ -182,7 +182,7 @@ void TSoundsManager::Free() SAFE_RELEASE(pDS); }; -TSoundContainer *__fastcall TSoundsManager::LoadFromFile(char *Dir, char *Name, int Concurrent) +TSoundContainer * TSoundsManager::LoadFromFile(char *Dir, char *Name, int Concurrent) { TSoundContainer *Tmp = First; First = new TSoundContainer(pDS, Dir, Name, Concurrent); @@ -303,7 +303,7 @@ void TSoundsManager::RestoreAll() }; // void TSoundsManager::Init(char *Name, int Concurrent) -//__fastcall TSoundsManager::TSoundsManager(HWND hWnd) +// TSoundsManager::TSoundsManager(HWND hWnd) // void TSoundsManager::Init(HWND hWnd, char *NDirectory) void TSoundsManager::Init(HWND hWnd) diff --git a/Sound.h b/Sound.h index 37652b45b..914b977f3 100644 --- a/Sound.h +++ b/Sound.h @@ -51,7 +51,7 @@ class TSoundsManager // static char Directory[80]; static int Count; static TSoundContainer *First; - static TSoundContainer *__fastcall LoadFromFile(char *Dir, char *Name, int Concurrent); + static TSoundContainer * LoadFromFile(char *Dir, char *Name, int Concurrent); public: // TSoundsManager(HWND hWnd); diff --git a/Spline.cpp b/Spline.cpp index 2c4c55252..15711487c 100644 --- a/Spline.cpp +++ b/Spline.cpp @@ -47,7 +47,7 @@ float CurveLength(vector3 p1, vector3 cp1, vector3 cp2, vector3 p2) return (l); } -__fastcall TKnot::TKnot() + TKnot::TKnot() { Next = Prev = NULL; Length = -1; @@ -58,7 +58,7 @@ __fastcall TKnot::TKnot() bSwitchDirectionBackward = false; } -__fastcall TKnot::TKnot(int n) + TKnot::TKnot(int n) { bSwitchDirectionForward = false; bSwitchDirectionBackward = false; @@ -73,7 +73,7 @@ __fastcall TKnot::TKnot(int n) } } -__fastcall TKnot::~TKnot() + TKnot::~TKnot() { } @@ -241,7 +241,7 @@ float TKnot::RombergIntegral(float fA, float fB) //----------------------------------------------------------------------------// -__fastcall TSpline::TSpline() + TSpline::TSpline() { // Closed= true; // asName= "foo"; @@ -252,7 +252,7 @@ __fastcall TSpline::TSpline() // Next=Prev= this; } -__fastcall TSpline::TSpline(AnsiString asNName) + TSpline::TSpline(AnsiString asNName) { // Closed= true; // asName= asNName; @@ -263,7 +263,7 @@ __fastcall TSpline::TSpline(AnsiString asNName) // Next=Prev= this; } -__fastcall TSpline::~TSpline() + TSpline::~TSpline() { // if (KnotsAllocated) // SafeDeleteArray(Knots); @@ -473,7 +473,7 @@ vector3 TSpline::GetCenter() pt /= iNumKnots; } -TKnot *__fastcall TSpline::GetLastKnot() +TKnot * TSpline::GetLastKnot() { TKnot *ck; ck = RootKnot; diff --git a/Spline.h b/Spline.h index d60d2cf08..39d9aa6c3 100644 --- a/Spline.h +++ b/Spline.h @@ -74,7 +74,7 @@ class TSpline int Load(TQueryParserComp *Parser, AnsiString asEndString = "endspline"); float GetLength(); vector3 GetCenter(); - TKnot *__fastcall GetLastKnot(); + TKnot * GetLastKnot(); bool Render(); // inline int NextIndex(int n) { return (npTrack; @@ -264,7 +264,7 @@ TTrack *__fastcall TTrack::Create400m(int what, double dx) return trk; }; -TTrack *__fastcall TTrack::NullCreate(int dir) +TTrack * TTrack::NullCreate(int dir) { // tworzenie toru wykolejającego od strony (dir), albo pętli dla samochodów TGroundNode *tmp = new TGroundNode(TP_TRACK), *tmp2 = NULL; // node TTrack *trk = tmp->pTrack; // tor; UWAGA! obrotnica może generować duże ilości tego @@ -2828,7 +2828,7 @@ void TTrack::RaAnimListAdd(TTrack *t) } }; -TTrack *__fastcall TTrack::RaAnimate() +TTrack * TTrack::RaAnimate() { // wykonanie rekurencyjne animacji, wywoływane przed wyświetleniem sektora // zwraca wskaźnik toru wymagającego dalszej animacji if (SwitchExtension->pNextAnim) @@ -3146,7 +3146,7 @@ void TTrack::ConnectionsLog() } }; -TTrack *__fastcall TTrack::Neightbour(int s, double &d) +TTrack * TTrack::Neightbour(int s, double &d) { // zwraca wskaźnik na sąsiedni tor, w kierunku określonym znakiem (s), odwraca (d) w razie // niezgodności kierunku torów TTrack *t; // nie zmieniamy kierunku (d), jeśli nie ma toru dalej diff --git a/Track.h b/Track.h index cd81f9c1d..bf736ff45 100644 --- a/Track.h +++ b/Track.h @@ -108,18 +108,18 @@ class TIsolated TIsolated(); TIsolated(const AnsiString &n, TIsolated *i); ~TIsolated(); - static TIsolated *__fastcall Find( + static TIsolated * Find( const AnsiString &n); // znalezienie obiektu albo utworzenie nowego void Modify(int i, TDynamicObject *o); // dodanie lub odjęcie osi bool Busy() { return (iAxles > 0); }; - static TIsolated *__fastcall Root() + static TIsolated * Root() { return (pRoot); }; - TIsolated *__fastcall Next() + TIsolated * Next() { return (pNext); }; @@ -192,8 +192,8 @@ class TTrack : public Resource TTrack(TGroundNode *g); ~TTrack(); void Init(); - static TTrack *__fastcall Create400m(int what, double dx); - TTrack *__fastcall NullCreate(int dir); + static TTrack * Create400m(int what, double dx); + TTrack * NullCreate(int dir); inline bool IsEmpty() { return (iNumDynamics <= 0); @@ -206,19 +206,19 @@ class TTrack : public Resource { return Segment->GetLength(); }; - inline TSegment *__fastcall CurrentSegment() + inline TSegment * CurrentSegment() { return Segment; }; - inline TTrack *__fastcall CurrentNext() + inline TTrack * CurrentNext() { return (trNext); }; - inline TTrack *__fastcall CurrentPrev() + inline TTrack * CurrentPrev() { return (trPrev); }; - TTrack *__fastcall Neightbour(int s, double &d); + TTrack * Neightbour(int s, double &d); bool SetConnections(int i); bool Switch(int i, double t = -1.0, double d = -1.0); bool SwitchForced(int i, TDynamicObject *o); @@ -257,7 +257,7 @@ class TTrack : public Resource void RaAssign(TGroundNode *gn, TAnimContainer *ac); void RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined); void RaAnimListAdd(TTrack *t); - TTrack *__fastcall RaAnimate(); + TTrack * RaAnimate(); void RadioStop(); void AxleCounter(int i, TDynamicObject *o) diff --git a/Traction.cpp b/Traction.cpp index ee7efd063..c7750a057 100644 --- a/Traction.cpp +++ b/Traction.cpp @@ -680,7 +680,7 @@ double TTraction::VoltageGet(double u, double i) // 1. zasilacz psPower[0] z rezystancją fResistance[0] oraz jego wewnętrzną // 2. zasilacz psPower[1] z rezystancją fResistance[1] oraz jego wewnętrzną // 3. zasilacz psPowered z jego wewnętrzną rezystancją dla przęseł zasilanych bezpośrednio - double res = (i != 0.0) ? fabs(u / i) : 10000.0; + double res = (i != 0.0) ? (u / i) : 10000.0; if (psPowered) return psPowered->CurrentGet(res) * res; // yB: dla zasilanego nie baw się w gwiazdy, tylko bierz bezpośrednio diff --git a/TractionPower.cpp b/TractionPower.cpp index fb086879c..c2ee5c0d0 100644 --- a/TractionPower.cpp +++ b/TractionPower.cpp @@ -28,7 +28,7 @@ obtain one at //--------------------------------------------------------------------------- -TTractionPowerSource::TTractionPowerSource() +TTractionPowerSource::TTractionPowerSource(TGroundNode *node) { NominalVoltage = 0; VoltageFrequency = 0; @@ -49,6 +49,7 @@ TTractionPowerSource::TTractionPowerSource() psNode[0] = NULL; // sekcje zostaną podłączone do zasilaczy psNode[1] = NULL; bSection = false; // sekcja nie jest źródłem zasilania, tylko grupuje przęsła + gMyNode = node; }; TTractionPowerSource::~TTractionPowerSource(){}; @@ -62,7 +63,7 @@ void TTractionPowerSource::Init(double u, double i) bool TTractionPowerSource::Load(cParser *parser) { - std::string token; + std::string token; // AnsiString str; // str= Parser->GetNextSymbol()LowerCase(); // asName= str; @@ -98,7 +99,10 @@ bool TTractionPowerSource::Render() bool TTractionPowerSource::Update(double dt) { // powinno być wykonane raz na krok fizyki - if (NominalVoltage * TotalPreviousAdmitance > + // if (NominalVoltage * TotalPreviousAdmitance > + // MaxOutputCurrent * 0.00000005) // iloczyn napięcia i admitancji daje prąd + // ErrorLog("Power overload: \"" + gMyNode->asName + "\" with current " + AnsiString(NominalVoltage * TotalPreviousAdmitance) + "A"); + if (NominalVoltage * TotalPreviousAdmitance > MaxOutputCurrent) // iloczyn napięcia i admitancji daje prąd { FastFuse = true; @@ -145,14 +149,15 @@ double TTractionPowerSource::CurrentGet(double res) FuseTimer = 0; return 0; } - if ((res > 0) || ((res < 0) && (Recuperation))) - TotalAdmitance += + if ((res > 0) || ((res < 0) && (Recuperation || true))) + TotalAdmitance += 1.0 / res; // połączenie równoległe rezystancji jest równoważne sumie admitancji - TotalCurrent = (TotalPreviousAdmitance != 0.0) ? - NominalVoltage / (InternalRes + 1.0 / TotalPreviousAdmitance) : - 0.0; // napięcie dzielone przez sumę rezystancji wewnętrznej i obciążenia - OutputVoltage = NominalVoltage - InternalRes * TotalCurrent; // napięcie na obciążeniu - return TotalCurrent / (res * TotalPreviousAdmitance); // prąd proporcjonalny do udziału (1/res) + float NomVolt = (TotalPreviousAdmitance < 0 ? NominalVoltage * 1.083 : NominalVoltage); + TotalCurrent = (TotalPreviousAdmitance != 0.0) ? + NomVolt / (InternalRes + 1.0 / TotalPreviousAdmitance) : + 0.0; // napięcie dzielone przez sumę rezystancji wewnętrznej i obciążenia + OutputVoltage = NomVolt - InternalRes * TotalCurrent; // napięcie na obciążeniu + return TotalCurrent / (res * TotalPreviousAdmitance); // prąd proporcjonalny do udziału (1/res) // w całkowitej admitancji }; diff --git a/TractionPower.h b/TractionPower.h index 5ba2599f7..8099e6776 100644 --- a/TractionPower.h +++ b/TractionPower.h @@ -33,15 +33,15 @@ class TTractionPowerSource bool SlowFuse; double FuseTimer; int FuseCounter; + TGroundNode *gMyNode; // wskaźnik na węzeł rodzica protected: public: // zmienne publiczne TTractionPowerSource *psNode[2]; // zasilanie na końcach dla sekcji bool bSection; // czy jest sekcją - TGroundNode *gMyNode; // Ra 2015-03: znowu prowizorka, aby mieć nazwę do logowania public: // AnsiString asName; - TTractionPowerSource(); + TTractionPowerSource(TGroundNode *node); ~TTractionPowerSource(); void Init(double u, double i); bool Load(cParser *parser); diff --git a/Train.cpp b/Train.cpp index 05f0e34a4..538c572cd 100644 --- a/Train.cpp +++ b/Train.cpp @@ -95,7 +95,7 @@ TCab::~TCab() delete[] btList; }; -TGauge *__fastcall TCab::Gauge(int n) +TGauge * TCab::Gauge(int n) { // pobranie adresu obiektu aniomowanego ruchem if (n < 0) { // rezerwacja wolnego @@ -106,7 +106,7 @@ TGauge *__fastcall TCab::Gauge(int n) return ggList + n; return NULL; }; -TButton *__fastcall TCab::Button(int n) +TButton * TCab::Button(int n) { // pobranie adresu obiektu animowanego wyborem 1 z 2 if (n < 0) { // rezerwacja wolnego @@ -127,7 +127,7 @@ void TCab::Update() } for (i = 0; i < iButtons; ++i) { // animacje dwustanowe - // btList[i].Update(); //odczyt parametru i wybór submodelu + btList[i].Update(); // odczyt parametru i wybór submodelu } }; @@ -232,9 +232,10 @@ bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d) // McZapkie: jazda luzem: // dsbRunningNoise=TSoundsManager::GetFromName("runningnoise.wav"); - // McZapkie? - dzwieki slyszalne tylko wewnatrz kabiny - generowane przez obiekt sterowany: + // McZapkie? - dzwieki slyszalne tylko wewnatrz kabiny - generowane przez + // obiekt sterowany: - // McZapkie-080302 sWentylatory.Init("wenton.wav","went.wav","wentoff.wav"); + // McZapkie-080302 sWentylatory.Init("wenton.wav","went.wav","wentoff.wav"); // McZapkie-010302 // sCompressor.Init("compressor-start.wav","compressor.wav","compressor-stop.wav"); @@ -260,733 +261,879 @@ bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d) return true; } -void TTrain::OnKeyDown(int cKey) -{ // naciśnięcie klawisza - bool isEztOer; - isEztOer = ((mvControlled->TrainType == dt_EZT) && (mvControlled->Battery == true) && - (mvControlled->EpFuse == true) && (mvOccupied->BrakeSubsystem == ss_ESt) && - (mvControlled->ActiveDir != 0)); // od yB - // isEztOer=(mvControlled->TrainType==dt_EZT)&&(mvControlled->Mains)&&(mvOccupied->BrakeSubsystem==ss_ESt)&&(mvControlled->ActiveDir!=0); - // isEztOer=((mvControlled->TrainType==dt_EZT)&&(mvControlled->Battery==true)&&(mvControlled->EpFuse==true)&&(mvOccupied->BrakeSubsystem==Oerlikon)&&(mvControlled->ActiveDir!=0)); - - if (GetAsyncKeyState(VK_SHIFT) < 0) - { // wciśnięty [Shift] - if (cKey == Global::Keys[k_IncMainCtrlFAST]) // McZapkie-200702: szybkie przelaczanie na - // poz. bezoporowa - { - if (mvControlled->IncMainCtrl(2)) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - } - else if (cKey == Global::Keys[k_DirectionBackward]) - { - if (mvControlled->Radio == false) - if (GetAsyncKeyState(VK_CONTROL) >= 0) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - mvControlled->Radio = true; - } - } - else - - if (cKey == Global::Keys[k_DecMainCtrlFAST]) - if (mvControlled->DecMainCtrl(2)) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - else - ; - else if (cKey == Global::Keys[k_IncScndCtrlFAST]) - if (mvControlled->IncScndCtrl(2)) - { - if (dsbNastawnikBocz) // hunter-081211 - { - dsbNastawnikBocz->SetCurrentPosition(0); - dsbNastawnikBocz->Play(0, 0, 0); - } - else if (!dsbNastawnikBocz) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - } - else - ; - else if (cKey == Global::Keys[k_DecScndCtrlFAST]) - if (mvControlled->DecScndCtrl(2)) - { - if (dsbNastawnikBocz) // hunter-081211 - { - dsbNastawnikBocz->SetCurrentPosition(0); - dsbNastawnikBocz->Play(0, 0, 0); - } - else if (!dsbNastawnikBocz) - { - dsbNastawnikJazdy->SetCurrentPosition(0); - dsbNastawnikJazdy->Play(0, 0, 0); - } - } - else - ; - else if (cKey == Global::Keys[k_IncLocalBrakeLevelFAST]) - if (mvOccupied->IncLocalBrakeLevel(2)) - ; - else - ; - else if (cKey == Global::Keys[k_DecLocalBrakeLevelFAST]) - if (mvOccupied->DecLocalBrakeLevel(2)) - ; - else - ; - // McZapkie-240302 - wlaczanie glownego obwodu klawiszem M+shift - //----------- - // hunter-141211: wyl. szybki zalaczony przeniesiony do TTrain::Update() - /* if (cKey==Global::Keys[k_Main]) - { - ggMainOnButton.PutValue(1); - if (mvControlled->MainSwitch(true)) - { - if (mvControlled->EngineType==DieselEngine) - dsbDieselIgnition->Play(0,0,0); - else - dsbNastawnikJazdy->Play(0,0,0); - } - } - else */ - if (cKey == Global::Keys[k_Battery]) - { - // if - // (((mvControlled->TrainType==dt_EZT)||(mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->EngineType==DieselElectric))&&(!mvControlled->Battery)) - if (!mvControlled->Battery) - { // wyłącznik jest też w SN61, ewentualnie załączać prąd na stałe z poziomu FIZ - if (mvOccupied->BatterySwitch(true)) // bateria potrzebna np. do zapalenia świateł - { - dsbSwitch->Play(0, 0, 0); - if (TestFlag(mvOccupied->SecuritySystem.SystemType, - 2)) // Ra: znowu w kabinie jest coś, co być nie powinno! - { - SetFlag(mvOccupied->SecuritySystem.Status, s_active); - SetFlag(mvOccupied->SecuritySystem.Status, s_SHPalarm); - } - } - } - } - else if (cKey == Global::Keys[k_StLinOff]) - { - if (mvControlled->TrainType == dt_EZT) - { - if ((mvControlled->Signalling == false)) - { - dsbSwitch->Play(0, 0, 0); - mvControlled->Signalling = true; - } - } - } - else if (cKey == Global::Keys[k_Sand]) - { - if (mvControlled->TrainType == dt_EZT) - { - if (!mvControlled->DoorSignalling) - { - dsbSwitch->Play(0, 0, 0); - mvControlled->DoorSignalling = true; - } - } - } - if (cKey == Global::Keys[k_Main]) - { - if (fabs(ggMainOnButton.GetValue()) < 0.001) - if (dsbSwitch) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else - //----------- - - if (cKey == - Global::Keys[k_BrakeProfile]) // McZapkie-240302-B: przelacznik opoznienia hamowania - { // yB://ABu: male poprawki, zeby bylo mozna ustawic dowolny wagon - int CouplNr = -2; - if (!FreeFlyModeFlag) - { - if (GetAsyncKeyState(VK_CONTROL) < 0) - if (mvOccupied->BrakeDelaySwitch(bdelay_R + bdelay_M)) - { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); - } - else - ; - else if (mvOccupied->BrakeDelaySwitch(bdelay_P)) - { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); - } - } - else - { - TDynamicObject *temp; - temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, 1500, - CouplNr)); - if (temp == NULL) - { - CouplNr = -2; - temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, - CouplNr)); - } - if (temp) - { - if (GetAsyncKeyState(VK_CONTROL) < 0) - if (temp->MoverParameters->BrakeDelaySwitch(bdelay_R + bdelay_M)) - { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); - } - else - ; - else if (temp->MoverParameters->BrakeDelaySwitch(bdelay_P)) - { - dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); - dsbPneumaticRelay->Play(0, 0, 0); - } - } - } - } - else - //----------- - // hunter-261211: przetwornica i sprzezarka przeniesione do TTrain::Update() - /* if (cKey==Global::Keys[k_Converter]) //NBMX 14-09-2003: przetwornica wl - { - if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || - (mvControlled->EnginePowerSource.SourceType!=CurrentCollector) || - (!Global::bLiveTraction)) - if (mvControlled->ConverterSwitch(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0,0,0); - } - } - else - if (cKey==Global::Keys[k_Compressor]) //NBMX 14-09-2003: sprezarka wl - { - if ((mvControlled->ConverterFlag) || (mvControlled->CompressorPower<2)) - if (mvControlled->CompressorSwitch(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0,0,0); - } - } - else */ - - if (cKey == Global::Keys[k_Converter]) - { - if (ggConverterButton.GetValue() == 0) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else - // if - // ((cKey==Global::Keys[k_Compressor])&&((mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->TrainType==dt_EZT))) - // //hunter-110212: poprawka dla EZT - if ((cKey == Global::Keys[k_Compressor]) && - (mvControlled->CompressorPower < 2)) // hunter-091012: tak jest poprawnie - { - if (ggCompressorButton.GetValue() == 0) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else if (cKey == Global::Keys[k_SmallCompressor]) // Winger 160404: mala sprezarka wl - { // Ra: dźwięk, gdy razem z [Shift] - if ((mvControlled->TrainType & dt_EZT) ? mvControlled == mvOccupied : - !mvOccupied->ActiveCab) // tylko w maszynowym - if (Console::Pressed(VK_CONTROL)) // z [Ctrl] - mvControlled->bPantKurek3 = true; // zbiornik pantografu połączony jest ze - // zbiornikiem głównym (pompowanie nie ma - // sensu) - else if (!mvControlled->PantCompFlag) // jeśli wyłączona - if (mvControlled->Battery) // jeszcze musi być załączona bateria - if (mvControlled->PantPress < 4.8) // piszą, że to tak nie działa - { - mvControlled->PantCompFlag = true; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); // dźwięk tylko po naciśnięciu klawisza - } - } - else if (cKey == VkKeyScan('q')) // ze Shiftem - włączenie AI - { // McZapkie-240302 - wlaczanie automatycznego pilota (zadziala tylko w trybie debugmode) - if (DynamicObject->Mechanik) - { - if (DebugModeFlag) - if (DynamicObject->Mechanik - ->AIControllFlag) //żeby nie trzeba było rozłączać dla zresetowania - DynamicObject->Mechanik->TakeControl(false); - DynamicObject->Mechanik->TakeControl(true); - } - } - else if (cKey == Global::Keys[k_MaxCurrent]) // McZapkie-160502: F - wysoki rozruch - { - if ((mvControlled->EngineType == DieselElectric) && (mvControlled->ShuntModeAllow) && - (mvControlled->MainCtrlPos == 0)) - { - mvControlled->ShuntMode = true; - } - if (mvControlled->CurrentSwitch(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - /* Ra: przeniesione do Mover.cpp - if (mvControlled->TrainType!=dt_EZT) //to powinno być w fizyce, a nie w kabinie! - if (mvControlled->MinCurrentSwitch(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0,0,0); - } - */ - } - else if (cKey == Global::Keys[k_CurrentAutoRelay]) // McZapkie-241002: G - wlaczanie PSR - { - if (mvControlled->AutoRelaySwitch(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else if (cKey == Global::Keys[k_FailedEngineCutOff]) // McZapkie-060103: E - wylaczanie - // sekcji silnikow - { - if (mvControlled->CutOffEngine()) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else if (cKey == Global::Keys[k_OpenLeft]) // NBMX 17-09-2003: otwieranie drzwi - { - if (mvOccupied->DoorOpenCtrl == 1) - if (mvOccupied->CabNo < 0 ? mvOccupied->DoorRight(true) : - mvOccupied->DoorLeft(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (dsbDoorOpen) - { - dsbDoorOpen->SetCurrentPosition(0); - dsbDoorOpen->Play(0, 0, 0); - } - } - } - else if (cKey == Global::Keys[k_OpenRight]) // NBMX 17-09-2003: otwieranie drzwi - { - if (mvOccupied->DoorCloseCtrl == 1) - if (mvOccupied->CabNo < 0 ? mvOccupied->DoorLeft(true) : - mvOccupied->DoorRight(true)) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (dsbDoorOpen) - { - dsbDoorOpen->SetCurrentPosition(0); - dsbDoorOpen->Play(0, 0, 0); - } - } - } - else - //----------- - // hunter-131211: dzwiek dla przelacznika universala podniesionego - // hunter-091012: ubajerowanie swiatla w kabinie (wyrzucenie przyciemnienia pod Univ4) - if (cKey == Global::Keys[k_Univ3]) - { - if (Console::Pressed(VK_CONTROL)) - { - if (bCabLight == false) //(ggCabLightButton.GetValue()==0) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else - { - if (ggUniversal3Button.GetValue() == 0) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - /* - if (Console::Pressed(VK_CONTROL)) - {//z [Ctrl] zapalamy albo gasimy światełko w kabinie - if (iCabLightFlag<2) ++iCabLightFlag; //zapalenie - } - */ - } - } - else - //----------- - // hunter-091012: dzwiek dla przyciemnienia swiatelka w kabinie - if (cKey == Global::Keys[k_Univ4]) - { - if (Console::Pressed(VK_CONTROL)) - { - if (bCabLightDim == false) //(ggCabLightDimButton.GetValue()==0) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - } - else - //----------- - if (cKey == Global::Keys[k_PantFrontUp]) - { // Winger 160204: podn. przedn. pantografu - if (mvOccupied->ActiveCab == - 1) //||((mvOccupied->ActiveCab<1)&&((mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))==0))) - { // przedni gdy w kabinie 1 lub (z wyjątkiem ET40, ET41, ET42 i EZT) gdy w kabinie -1 - mvControlled->PantFrontSP = false; - if (mvControlled->PantFront(true)) - if (mvControlled->PantFrontStart != 1) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else - // if - // ((mvOccupied->ActiveCab<1)&&(mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))) - { // w kabinie -1 dla ET40, ET41, ET42 i EZT - mvControlled->PantRearSP = false; - if (mvControlled->PantRear(true)) - if (mvControlled->PantRearStart != 1) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - } - else if (cKey == Global::Keys[k_PantRearUp]) - { // Winger 160204: podn. tyln. pantografu względem kierunku jazdy - if (mvOccupied->ActiveCab == - 1) //||((mvOccupied->ActiveCab<1)&&((mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))==0))) - { // tylny gdy w kabinie 1 lub (z wyjątkiem ET40, ET41, ET42 i EZT) gdy w kabinie -1 - mvControlled->PantRearSP = false; - if (mvControlled->PantRear(true)) - if (mvControlled->PantRearStart != 1) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - else - // if - // ((mvOccupied->ActiveCab<1)&&(mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))) - { // przedni w kabinie -1 dla ET40, ET41, ET42 i EZT - mvControlled->PantFrontSP = false; - if (mvControlled->PantFront(true)) - if (mvControlled->PantFrontStart != 1) - { - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - } - else if (cKey == Global::Keys[k_Active]) // yB 300407: przelacznik rozrzadu - { // Ra 2014-06: uruchomiłem to, aby aktywować czuwak w zajmowanym członie, a wyłączyć w - // innych - // Ra 2014-03: aktywacja czuwaka przepięta na ustawienie kierunku w mvOccupied - // if (mvControlled->Battery) //jeśli bateria jest już załączona - // mvOccupied->BatterySwitch(true); //to w ten oto durny sposób aktywuje się CA/SHP - // if (mvControlled->CabActivisation()) - // { - // dsbSwitch->SetVolume(DSBVOLUME_MAX); - // dsbSwitch->Play(0,0,0); - // } - } - else if (cKey == Global::Keys[k_Heating]) // Winger 020304: ogrzewanie skladu - wlaczenie - { // Ra 2014-09: w trybie latania obsługa jest w World.cpp - if (!FreeFlyModeFlag) - { - if ((mvControlled->Heating == false) && - ((mvControlled->EngineType == ElectricSeriesMotor) && - (mvControlled->Mains == true) || - (mvControlled->ConverterFlag))) - { - mvControlled->Heating = true; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - } - } - } - else - // ABu 060205: dzielo Wingera po malutkim liftingu: - if (cKey == Global::Keys[k_LeftSign]) // lewe swiatlo - włączenie - { - if ((GetAsyncKeyState(VK_CONTROL) < 0) && - (ggRearLeftLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu - { - //------------------------------ - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[1]) & 3) == 0) - { - DynamicObject->iLights[1] |= 1; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearLeftLightButton.PutValue(1); - } - if (((DynamicObject->iLights[1]) & 3) == 2) - { - DynamicObject->iLights[1] &= (255 - 2); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRearLeftEndLightButton.SubModel) - { - ggRearLeftEndLightButton.PutValue(0); - ggRearLeftLightButton.PutValue(0); - } - else - ggRearLeftLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[0]) & 3) == 0) - { - DynamicObject->iLights[0] |= 1; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearLeftLightButton.PutValue(1); - } - if (((DynamicObject->iLights[0]) & 3) == 2) - { - DynamicObject->iLights[0] &= (255 - 2); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRearLeftEndLightButton.SubModel) - { - ggRearLeftEndLightButton.PutValue(0); - ggRearLeftLightButton.PutValue(0); - } - else - ggRearLeftLightButton.PutValue(0); - } - } - //---------------------- - } - else - { - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[0]) & 3) == 0) - { - DynamicObject->iLights[0] |= 1; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggLeftLightButton.PutValue(1); - } - if (((DynamicObject->iLights[0]) & 3) == 2) - { - DynamicObject->iLights[0] &= (255 - 2); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggLeftEndLightButton.SubModel) - { - ggLeftEndLightButton.PutValue(0); - ggLeftLightButton.PutValue(0); - } - else - ggLeftLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[1]) & 3) == 0) - { - DynamicObject->iLights[1] |= 1; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggLeftLightButton.PutValue(1); - } - if (((DynamicObject->iLights[1]) & 3) == 2) - { - DynamicObject->iLights[1] &= (255 - 2); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggLeftEndLightButton.SubModel) - { - ggLeftEndLightButton.PutValue(0); - ggLeftLightButton.PutValue(0); - } - else - ggLeftLightButton.PutValue(0); - } - } - } //----------- - } - else if (cKey == Global::Keys[k_UpperSign]) // ABu 060205: światło górne - włączenie - { - if ((GetAsyncKeyState(VK_CONTROL) < 0) && - (ggRearUpperLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu - { - //------------------------------ - if ((mvOccupied->ActiveCab) == 1) - { // kabina 1 - if (((DynamicObject->iLights[1]) & 12) == 0) - { - DynamicObject->iLights[1] |= 4; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearUpperLightButton.PutValue(1); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[0]) & 12) == 0) - { - DynamicObject->iLights[0] |= 4; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearUpperLightButton.PutValue(1); - } - } - } //------------------------------ - else - { - if ((mvOccupied->ActiveCab) == 1) - { // kabina 1 - if (((DynamicObject->iLights[0]) & 12) == 0) - { - DynamicObject->iLights[0] |= 4; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggUpperLightButton.PutValue(1); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[1]) & 12) == 0) - { - DynamicObject->iLights[1] |= 4; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggUpperLightButton.PutValue(1); - } - } - } - } - else if (cKey == - Global::Keys[k_RightSign]) // Winger 070304: swiatla tylne (koncowki) - wlaczenie - { - if ((GetAsyncKeyState(VK_CONTROL) < 0) && - (ggRearRightLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu - { - //------------------------------ - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[1]) & 48) == 0) - { - DynamicObject->iLights[1] |= 16; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearRightLightButton.PutValue(1); - } - if (((DynamicObject->iLights[1]) & 48) == 32) - { - DynamicObject->iLights[1] &= (255 - 32); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRearRightEndLightButton.SubModel) - { - ggRearRightEndLightButton.PutValue(0); - ggRearRightLightButton.PutValue(0); - } - else - ggRearRightLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[0]) & 48) == 0) - { - DynamicObject->iLights[0] |= 16; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearRightLightButton.PutValue(1); - } - if (((DynamicObject->iLights[0]) & 48) == 32) - { - DynamicObject->iLights[0] &= (255 - 32); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRearRightEndLightButton.SubModel) - { - ggRearRightEndLightButton.PutValue(0); - ggRearRightLightButton.PutValue(0); - } - else - ggRearRightLightButton.PutValue(0); - } - } - } //------------------------------ - else - { - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[0]) & 48) == 0) - { - DynamicObject->iLights[0] |= 16; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRightLightButton.PutValue(1); - } - if (((DynamicObject->iLights[0]) & 48) == 32) - { - DynamicObject->iLights[0] &= (255 - 32); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRightEndLightButton.SubModel) - { - ggRightEndLightButton.PutValue(0); - ggRightLightButton.PutValue(0); - } - else - ggRightLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[1]) & 48) == 0) - { - DynamicObject->iLights[1] |= 16; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRightLightButton.PutValue(1); - } - if (((DynamicObject->iLights[1]) & 48) == 32) - { - DynamicObject->iLights[1] &= (255 - 32); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRightEndLightButton.SubModel) - { - ggRightEndLightButton.PutValue(0); - ggRightLightButton.PutValue(0); - } - else - ggRightLightButton.PutValue(0); - } - } - } - } +PyObject *TTrain::GetTrainState() +{ + PyObject *dict = PyDict_New(); + if (dict == NULL) + { + return NULL; } + + PyDict_SetItemString(dict, "direction", PyGetInt(DynamicObject->MoverParameters->ActiveDir)); + PyDict_SetItemString(dict, "cab", PyGetInt(DynamicObject->MoverParameters->ActiveCab)); + PyDict_SetItemString(dict, "slipping_wheels", + PyGetBool(DynamicObject->MoverParameters->SlippingWheels)); + PyDict_SetItemString(dict, "converter", + PyGetBool(DynamicObject->MoverParameters->ConverterFlag)); + PyDict_SetItemString(dict, "main_ctrl_actual_pos", + PyGetInt(DynamicObject->MoverParameters->MainCtrlActualPos)); + PyDict_SetItemString(dict, "scnd_ctrl_actual_pos", + PyGetInt(DynamicObject->MoverParameters->ScndCtrlActualPos)); + PyDict_SetItemString(dict, "fuse", PyGetBool(DynamicObject->MoverParameters->FuseFlag)); + PyDict_SetItemString(dict, "converter_overload", + PyGetBool(DynamicObject->MoverParameters->ConvOvldFlag)); + PyDict_SetItemString(dict, "voltage", PyGetFloat(DynamicObject->MoverParameters->Voltage)); + PyDict_SetItemString(dict, "velocity", PyGetFloat(DynamicObject->MoverParameters->Vel)); + PyDict_SetItemString(dict, "im", PyGetFloat(DynamicObject->MoverParameters->Im)); + PyDict_SetItemString(dict, "compress", + PyGetBool(DynamicObject->MoverParameters->CompressorFlag)); + PyDict_SetItemString(dict, "hours", PyGetInt(GlobalTime->hh)); + PyDict_SetItemString(dict, "minutes", PyGetInt(GlobalTime->mm)); + PyDict_SetItemString(dict, "seconds", PyGetInt(GlobalTime->mr)); + PyDict_SetItemString(dict, "velocity_desired", PyGetFloat(DynamicObject->Mechanik->VelDesired)); + Char* TXTT[10] = { "fd","fdt","fdb","pd","pdt","pdb","itothv","1","2","3" }; + Char* TXTC[10] = { "fr","frt","frb","pr","prt","prb","im","vm","ihv","uhv" }; + Char* TXTP[3] = { "bc","bp","sp" }; + for (int j = 0; j<10; j++) + PyDict_SetItemString(dict, (AnsiString("eimp_t_") + AnsiString(TXTT[j])).c_str(), PyGetFloatS(fEIMParams[0][j])); + for (int i = 0; i<8; i++) + { + for (int j = 0; j<10; j++) + PyDict_SetItemString(dict, (AnsiString("eimp_c") + IntToStr(i + 1) + AnsiString("_") + AnsiString(TXTC[j])).c_str(), PyGetFloatS(fEIMParams[i + 1][j])); + PyDict_SetItemString(dict, (AnsiString("eimp_c") + IntToStr(i + 1) + AnsiString("_ms")).c_str(), PyGetBool(bMains[i])); + PyDict_SetItemString(dict, (AnsiString("eimp_c") + IntToStr(i + 1) + AnsiString("_cv")).c_str(), PyGetFloatS(fCntVol[i])); + PyDict_SetItemString(dict, (AnsiString("eimp_u") + IntToStr(i + 1) + AnsiString("_pf")).c_str(), PyGetBool(bPants[i][0])); + PyDict_SetItemString(dict, (AnsiString("eimp_u") + IntToStr(i + 1) + AnsiString("_pr")).c_str(), PyGetBool(bPants[i][1])); + PyDict_SetItemString(dict, (AnsiString("eimp_c") + IntToStr(i + 1) + AnsiString("_fuse")).c_str(), PyGetBool(bFuse[i])); + PyDict_SetItemString(dict, (AnsiString("eimp_c") + IntToStr(i + 1) + AnsiString("_batt")).c_str(), PyGetBool(bBatt[i])); + PyDict_SetItemString(dict, (AnsiString("eimp_c") + IntToStr(i + 1) + AnsiString("_conv")).c_str(), PyGetBool(bConv[i])); + PyDict_SetItemString(dict, (AnsiString("eimp_u") + IntToStr(i + 1) + AnsiString("_comp_a")).c_str(), PyGetBool(bComp[i][0])); + PyDict_SetItemString(dict, (AnsiString("eimp_u") + IntToStr(i + 1) + AnsiString("_comp_w")).c_str(), PyGetBool(bComp[i][1])); + PyDict_SetItemString(dict, (AnsiString("eimp_c") + IntToStr(i + 1) + AnsiString("_heat")).c_str(), PyGetBool(bHeat[i])); + + } + for (int i = 0; i<20; i++) + { + for (int j = 0; j<3; j++) + PyDict_SetItemString(dict, (AnsiString("eimp_pn") + IntToStr(i + 1) + AnsiString("_") + AnsiString(TXTP[j])).c_str(), + PyGetFloatS(fPress[i][j])); + } + bool bEP, bPN; + bEP = (mvControlled->LocHandle->GetCP()>0.2) || (fEIMParams[0][2]>0.01); + PyDict_SetItemString(dict, "dir_brake", PyGetBool(bEP)); + if (mvControlled->Hamulec->ClassNameIs("TLSt") || mvControlled->Hamulec->ClassNameIs("TEStED")) + { + TBrake* temp_ham = mvControlled->Hamulec; + // TLSt* temp_ham2 = temp_ham; + bPN = (static_cast(temp_ham)->GetEDBCP()>0.2); + } + else + bPN = false; + PyDict_SetItemString(dict, "indir_brake", PyGetBool(bPN)); + for (int i = 0; i<20; i++) + { + PyDict_SetItemString(dict, (AnsiString("doors_") + IntToStr(i + 1)).c_str(), PyGetFloatS(bDoors[i][0])); + PyDict_SetItemString(dict, (AnsiString("doors_r_") + IntToStr(i + 1)).c_str(), PyGetFloatS(bDoors[i][1])); + PyDict_SetItemString(dict, (AnsiString("doors_l_") + IntToStr(i + 1)).c_str(), PyGetFloatS(bDoors[i][2])); + PyDict_SetItemString(dict, (AnsiString("doors_no_") + IntToStr(i + 1)).c_str(), PyGetInt(iDoorNo[i])); + PyDict_SetItemString(dict, (AnsiString("code_") + IntToStr(i + 1)).c_str(), PyGetString(AnsiString(IntToStr(iUnits[i]) + + cCode[i]).c_str())); + PyDict_SetItemString(dict, (AnsiString("car_name") + IntToStr(i + 1)).c_str(), PyGetString(asCarName[i].c_str())); + } + PyDict_SetItemString(dict, "car_no", PyGetInt(iCarNo)); + PyDict_SetItemString(dict, "power_no", PyGetInt(iPowerNo)); + PyDict_SetItemString(dict, "unit_no", PyGetInt(iUnitNo)); + PyDict_SetItemString(dict, "universal3", PyGetBool(LampkaUniversal3_st)); + PyDict_SetItemString(dict, "ca", PyGetBool(TestFlag(mvOccupied->SecuritySystem.Status, s_aware))); + PyDict_SetItemString(dict, "shp", PyGetBool(TestFlag(mvOccupied->SecuritySystem.Status, s_active))); + PyDict_SetItemString(dict, "manual_brake", PyGetBool(mvOccupied->ManualBrakePos > 0)); + PyDict_SetItemString(dict, "pantpress", PyGetFloat(mvControlled->PantPress)); + PyDict_SetItemString(dict, "trainnumber", PyGetString(DynamicObject->Mechanik->TrainName().c_str())); + + return dict; +} + +void TTrain::OnKeyDown(int cKey) +{ // naciśnięcie klawisza + bool isEztOer; + isEztOer = ((mvControlled->TrainType == dt_EZT) && (mvControlled->Battery == true) && + (mvControlled->EpFuse == true) && (mvOccupied->BrakeSubsystem == ss_ESt) && + (mvControlled->ActiveDir != 0)); // od yB + // isEztOer=(mvControlled->TrainType==dt_EZT)&&(mvControlled->Mains)&&(mvOccupied->BrakeSubsystem==ss_ESt)&&(mvControlled->ActiveDir!=0); + // isEztOer=((mvControlled->TrainType==dt_EZT)&&(mvControlled->Battery==true)&&(mvControlled->EpFuse==true)&&(mvOccupied->BrakeSubsystem==Oerlikon)&&(mvControlled->ActiveDir!=0)); + + if (GetAsyncKeyState(VK_SHIFT) < 0) + { // wciśnięty [Shift] + if (cKey == Global::Keys[k_IncMainCtrlFAST]) // McZapkie-200702: szybkie + // przelaczanie na poz. + // bezoporowa + { + if (mvControlled->IncMainCtrl(2)) + { + dsbNastawnikJazdy->SetCurrentPosition(0); + dsbNastawnikJazdy->Play(0, 0, 0); + } + } + else if (cKey == Global::Keys[k_DirectionBackward]) + { + if (mvOccupied->Radio == false) + if (GetAsyncKeyState(VK_CONTROL) >= 0) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + mvOccupied->Radio = true; + } + } + else if (cKey == Global::Keys[k_DecMainCtrlFAST]) + if (mvControlled->DecMainCtrl(2)) + { + dsbNastawnikJazdy->SetCurrentPosition(0); + dsbNastawnikJazdy->Play(0, 0, 0); + } + else + ; + else if (cKey == Global::Keys[k_IncScndCtrlFAST]) + if (mvControlled->IncScndCtrl(2)) + { + if (dsbNastawnikBocz) // hunter-081211 + { + dsbNastawnikBocz->SetCurrentPosition(0); + dsbNastawnikBocz->Play(0, 0, 0); + } + else if (!dsbNastawnikBocz) + { + dsbNastawnikJazdy->SetCurrentPosition(0); + dsbNastawnikJazdy->Play(0, 0, 0); + } + } + else + ; + else if (cKey == Global::Keys[k_DecScndCtrlFAST]) + if (mvControlled->DecScndCtrl(2)) + { + if (dsbNastawnikBocz) // hunter-081211 + { + dsbNastawnikBocz->SetCurrentPosition(0); + dsbNastawnikBocz->Play(0, 0, 0); + } + else if (!dsbNastawnikBocz) + { + dsbNastawnikJazdy->SetCurrentPosition(0); + dsbNastawnikJazdy->Play(0, 0, 0); + } + } + else + ; + else if (cKey == Global::Keys[k_IncLocalBrakeLevelFAST]) + if (mvOccupied->IncLocalBrakeLevel(2)) + ; + else + ; + else if (cKey == Global::Keys[k_DecLocalBrakeLevelFAST]) + if (mvOccupied->DecLocalBrakeLevel(2)) + ; + else + ; + // McZapkie-240302 - wlaczanie glownego obwodu klawiszem M+shift + //----------- + // hunter-141211: wyl. szybki zalaczony przeniesiony do TTrain::Update() + /* if (cKey==Global::Keys[k_Main]) + { + ggMainOnButton.PutValue(1); + if (mvControlled->MainSwitch(true)) + { + if (mvControlled->EngineType==DieselEngine) + dsbDieselIgnition->Play(0,0,0); + else + dsbNastawnikJazdy->Play(0,0,0); + } + } + else */ + if (cKey == Global::Keys[k_Battery]) + { + // if + // (((mvControlled->TrainType==dt_EZT)||(mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->EngineType==DieselElectric))&&(!mvControlled->Battery)) + if (!mvControlled->Battery) + { // wyłącznik jest też w SN61, ewentualnie + // załączać prąd na stałe z poziomu FIZ + if (mvOccupied->BatterySwitch(true)) // bateria potrzebna np. do zapalenia świateł + { + dsbSwitch->Play(0, 0, 0); + SetLights(); + if (TestFlag(mvOccupied->SecuritySystem.SystemType, + 2)) // Ra: znowu w kabinie jest coś, co być nie powinno! + { + SetFlag(mvOccupied->SecuritySystem.Status, s_active); + SetFlag(mvOccupied->SecuritySystem.Status, s_SHPalarm); + } + } + } + } + else if (cKey == Global::Keys[k_StLinOff]) + { + if (mvControlled->TrainType == dt_EZT) + { + if ((mvControlled->Signalling == false)) + { + dsbSwitch->Play(0, 0, 0); + mvControlled->Signalling = true; + } + } + } + else if (cKey == Global::Keys[k_Sand]) + { + if (mvControlled->TrainType == dt_EZT) + { + if (ggDoorSignallingButton.SubModel != NULL) + { + if (!mvControlled->DoorSignalling) + { + mvOccupied->DoorBlocked = true; + dsbSwitch->Play(0, 0, 0); + mvControlled->DoorSignalling = true; + } + } + } + else if (mvControlled->TrainType != dt_EZT) + { + if (ggSandButton.SubModel != NULL) + { + ggSandButton.PutValue(1); + // dsbPneumaticRelay->SetVolume(-80); + // dsbPneumaticRelay->Play(0, 0, 0); + } + } + } + if (cKey == Global::Keys[k_Main]) + { + if (fabs(ggMainOnButton.GetValue()) < 0.001) + if (dsbSwitch) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + else if (cKey == Global::Keys[k_BrakeProfile]) // McZapkie-240302-B: + //----------- + + + // przelacznik opoznienia + // hamowania + { // yB://ABu: male poprawki, zeby bylo mozna ustawic dowolny wagon + int CouplNr = -2; + if (!FreeFlyModeFlag) + { + if (GetAsyncKeyState(VK_CONTROL) < 0) + if (mvOccupied->BrakeDelaySwitch(bdelay_R + bdelay_M)) + { + dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); + dsbPneumaticRelay->Play(0, 0, 0); + } + else + ; + else if (mvOccupied->BrakeDelaySwitch(bdelay_P)) + { + dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); + dsbPneumaticRelay->Play(0, 0, 0); + } + } + else + { + TDynamicObject *temp; + temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), -1, 1500, + CouplNr)); + if (temp == NULL) + { + CouplNr = -2; + temp = (DynamicObject->ABuScanNearestObject(DynamicObject->GetTrack(), 1, 1500, + CouplNr)); + } + if (temp) + { + if (GetAsyncKeyState(VK_CONTROL) < 0) + if (temp->MoverParameters->BrakeDelaySwitch(bdelay_R + bdelay_M)) + { + dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); + dsbPneumaticRelay->Play(0, 0, 0); + } + else + ; + else if (temp->MoverParameters->BrakeDelaySwitch(bdelay_P)) + { + dsbPneumaticRelay->SetVolume(DSBVOLUME_MAX); + dsbPneumaticRelay->Play(0, 0, 0); + } + } + } + } + //----------- + // hunter-261211: przetwornica i sprzezarka przeniesione do + // TTrain::Update() + /* if (cKey==Global::Keys[k_Converter]) //NBMX 14-09-2003: + przetwornica wl + { + if ((mvControlled->PantFrontVolt) || (mvControlled->PantRearVolt) || + (mvControlled->EnginePowerSource.SourceType!=CurrentCollector) || + (!Global::bLiveTraction)) + if (mvControlled->ConverterSwitch(true)) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0,0,0); + } + } + else + if (cKey==Global::Keys[k_Compressor]) //NBMX 14-09-2003: sprezarka wl + { + if ((mvControlled->ConverterFlag) || + (mvControlled->CompressorPower<2)) + if (mvControlled->CompressorSwitch(true)) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0,0,0); + } + } + else */ + + else if (cKey == Global::Keys[k_Converter]) + { + if (ggConverterButton.GetValue() == 0) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + else if ((cKey == Global::Keys[k_Compressor]) && + (mvControlled->CompressorPower < 2)) // hunter-091012: tak jest poprawnie + // if + // ((cKey==Global::Keys[k_Compressor])&&((mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->TrainType==dt_EZT))) + // //hunter-110212: poprawka dla EZT + + { + if (ggCompressorButton.GetValue() == 0) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + else if (cKey == Global::Keys[k_SmallCompressor]) // Winger 160404: mala + // sprezarka wl + { // Ra: dźwięk, gdy razem z [Shift] + if ((mvControlled->TrainType & dt_EZT) ? mvControlled == mvOccupied : + !mvOccupied->ActiveCab) // tylko w maszynowym + if (Console::Pressed(VK_CONTROL)) // z [Ctrl] + mvControlled->bPantKurek3 = true; // zbiornik pantografu połączony + // jest ze zbiornikiem głównym + // (pompowanie nie ma sensu) + else if (!mvControlled->PantCompFlag) // jeśli wyłączona + if (mvControlled->Battery) // jeszcze musi być załączona bateria + if (mvControlled->PantPress < 4.8) // piszą, że to tak nie działa + { + mvControlled->PantCompFlag = true; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); // dźwięk tylko po naciśnięciu klawisza + } + } + else if (cKey == VkKeyScan('q')) // ze Shiftem - włączenie AI + { // McZapkie-240302 - wlaczanie automatycznego pilota (zadziala tylko w + // trybie debugmode) + if (DynamicObject->Mechanik) + { + if (DebugModeFlag) + if (DynamicObject->Mechanik->AIControllFlag) //żeby nie trzeba było + // rozłączać dla + // zresetowania + DynamicObject->Mechanik->TakeControl(false); + DynamicObject->Mechanik->TakeControl(true); + } + } + else if (cKey == Global::Keys[k_MaxCurrent]) // McZapkie-160502: F - + // wysoki rozruch + { + if ((mvControlled->EngineType == DieselElectric) && (mvControlled->ShuntModeAllow) && + (mvControlled->MainCtrlPos == 0)) + { + mvControlled->ShuntMode = true; + } + if (mvControlled->CurrentSwitch(true)) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + /* Ra: przeniesione do Mover.cpp + if (mvControlled->TrainType!=dt_EZT) //to powinno być w fizyce, a + nie w kabinie! + if (mvControlled->MinCurrentSwitch(true)) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0,0,0); + } + */ + } + else if (cKey == Global::Keys[k_CurrentAutoRelay]) // McZapkie-241002: G - + // wlaczanie PSR + { + if (mvControlled->AutoRelaySwitch(true)) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + else if (cKey == Global::Keys[k_FailedEngineCutOff]) // McZapkie-060103: E + // - wylaczanie + // sekcji silnikow + { + if (mvControlled->CutOffEngine()) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + else if (cKey == Global::Keys[k_OpenLeft]) // NBMX 17-09-2003: otwieranie drzwi + { + if (mvOccupied->DoorOpenCtrl == 1) + if (mvOccupied->CabNo < 0 ? mvOccupied->DoorRight(true) : + mvOccupied->DoorLeft(true)) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (dsbDoorOpen) + { + dsbDoorOpen->SetCurrentPosition(0); + dsbDoorOpen->Play(0, 0, 0); + } + } + } + else if (cKey == Global::Keys[k_OpenRight]) // NBMX 17-09-2003: otwieranie drzwi + { + if (mvOccupied->DoorCloseCtrl == 1) + if (mvOccupied->CabNo < 0 ? mvOccupied->DoorLeft(true) : + mvOccupied->DoorRight(true)) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (dsbDoorOpen) + { + dsbDoorOpen->SetCurrentPosition(0); + dsbDoorOpen->Play(0, 0, 0); + } + } + } + //----------- + // hunter-131211: dzwiek dla przelacznika universala podniesionego + // hunter-091012: ubajerowanie swiatla w kabinie (wyrzucenie + // przyciemnienia pod Univ4) + else if (cKey == Global::Keys[k_Univ3]) + { + if (Console::Pressed(VK_CONTROL)) + { + if (bCabLight == false) //(ggCabLightButton.GetValue()==0) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + else + { + if (ggUniversal3Button.GetValue() == 0) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + /* + if (Console::Pressed(VK_CONTROL)) + {//z [Ctrl] zapalamy albo gasimy światełko w kabinie + if (iCabLightFlag<2) ++iCabLightFlag; //zapalenie + } + */ + } + } + + //----------- + // hunter-091012: dzwiek dla przyciemnienia swiatelka w kabinie + else if (cKey == Global::Keys[k_Univ4]) + { + if (Console::Pressed(VK_CONTROL)) + { + if (bCabLightDim == false) //(ggCabLightDimButton.GetValue()==0) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + } + + //----------- + else if (cKey == Global::Keys[k_PantFrontUp]) + { // Winger 160204: podn. + // przedn. pantografu + if (mvOccupied->ActiveCab == + 1) //||((mvOccupied->ActiveCab<1)&&((mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))==0))) + { // przedni gdy w kabinie 1 lub (z wyjątkiem ET40, ET41, ET42 i EZT) gdy + // w kabinie -1 + mvControlled->PantFrontSP = false; + if (mvControlled->PantFront(true)) + if (mvControlled->PantFrontStart != 1) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + else + // if + // ((mvOccupied->ActiveCab<1)&&(mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))) + { // w kabinie -1 dla ET40, ET41, ET42 i EZT + mvControlled->PantRearSP = false; + if (mvControlled->PantRear(true)) + if (mvControlled->PantRearStart != 1) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + } + else if (cKey == Global::Keys[k_PantRearUp]) + { // Winger 160204: podn. + // tyln. pantografu + // względem kierunku jazdy + if (mvOccupied->ActiveCab == + 1) //||((mvOccupied->ActiveCab<1)&&((mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))==0))) + { // tylny gdy w kabinie 1 lub (z wyjątkiem ET40, ET41, ET42 i EZT) gdy w + // kabinie -1 + mvControlled->PantRearSP = false; + if (mvControlled->PantRear(true)) + if (mvControlled->PantRearStart != 1) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + else + // if + // ((mvOccupied->ActiveCab<1)&&(mvControlled->TrainType&(dt_ET40|dt_ET41|dt_ET42|dt_EZT))) + { // przedni w kabinie -1 dla ET40, ET41, ET42 i EZT + mvControlled->PantFrontSP = false; + if (mvControlled->PantFront(true)) + if (mvControlled->PantFrontStart != 1) + { + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + } + else if (cKey == Global::Keys[k_Active]) // yB 300407: przelacznik rozrzadu + { // Ra 2014-06: uruchomiłem to, aby aktywować czuwak w zajmowanym członie, + // a wyłączyć w innych + // Ra 2014-03: aktywacja czuwaka przepięta na ustawienie kierunku w + // mvOccupied + // if (mvControlled->Battery) //jeśli bateria jest już załączona + // mvOccupied->BatterySwitch(true); //to w ten oto durny sposób aktywuje + // się CA/SHP + // if (mvControlled->CabActivisation()) + // { + // dsbSwitch->SetVolume(DSBVOLUME_MAX); + // dsbSwitch->Play(0,0,0); + // } + } + else if (cKey == Global::Keys[k_Heating]) // Winger 020304: ogrzewanie + // skladu - wlaczenie + { // Ra 2014-09: w trybie latania obsługa jest w World.cpp + if (!FreeFlyModeFlag) + { + if ((mvControlled->Heating == false) && + ((mvControlled->EngineType == ElectricSeriesMotor) && + (mvControlled->Mains == true) || + (mvControlled->ConverterFlag))) + { + mvControlled->Heating = true; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + } + } + } + else if (cKey == Global::Keys[k_LeftSign]) // lewe swiatlo - włączenie + // ABu 060205: dzielo Wingera po malutkim liftingu: + { + if (!mvOccupied->LightsPosNo > 0) + { + if ((GetAsyncKeyState(VK_CONTROL) < 0) && + (ggRearLeftLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu + { + //------------------------------ + if (mvOccupied->ActiveCab == 1) + { // kabina 1 + if (((DynamicObject->iLights[1]) & 3) == 0) + { + DynamicObject->iLights[1] |= 1; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRearLeftLightButton.PutValue(1); + } + if (((DynamicObject->iLights[1]) & 3) == 2) + { + DynamicObject->iLights[1] &= (255 - 2); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRearLeftEndLightButton.SubModel) + { + ggRearLeftEndLightButton.PutValue(0); + ggRearLeftLightButton.PutValue(0); + } + else + ggRearLeftLightButton.PutValue(0); + } + } + else + { // kabina -1 + if (((DynamicObject->iLights[0]) & 3) == 0) + { + DynamicObject->iLights[0] |= 1; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRearLeftLightButton.PutValue(1); + } + if (((DynamicObject->iLights[0]) & 3) == 2) + { + DynamicObject->iLights[0] &= (255 - 2); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRearLeftEndLightButton.SubModel) + { + ggRearLeftEndLightButton.PutValue(0); + ggRearLeftLightButton.PutValue(0); + } + else + ggRearLeftLightButton.PutValue(0); + } + } + //---------------------- + } + else + { + if (mvOccupied->ActiveCab == 1) + { // kabina 1 + if (((DynamicObject->iLights[0]) & 3) == 0) + { + DynamicObject->iLights[0] |= 1; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggLeftLightButton.PutValue(1); + } + if (((DynamicObject->iLights[0]) & 3) == 2) + { + DynamicObject->iLights[0] &= (255 - 2); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggLeftEndLightButton.SubModel) + { + ggLeftEndLightButton.PutValue(0); + ggLeftLightButton.PutValue(0); + } + else + ggLeftLightButton.PutValue(0); + } + } + else + { // kabina -1 + if (((DynamicObject->iLights[1]) & 3) == 0) + { + DynamicObject->iLights[1] |= 1; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggLeftLightButton.PutValue(1); + } + if (((DynamicObject->iLights[1]) & 3) == 2) + { + DynamicObject->iLights[1] &= (255 - 2); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggLeftEndLightButton.SubModel) + { + ggLeftEndLightButton.PutValue(0); + ggLeftLightButton.PutValue(0); + } + else + ggLeftLightButton.PutValue(0); + } + } + } //----------- + } + } + else if (cKey == Global::Keys[k_UpperSign]) // ABu 060205: światło górne - + // włączenie + { + if (mvOccupied->LightsPosNo > 0) //kręciolek od swiatel + { + if ((mvOccupied->LightsPos < mvOccupied->LightsPosNo) || (mvOccupied->LightsWrap)) + { + mvOccupied->LightsPos++; + if (mvOccupied->LightsPos > mvOccupied->LightsPosNo) + { + mvOccupied->LightsPos = 1; + } + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + SetLights(); + } + + } + else if ((GetAsyncKeyState(VK_CONTROL) < 0) && + (ggRearUpperLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu + { + //------------------------------ + if ((mvOccupied->ActiveCab) == 1) + { // kabina 1 + if (((DynamicObject->iLights[1]) & 12) == 0) + { + DynamicObject->iLights[1] |= 4; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRearUpperLightButton.PutValue(1); + } + } + else + { // kabina -1 + if (((DynamicObject->iLights[0]) & 12) == 0) + { + DynamicObject->iLights[0] |= 4; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRearUpperLightButton.PutValue(1); + } + } + } //------------------------------ + else + { + if ((mvOccupied->ActiveCab) == 1) + { // kabina 1 + if (((DynamicObject->iLights[0]) & 12) == 0) + { + DynamicObject->iLights[0] |= 4; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggUpperLightButton.PutValue(1); + } + } + else + { // kabina -1 + if (((DynamicObject->iLights[1]) & 12) == 0) + { + DynamicObject->iLights[1] |= 4; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggUpperLightButton.PutValue(1); + } + } + } + } + else if (cKey == Global::Keys[k_RightSign]) // Winger 070304: swiatla + // tylne (koncowki) - + // wlaczenie + { + if (!mvOccupied->LightsPosNo > 0) + { + if ((GetAsyncKeyState(VK_CONTROL) < 0) && + (ggRearRightLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu + { + //------------------------------ + if (mvOccupied->ActiveCab == 1) + { // kabina 1 + if (((DynamicObject->iLights[1]) & 48) == 0) + { + DynamicObject->iLights[1] |= 16; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRearRightLightButton.PutValue(1); + } + if (((DynamicObject->iLights[1]) & 48) == 32) + { + DynamicObject->iLights[1] &= (255 - 32); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRearRightEndLightButton.SubModel) + { + ggRearRightEndLightButton.PutValue(0); + ggRearRightLightButton.PutValue(0); + } + else + ggRearRightLightButton.PutValue(0); + } + } + else + { // kabina -1 + if (((DynamicObject->iLights[0]) & 48) == 0) + { + DynamicObject->iLights[0] |= 16; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRearRightLightButton.PutValue(1); + } + if (((DynamicObject->iLights[0]) & 48) == 32) + { + DynamicObject->iLights[0] &= (255 - 32); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRearRightEndLightButton.SubModel) + { + ggRearRightEndLightButton.PutValue(0); + ggRearRightLightButton.PutValue(0); + } + else + ggRearRightLightButton.PutValue(0); + } + } + } //------------------------------ + else + { + if (mvOccupied->ActiveCab == 1) + { // kabina 1 + if (((DynamicObject->iLights[0]) & 48) == 0) + { + DynamicObject->iLights[0] |= 16; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRightLightButton.PutValue(1); + } + if (((DynamicObject->iLights[0]) & 48) == 32) + { + DynamicObject->iLights[0] &= (255 - 32); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRightEndLightButton.SubModel) + { + ggRightEndLightButton.PutValue(0); + ggRightLightButton.PutValue(0); + } + else + ggRightLightButton.PutValue(0); + } + } + else + { // kabina -1 + if (((DynamicObject->iLights[1]) & 48) == 0) + { + DynamicObject->iLights[1] |= 16; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRightLightButton.PutValue(1); + } + if (((DynamicObject->iLights[1]) & 48) == 32) + { + DynamicObject->iLights[1] &= (255 - 32); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRightEndLightButton.SubModel) + { + ggRightEndLightButton.PutValue(0); + ggRightLightButton.PutValue(0); + } + else + ggRightLightButton.PutValue(0); + } + } + } + } + } + } else // McZapkie-240302 - klawisze bez shifta { if (cKey == Global::Keys[k_IncMainCtrl]) @@ -1007,7 +1154,8 @@ void TTrain::OnKeyDown(int cKey) ; else if (cKey == Global::Keys[k_IncScndCtrl]) // if (MoverParameters->ScndCtrlPosScndCtrlPosNo) - // if (mvControlled->EnginePowerSource.SourceType==CurrentCollector) + // if + // (mvControlled->EnginePowerSource.SourceType==CurrentCollector) if (mvControlled->ShuntMode) { mvControlled->AnPos += (GetDeltaTime() / 0.85f); @@ -1056,7 +1204,10 @@ void TTrain::OnKeyDown(int cKey) else ; else if (cKey == Global::Keys[k_IncLocalBrakeLevel]) - { // Ra 2014-09: w trybie latania obsługa jest w World.cpp + { // Ra 2014-09: w + // trybie latania + // obsługa jest w + // World.cpp if (!FreeFlyModeFlag) { if (GetAsyncKeyState(VK_CONTROL) < 0) @@ -1071,7 +1222,10 @@ void TTrain::OnKeyDown(int cKey) } } else if (cKey == Global::Keys[k_DecLocalBrakeLevel]) - { // Ra 2014-06: wersja dla swobodnego latania przeniesiona do World.cpp + { // Ra 2014-06: wersja dla + // swobodnego latania + // przeniesiona do + // World.cpp if (!FreeFlyModeFlag) { if (GetAsyncKeyState(VK_CONTROL) < 0) @@ -1079,16 +1233,17 @@ void TTrain::OnKeyDown(int cKey) mvOccupied->DecManualBrakeLevel(1); else ; - else // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku - odhamować - // jakoś trzeba + else // Ra 1014-06: AI potrafi zahamować pomocniczym mimo jego braku - + // odhamować jakoś trzeba if ((mvOccupied->LocalBrake != ManualBrake) || mvOccupied->LocalBrakePos) mvOccupied->DecLocalBrakeLevel(1); } } else if ((cKey == Global::Keys[k_IncBrakeLevel]) && (mvOccupied->BrakeHandle != FV4a)) // if (mvOccupied->IncBrakeLevel()) - if (mvOccupied->BrakeLevelAdd( - Global::fBrakeStep)) // nieodpowiedni warunek; true, jeśli można dalej kręcić + if (mvOccupied->BrakeLevelAdd(Global::fBrakeStep)) // nieodpowiedni + // warunek; true, jeśli + // można dalej kręcić { keybrakecount = 0; if ((isEztOer) && (mvOccupied->BrakeCtrlPos < 3)) @@ -1101,7 +1256,8 @@ void TTrain::OnKeyDown(int cKey) ; else if ((cKey == Global::Keys[k_DecBrakeLevel]) && (mvOccupied->BrakeHandle != FV4a)) { - // nową wersję dostarczył ZiomalCl ("fixed looped sound in ezt when using NUM_9 key") + // nową wersję dostarczył ZiomalCl ("fixed looped sound in ezt when using + // NUM_9 key") if ((mvOccupied->BrakeCtrlPos > -1) || (keybrakecount > 1)) { @@ -1116,12 +1272,14 @@ void TTrain::OnKeyDown(int cKey) else keybrakecount += 1; // koniec wersji dostarczonej przez ZiomalCl - /* wersja poprzednia - ten pierwszy if ze średnikiem nie działał jak warunek + /* wersja poprzednia - ten pierwszy if ze średnikiem nie działał jak + warunek if ((mvOccupied->BrakeCtrlPos>-1)|| (keybrakecount>1)) { if (mvOccupied->DecBrakeLevel()); { - if ((isEztOer) && (mvOccupied->BrakeCtrlPos<2)&&(keybrakecount<=1)) + if ((isEztOer) && + (mvOccupied->BrakeCtrlPos<2)&&(keybrakecount<=1)) { dsbPneumaticSwitch->SetVolume(-10); dsbPneumaticSwitch->Play(0,0,0); @@ -1165,11 +1323,10 @@ void TTrain::OnKeyDown(int cKey) mvOccupied->BrakeLevelSet(mvOccupied->BrakeCtrlPosNo / 2 + (mvOccupied->BrakeHandle == FV4a ? 1 : 0)); if (GetAsyncKeyState(VK_CONTROL) < 0) - mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_NP)); // yB: czy ten stos - // funkcji nie - // powinien być jako - // oddzielna funkcja - // movera? + mvOccupied->BrakeLevelSet( + mvOccupied->Handle->GetPos(bh_NP)); // yB: czy ten stos funkcji nie + // powinien być jako oddzielna + // funkcja movera? } else if (cKey == Global::Keys[k_Brake1]) { @@ -1212,10 +1369,9 @@ void TTrain::OnKeyDown(int cKey) // while (mvOccupied->BrakeCtrlPos<-1 && mvOccupied->IncBrakeLevel()); mvOccupied->BrakeLevelSet(-1); } - else + else if (cKey == Global::Keys[k_Czuwak]) //--------------- // hunter-131211: zbicie czuwaka przeniesione do TTrain::Update() - if (cKey == Global::Keys[k_Czuwak]) { // Ra: tu został tylko dźwięk // dsbBuzzer->Stop(); // if (mvOccupied->SecuritySystemReset()) @@ -1226,10 +1382,10 @@ void TTrain::OnKeyDown(int cKey) } // ggSecurityResetButton.PutValue(1); } - else + else if (cKey == Global::Keys[k_AntiSlipping]) //--------------- - // hunter-221211: hamulec przeciwposlizgowy przeniesiony do TTrain::Update() - if (cKey == Global::Keys[k_AntiSlipping]) + // hunter-221211: hamulec przeciwposlizgowy przeniesiony do + // TTrain::Update() { if (mvOccupied->BrakeSystem != ElectroPneumatic) { @@ -1244,15 +1400,14 @@ void TTrain::OnKeyDown(int cKey) // ggAntiSlipButton.PutValue(1); } } - else + else if (cKey == Global::Keys[k_Fuse]) //--------------- - - if (cKey == Global::Keys[k_Fuse]) { if (GetAsyncKeyState(VK_CONTROL) < 0) // z controlem { ggConverterFuseButton.PutValue(1); // hunter-261211 - if ((mvControlled->Mains == false) && (ggConverterButton.GetValue() == 0)) + if ((mvControlled->Mains == false) && (ggConverterButton.GetValue() == 0) && + (mvControlled->TrainType != dt_EZT)) mvControlled->ConvOvldFlag = false; } else @@ -1261,9 +1416,8 @@ void TTrain::OnKeyDown(int cKey) mvControlled->FuseOn(); } } - else + else if (cKey == Global::Keys[k_DirectionForward]) // McZapkie-240302 - zmiana kierunku: 'd' do przodu, 'r' do tylu - if (cKey == Global::Keys[k_DirectionForward]) { if (mvOccupied->DirectionForward()) { @@ -1292,11 +1446,11 @@ void TTrain::OnKeyDown(int cKey) { if (GetAsyncKeyState(VK_CONTROL) < 0) { // wciśnięty [Ctrl] - if (mvControlled->Radio == true) + if (mvOccupied->Radio == true) { dsbSwitch->SetVolume(DSBVOLUME_MAX); dsbSwitch->Play(0, 0, 0); - mvControlled->Radio = false; + mvOccupied->Radio = false; } } else if (mvOccupied->DirectionBackward()) @@ -1322,11 +1476,10 @@ void TTrain::OnKeyDown(int cKey) Change_direction); // aktualizacja skrajnych pojazdów w składzie } } - else + else if (cKey == Global::Keys[k_Main]) // McZapkie-240302 - wylaczanie glownego obwodu //----------- // hunter-141211: wyl. szybki wylaczony przeniesiony do TTrain::Update() - if (cKey == Global::Keys[k_Main]) { if (fabs(ggMainOffButton.GetValue()) < 0.001) if (dsbSwitch) @@ -1335,15 +1488,15 @@ void TTrain::OnKeyDown(int cKey) dsbSwitch->Play(0, 0, 0); } } - else - - if (cKey == Global::Keys[k_Battery]) + else if (cKey == Global::Keys[k_Battery]) { // if ((mvControlled->TrainType==dt_EZT) || // (mvControlled->EngineType==ElectricSeriesMotor)|| // (mvControlled->EngineType==DieselElectric)) if (mvOccupied->BatterySwitch(false)) - { // ewentualnie zablokować z FIZ, np. w samochodach się nie odłącza akumulatora + { // ewentualnie zablokować z FIZ, + // np. w samochodach się nie + // odłącza akumulatora dsbSwitch->Play(0, 0, 0); // mvOccupied->SecuritySystem.Status=0; mvControlled->PantFront(false); @@ -1352,7 +1505,8 @@ void TTrain::OnKeyDown(int cKey) } //----------- - // if (cKey==Global::Keys[k_Active]) //yB 300407: przelacznik rozrzadu + // if (cKey==Global::Keys[k_Active]) //yB 300407: przelacznik + // rozrzadu // { // if (mvControlled->CabDeactivisation()) // { @@ -1362,7 +1516,9 @@ void TTrain::OnKeyDown(int cKey) // } // else if (cKey == Global::Keys[k_BrakeProfile]) - { // yB://ABu: male poprawki, zeby bylo mozna ustawic dowolny wagon + { // yB://ABu: male poprawki, zeby + // bylo mozna ustawic dowolny + // wagon int CouplNr = -2; if (!FreeFlyModeFlag) { @@ -1409,10 +1565,10 @@ void TTrain::OnKeyDown(int cKey) } } } - else + else if (cKey == Global::Keys[k_Converter]) //----------- - // hunter-261211: przetwornica i sprzezarka przeniesione do TTrain::Update() - if (cKey == Global::Keys[k_Converter]) + // hunter-261211: przetwornica i sprzezarka przeniesione do + // TTrain::Update() { if (ggConverterButton.GetValue() != 0) { @@ -1420,11 +1576,10 @@ void TTrain::OnKeyDown(int cKey) dsbSwitch->Play(0, 0, 0); } } - else // if // ((cKey==Global::Keys[k_Compressor])&&((mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->TrainType==dt_EZT))) // //hunter-110212: poprawka dla EZT - if ((cKey == Global::Keys[k_Compressor]) && + else if ((cKey == Global::Keys[k_Compressor]) && (mvControlled->CompressorPower < 2)) // hunter-091012: tak jest poprawnie { if (ggCompressorButton.GetValue() != 0) @@ -1433,9 +1588,8 @@ void TTrain::OnKeyDown(int cKey) dsbSwitch->Play(0, 0, 0); } } - else //----------- - if (cKey == Global::Keys[k_Releaser]) // odluzniacz + else if (cKey == Global::Keys[k_Releaser]) // odluzniacz { if (!FreeFlyModeFlag) { @@ -1446,22 +1600,24 @@ void TTrain::OnKeyDown(int cKey) if (mvOccupied->BrakeCtrlPosNo > 0) { ggReleaserButton.PutValue(1); - if (mvOccupied->BrakeReleaser(1)) - { - dsbPneumaticRelay->SetVolume(-80); - dsbPneumaticRelay->Play(0, 0, 0); - } + mvOccupied->BrakeReleaser(1); + // if (mvOccupied->BrakeReleaser(1)) + // { + // dsbPneumaticRelay->SetVolume(-80); + // dsbPneumaticRelay->Play(0, 0, 0); + // } } } } - else if (cKey == Global::Keys[k_SmallCompressor]) // Winger 160404: mala sprezarka wl + else if (cKey == Global::Keys[k_SmallCompressor]) // Winger 160404: mala + // sprezarka wl { // Ra: bez [Shift] też dać dźwięk if ((mvControlled->TrainType & dt_EZT) ? mvControlled == mvOccupied : !mvOccupied->ActiveCab) // tylko w maszynowym if (Console::Pressed(VK_CONTROL)) // z [Ctrl] - mvControlled->bPantKurek3 = false; // zbiornik pantografu połączony jest z małą - // sprężarką (pompowanie ma sens, ale potem - // trzeba przełączyć) + mvControlled->bPantKurek3 = + false; // zbiornik pantografu połączony jest z małą sprężarką + // (pompowanie ma sens, ale potem trzeba przełączyć) else if (!mvControlled->PantCompFlag) // jeśli wyłączona if (mvControlled->Battery) // jeszcze musi być załączona bateria if (mvControlled->PantPress < 4.8) // piszą, że to tak nie działa @@ -1471,7 +1627,8 @@ void TTrain::OnKeyDown(int cKey) dsbSwitch->Play(0, 0, 0); // dźwięk tylko po naciśnięciu klawisza } } - // McZapkie-240302 - wylaczanie automatycznego pilota (w trybie ~debugmode mozna tylko raz) + // McZapkie-240302 - wylaczanie automatycznego pilota (w trybie ~debugmode + // mozna tylko raz) else if (cKey == VkKeyScan('q')) // bez Shift { if (DynamicObject->Mechanik) @@ -1498,7 +1655,8 @@ void TTrain::OnKeyDown(int cKey) } */ } - else if (cKey == Global::Keys[k_CurrentAutoRelay]) // McZapkie-241002: g - wylaczanie PSR + else if (cKey == Global::Keys[k_CurrentAutoRelay]) // McZapkie-241002: g - + // wylaczanie PSR { if (mvControlled->AutoRelaySwitch(false)) { @@ -1506,9 +1664,10 @@ void TTrain::OnKeyDown(int cKey) dsbSwitch->Play(0, 0, 0); } } - else - // hunter-201211: piasecznica poprawiona oraz przeniesiona do TTrain::Update() - if (cKey == Global::Keys[k_Sand]) + + // hunter-201211: piasecznica poprawiona oraz przeniesiona do + // TTrain::Update() + else if (cKey == Global::Keys[k_Sand]) { /* if (mvControlled->TrainType!=dt_EZT) @@ -1523,11 +1682,15 @@ void TTrain::OnKeyDown(int cKey) */ if (mvControlled->TrainType == dt_EZT) { - if (mvControlled->DoorSignalling) - { - dsbSwitch->Play(0, 0, 0); - mvControlled->DoorSignalling = false; - } + if (ggDoorSignallingButton.SubModel != NULL) + { + if (mvControlled->DoorSignalling) + { + mvOccupied->DoorBlocked = false; + dsbSwitch->Play(0, 0, 0); + mvControlled->DoorSignalling = false; + } + } } } else if (cKey == Global::Keys[k_CabForward]) @@ -1558,7 +1721,9 @@ void TTrain::OnKeyDown(int cKey) false; // wyjście z maszynowego wyłącza sprężarkę pomocniczą } else if (cKey == Global::Keys[k_Couple]) - { // ABu051104: male zmiany, zeby mozna bylo laczyc odlegle wagony + { // ABu051104: male zmiany, zeby + // mozna bylo laczyc odlegle + // wagony // da sie zoptymalizowac, ale nie ma na to czasu :( if (iCabn > 0) { @@ -1566,24 +1731,26 @@ void TTrain::OnKeyDown(int cKey) { /* if (mvControlled->Couplers[iCabn-1].CouplingFlag==0) { - if - (mvControlled->Attach(iCabn-1,mvControlled->Couplers[iCabn-1].Connected,ctrain_coupler)) +if + (mvControlled->Attach(iCabn-1,mvControlled->Couplers[iCabn-1].Connected,ctrain_coupler)) { dsbCouplerAttach->SetVolume(DSBVOLUME_MAX); dsbCouplerAttach->Play(0,0,0); - //ABu: aha, a guzik, nie dziala i nie bedzie, a przydalo by sie cos takiego: + //ABu: aha, a guzik, nie dziala i nie bedzie, a przydalo by sie + cos takiego: //DynamicObject->NextConnected=mvControlled->Couplers[iCabn-1].Connected; //DynamicObject->PrevConnected=mvControlled->Couplers[iCabn-1].Connected; } } else - if (!TestFlag(mvControlled->Couplers[iCabn-1].CouplingFlag,ctrain_pneumatic)) + if + (!TestFlag(mvControlled->Couplers[iCabn-1].CouplingFlag,ctrain_pneumatic)) { //ABu021104: zeby caly czas bylo widac sprzegi: - if - (mvControlled->Attach(iCabn-1,mvControlled->Couplers[iCabn-1].Connected,mvControlled->Couplers[iCabn-1].CouplingFlag+ctrain_pneumatic)) - //if - (mvControlled->Attach(iCabn-1,mvControlled->Couplers[iCabn-1].Connected,ctrain_pneumatic)) +if + (mvControlled->Attach(iCabn-1,mvControlled->Couplers[iCabn-1].Connected,mvControlled->Couplers[iCabn-1].CouplingFlag+ctrain_pneumatic)) +//if + (mvControlled->Attach(iCabn-1,mvControlled->Couplers[iCabn-1].Connected,ctrain_pneumatic)) { rsHiss.Play(1,DSBPLAY_LOOPING,true,DynamicObject->GetPosition()); } @@ -1710,11 +1877,13 @@ void TTrain::OnKeyDown(int cKey) } } else if (cKey == Global::Keys[k_DeCouple]) - { // ABu051104: male zmiany, zeby mozna bylo rozlaczac odlegle wagony + { // ABu051104: male zmiany, + // zeby mozna bylo rozlaczac + // odlegle wagony if (iCabn > 0) { - if (!FreeFlyModeFlag) // tryb 'kabinowy' (pozwala również rozłączyć sprzęgi - // zablokowane) + if (!FreeFlyModeFlag) // tryb 'kabinowy' (pozwala również rozłączyć + // sprzęgi zablokowane) { if (DynamicObject->DettachStatus(iCabn - 1) < 0) // jeśli jest co odczepić if (DynamicObject->Dettach(iCabn - 1)) // iCab==1:przód,iCab==2:tył @@ -1775,11 +1944,12 @@ void TTrain::OnKeyDown(int cKey) } } } - else + //----------- // hunter-131211: dzwiek dla przelacznika universala - // hunter-091012: ubajerowanie swiatla w kabinie (wyrzucenie przyciemnienia pod Univ4) - if (cKey == Global::Keys[k_Univ3]) + // hunter-091012: ubajerowanie swiatla w kabinie (wyrzucenie + // przyciemnienia pod Univ4) + else if (cKey == Global::Keys[k_Univ3]) { if (Console::Pressed(VK_CONTROL)) { @@ -1803,10 +1973,10 @@ void TTrain::OnKeyDown(int cKey) } */ } } - else + //----------- // hunter-091012: dzwiek dla przyciemnienia swiatelka w kabinie - if (cKey == Global::Keys[k_Univ4]) + else if (cKey == Global::Keys[k_Univ4]) { if (Console::Pressed(VK_CONTROL)) { @@ -1818,7 +1988,8 @@ void TTrain::OnKeyDown(int cKey) } } //----------- - else if (cKey == Global::Keys[k_PantFrontDown]) // Winger 160204: opuszczanie prz. patyka + else if (cKey == Global::Keys[k_PantFrontDown]) // Winger 160204: + // opuszczanie prz. patyka { if (mvOccupied->ActiveCab == 1) //||((mvOccupied->ActiveCab<1)&&(mvControlled->TrainType!=dt_ET40)&&(mvControlled->TrainType!=dt_ET41)&&(mvControlled->TrainType!=dt_ET42)&&(mvControlled->TrainType!=dt_EZT))) @@ -1843,7 +2014,8 @@ void TTrain::OnKeyDown(int cKey) } } } - else if (cKey == Global::Keys[k_PantRearDown]) // Winger 160204: opuszczanie tyl. patyka + else if (cKey == Global::Keys[k_PantRearDown]) // Winger 160204: + // opuszczanie tyl. patyka { if (mvOccupied->ActiveCab == 1) //||((mvOccupied->ActiveCab<1)&&(mvControlled->TrainType!=dt_ET40)&&(mvControlled->TrainType!=dt_ET41)&&(mvControlled->TrainType!=dt_ET42)&&(mvControlled->TrainType!=dt_EZT))) @@ -1869,7 +2041,8 @@ void TTrain::OnKeyDown(int cKey) } } } - else if (cKey == Global::Keys[k_Heating]) // Winger 020304: ogrzewanie - wylaczenie + else if (cKey == Global::Keys[k_Heating]) // Winger 020304: ogrzewanie - + // wylaczenie { // Ra 2014-09: w trybie latania obsługa jest w World.cpp if (!FreeFlyModeFlag) { @@ -1881,113 +2054,132 @@ void TTrain::OnKeyDown(int cKey) } } } - else if (cKey == Global::Keys[k_LeftSign]) // ABu 060205: lewe swiatlo - wylaczenie - { - if ((GetAsyncKeyState(VK_CONTROL) < 0) && - (ggRearLeftLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu - { - //------------------------------ - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[1]) & 3) == 0) - { - DynamicObject->iLights[1] |= 2; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRearLeftEndLightButton.SubModel) - { - ggRearLeftEndLightButton.PutValue(1); - ggRearLeftLightButton.PutValue(0); - } - else - ggRearLeftLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[1]) & 3) == 1) - { - DynamicObject->iLights[1] &= (255 - 1); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearLeftLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[0]) & 3) == 0) - { - DynamicObject->iLights[0] |= 2; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRearLeftEndLightButton.SubModel) - { - ggRearLeftEndLightButton.PutValue(1); - ggRearLeftLightButton.PutValue(0); - } - else - ggRearLeftLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[1]) & 3) == 1) - { - DynamicObject->iLights[1] &= (255 - 1); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggLeftLightButton.PutValue(0); - } - } - } //------------------------------ - else - { - if (mvOccupied->ActiveCab == 1) - { // kabina 1 - if (((DynamicObject->iLights[0]) & 3) == 0) - { - DynamicObject->iLights[0] |= 2; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggLeftEndLightButton.SubModel) - { - ggLeftEndLightButton.PutValue(1); - ggLeftLightButton.PutValue(0); - } - else - ggLeftLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[0]) & 3) == 1) - { - DynamicObject->iLights[0] &= (255 - 1); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggLeftLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[1]) & 3) == 0) - { - DynamicObject->iLights[1] |= 2; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggLeftEndLightButton.SubModel) - { - ggLeftEndLightButton.PutValue(1); - ggLeftLightButton.PutValue(0); - } - else - ggLeftLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[1]) & 3) == 1) - { - DynamicObject->iLights[1] &= (255 - 1); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggLeftLightButton.PutValue(0); - } - } - } - } - else if (cKey == Global::Keys[k_UpperSign]) // ABu 060205: światło górne - wyłączenie - { - if ((GetAsyncKeyState(VK_CONTROL) < 0) && - (ggRearUpperLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu + else if (cKey == Global::Keys[k_LeftSign]) // ABu 060205: lewe swiatlo - + // wylaczenie + { + if (!mvOccupied->LightsPosNo > 0) + { + if ((GetAsyncKeyState(VK_CONTROL) < 0) && + (ggRearLeftLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu + { + //------------------------------ + if (mvOccupied->ActiveCab == 1) + { // kabina 1 + if (((DynamicObject->iLights[1]) & 3) == 0) + { + DynamicObject->iLights[1] |= 2; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRearLeftEndLightButton.SubModel) + { + ggRearLeftEndLightButton.PutValue(1); + ggRearLeftLightButton.PutValue(0); + } + else + ggRearLeftLightButton.PutValue(-1); + } + if (((DynamicObject->iLights[1]) & 3) == 1) + { + DynamicObject->iLights[1] &= (255 - 1); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRearLeftLightButton.PutValue(0); + } + } + else + { // kabina -1 + if (((DynamicObject->iLights[0]) & 3) == 0) + { + DynamicObject->iLights[0] |= 2; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRearLeftEndLightButton.SubModel) + { + ggRearLeftEndLightButton.PutValue(1); + ggRearLeftLightButton.PutValue(0); + } + else + ggRearLeftLightButton.PutValue(-1); + } + if (((DynamicObject->iLights[1]) & 3) == 1) + { + DynamicObject->iLights[1] &= (255 - 1); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggLeftLightButton.PutValue(0); + } + } + } //------------------------------ + else + { + if (mvOccupied->ActiveCab == 1) + { // kabina 1 + if (((DynamicObject->iLights[0]) & 3) == 0) + { + DynamicObject->iLights[0] |= 2; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggLeftEndLightButton.SubModel) + { + ggLeftEndLightButton.PutValue(1); + ggLeftLightButton.PutValue(0); + } + else + ggLeftLightButton.PutValue(-1); + } + if (((DynamicObject->iLights[0]) & 3) == 1) + { + DynamicObject->iLights[0] &= (255 - 1); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggLeftLightButton.PutValue(0); + } + } + else + { // kabina -1 + if (((DynamicObject->iLights[1]) & 3) == 0) + { + DynamicObject->iLights[1] |= 2; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggLeftEndLightButton.SubModel) + { + ggLeftEndLightButton.PutValue(1); + ggLeftLightButton.PutValue(0); + } + else + ggLeftLightButton.PutValue(-1); + } + if (((DynamicObject->iLights[1]) & 3) == 1) + { + DynamicObject->iLights[1] &= (255 - 1); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggLeftLightButton.PutValue(0); + } + } + } + } + } + else if (cKey == Global::Keys[k_UpperSign]) // ABu 060205: światło górne - + // wyłączenie + { + if (mvOccupied->LightsPosNo > 0) //kręciolek od swiatel + { + if ((mvOccupied->LightsPos > 1) || (mvOccupied->LightsWrap)) + { + mvOccupied->LightsPos--; + if (mvOccupied->LightsPos < 1) + { + mvOccupied->LightsPos = mvOccupied->LightsPosNo; + } + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + SetLights(); + } + } + else if ((GetAsyncKeyState(VK_CONTROL) < 0) && + (ggRearUpperLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu { //------------------------------ if (mvOccupied->ActiveCab == 1) @@ -2035,111 +2227,115 @@ void TTrain::OnKeyDown(int cKey) } } } - if (cKey == Global::Keys[k_RightSign]) // Winger 070304: swiatla tylne (koncowki) - - // wlaczenie - { - if ((GetAsyncKeyState(VK_CONTROL) < 0) && - (ggRearRightLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu - { - //------------------------------ - if (mvOccupied->ActiveCab == 1) - { // kabina 1 (od strony 0) - if (((DynamicObject->iLights[1]) & 48) == 0) - { - DynamicObject->iLights[1] |= 32; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRearRightEndLightButton.SubModel) - { - ggRearRightEndLightButton.PutValue(1); - ggRearRightLightButton.PutValue(0); - } - else - ggRearRightLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[1]) & 48) == 16) - { - DynamicObject->iLights[1] &= (255 - 16); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearRightLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[0]) & 48) == 0) - { - DynamicObject->iLights[0] |= 32; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRearRightEndLightButton.SubModel) - { - ggRearRightEndLightButton.PutValue(1); - ggRearRightLightButton.PutValue(0); - } - else - ggRearRightLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[0]) & 48) == 16) - { - DynamicObject->iLights[0] &= (255 - 16); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRearRightLightButton.PutValue(0); - } - } - } //------------------------------ - else - { - if (mvOccupied->ActiveCab == 1) - { // kabina 0 - if (((DynamicObject->iLights[0]) & 48) == 0) - { - DynamicObject->iLights[0] |= 32; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRightEndLightButton.SubModel) - { - ggRightEndLightButton.PutValue(1); - ggRightLightButton.PutValue(0); - } - else - ggRightLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[0]) & 48) == 16) - { - DynamicObject->iLights[0] &= (255 - 16); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRightLightButton.PutValue(0); - } - } - else - { // kabina -1 - if (((DynamicObject->iLights[1]) & 48) == 0) - { - DynamicObject->iLights[1] |= 32; - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - if (ggRightEndLightButton.SubModel) - { - ggRightEndLightButton.PutValue(1); - ggRightLightButton.PutValue(0); - } - else - ggRightLightButton.PutValue(-1); - } - if (((DynamicObject->iLights[1]) & 48) == 16) - { - DynamicObject->iLights[1] &= (255 - 16); - dsbSwitch->SetVolume(DSBVOLUME_MAX); - dsbSwitch->Play(0, 0, 0); - ggRightLightButton.PutValue(0); - } - } - } - } - else if (cKey == Global::Keys[k_StLinOff]) // Winger 110904: wylacznik st. liniowych + if (cKey == Global::Keys[k_RightSign]) // Winger 070304: swiatla tylne + // (koncowki) - wlaczenie + { + if (!mvOccupied->LightsPosNo > 0) + { + if ((GetAsyncKeyState(VK_CONTROL) < 0) && + (ggRearRightLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu + { + //------------------------------ + if (mvOccupied->ActiveCab == 1) + { // kabina 1 (od strony 0) + if (((DynamicObject->iLights[1]) & 48) == 0) + { + DynamicObject->iLights[1] |= 32; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRearRightEndLightButton.SubModel) + { + ggRearRightEndLightButton.PutValue(1); + ggRearRightLightButton.PutValue(0); + } + else + ggRearRightLightButton.PutValue(-1); + } + if (((DynamicObject->iLights[1]) & 48) == 16) + { + DynamicObject->iLights[1] &= (255 - 16); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRearRightLightButton.PutValue(0); + } + } + else + { // kabina -1 + if (((DynamicObject->iLights[0]) & 48) == 0) + { + DynamicObject->iLights[0] |= 32; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRearRightEndLightButton.SubModel) + { + ggRearRightEndLightButton.PutValue(1); + ggRearRightLightButton.PutValue(0); + } + else + ggRearRightLightButton.PutValue(-1); + } + if (((DynamicObject->iLights[0]) & 48) == 16) + { + DynamicObject->iLights[0] &= (255 - 16); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRearRightLightButton.PutValue(0); + } + } + } //------------------------------ + else + { + if (mvOccupied->ActiveCab == 1) + { // kabina 0 + if (((DynamicObject->iLights[0]) & 48) == 0) + { + DynamicObject->iLights[0] |= 32; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRightEndLightButton.SubModel) + { + ggRightEndLightButton.PutValue(1); + ggRightLightButton.PutValue(0); + } + else + ggRightLightButton.PutValue(-1); + } + if (((DynamicObject->iLights[0]) & 48) == 16) + { + DynamicObject->iLights[0] &= (255 - 16); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRightLightButton.PutValue(0); + } + } + else + { // kabina -1 + if (((DynamicObject->iLights[1]) & 48) == 0) + { + DynamicObject->iLights[1] |= 32; + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + if (ggRightEndLightButton.SubModel) + { + ggRightEndLightButton.PutValue(1); + ggRightLightButton.PutValue(0); + } + else + ggRightLightButton.PutValue(-1); + } + if (((DynamicObject->iLights[1]) & 48) == 16) + { + DynamicObject->iLights[1] &= (255 - 16); + dsbSwitch->SetVolume(DSBVOLUME_MAX); + dsbSwitch->Play(0, 0, 0); + ggRightLightButton.PutValue(0); + } + } + } + } + } + else if (cKey == Global::Keys[k_StLinOff]) // Winger 110904: wylacznik st. + // liniowych { if ((mvControlled->TrainType != dt_EZT) && (mvControlled->TrainType != dt_EP05) && (mvControlled->TrainType != dt_ET40)) @@ -2181,8 +2377,8 @@ void TTrain::OnKeyDown(int cKey) vMechMovement.x += fMechCroach; if (DynamicObject->Mechanik) if (!FreeFlyModeFlag) //żeby nie mieszać obserwując z zewnątrz - DynamicObject->Mechanik->RouteSwitch(1); // na skrzyżowaniu skręci w - // lewo + DynamicObject->Mechanik->RouteSwitch( + 1); // na skrzyżowaniu skręci w lewo } else if (cKey == Global::Keys[k_MechRight]) { @@ -2197,7 +2393,8 @@ void TTrain::OnKeyDown(int cKey) vMechMovement.z -= fMechCroach; // if (DynamicObject->Mechanik) // if (!FreeFlyModeFlag) //żeby nie mieszać obserwując z zewnątrz - // DynamicObject->Mechanik->RouteSwitch(0); //na skrzyżowaniu stanie i poczeka + // DynamicObject->Mechanik->RouteSwitch(0); //na skrzyżowaniu stanie + // i poczeka } else if (cKey == Global::Keys[k_MechForward]) { @@ -2277,10 +2474,13 @@ void TTrain::OnKeyUp(int cKey) }; void TTrain::UpdateMechPosition(double dt) -{ // Ra: mechanik powinien być telepany niezależnie od pozycji pojazdu +{ // Ra: mechanik powinien być + // telepany niezależnie od pozycji + // pojazdu // Ra: trzeba zrobić model bujania głową i wczepić go do pojazdu - // DynamicObject->vFront=DynamicObject->GetDirection(); //to jest już policzone + // DynamicObject->vFront=DynamicObject->GetDirection(); //to jest już + // policzone // Ra: tu by się przydało uwzględnić rozkład sił: // - na postoju horyzont prosto, kabina skosem @@ -2330,9 +2530,9 @@ void TTrain::UpdateMechPosition(double dt) } else { // hamowanie rzucania przy spadku FPS - pMechShake -= - pMechShake * - Min0R(dt, 1); // po tym chyba potrafią zostać jakieś ułamki, które powodują zjazd + pMechShake -= pMechShake * Min0R(dt, 1); // po tym chyba potrafią zostać + // jakieś ułamki, które powodują + // zjazd pMechOffset += vMechMovement * dt; vMechVelocity.y = 0.5 * vMechVelocity.y; pNewMechPosition = pMechOffset + vector3(pMechShake.x, 5 * pMechShake.y, pMechShake.z); @@ -2390,15 +2590,17 @@ bool TTrain::Update() DWORD stat; double dt = Timer::GetDeltaTime(); if (DynamicObject->mdKabina) - { // Ra: TODO: odczyty klawiatury/pulpitu nie powinny być uzależnione od istnienia modelu kabiny + { // Ra: TODO: odczyty klawiatury/pulpitu nie + // powinny być uzależnione od istnienia modelu + // kabiny tor = DynamicObject->GetTrack(); // McZapkie-180203 // McZapkie: predkosc wyswietlana na tachometrze brana jest z obrotow kol float maxtacho = 3; fTachoVelocity = Min0R(fabs(11.31 * mvControlled->WheelDiameter * mvControlled->nrot), mvControlled->Vmax * 1.05); { // skacze osobna zmienna - float ff = floor( - GlobalTime->mr); // skacze co sekunde - pol sekundy pomiar, pol sekundy ustawienie + float ff = floor(GlobalTime->mr); // skacze co sekunde - pol sekundy + // pomiar, pol sekundy ustawienie if (ff != fTachoTimer) // jesli w tej sekundzie nie zmienial { if (fTachoVelocity > 1) // jedzie @@ -2414,8 +2616,8 @@ bool TTrain::Update() fTachoCount += dt * 3; // szybciej zacznij stukac } else if (fTachoCount > 0) - fTachoCount -= - dt * 0.66; // schodz powoli - niektore haslery to ze 4 sekundy potrafia stukac + fTachoCount -= dt * 0.66; // schodz powoli - niektore haslery to ze 4 + // sekundy potrafia stukac /* Ra: to by trzeba było przemyśleć, zmienione na szybko problemy robi //McZapkie: predkosc wyswietlana na tachometrze brana jest z obrotow kol @@ -2433,18 +2635,19 @@ bool TTrain::Update() if (mvControlled->TrainType==dt_EZT) //dla EZT wskazówka porusza się niestabilnie if (fTachoVelocity>7.0) - {fTachoVelocity=floor(0.5+fTachoVelocity+random(5)-random(5)); - //*floor(0.2*fTachoVelocity); + {fTachoVelocity=floor(0.5+fTachoVelocity+random(5)-random(5)); + //*floor(0.2*fTachoVelocity); if (fTachoVelocity<0.0) fTachoVelocity=0.0; } iSekunda=floor(GlobalTime->mr); } */ - // Ra 2014-09: napięcia i prądy muszą być ustalone najpierw, bo wysyłane są ewentualnie na + // Ra 2014-09: napięcia i prądy muszą być ustalone najpierw, bo wysyłane są + // ewentualnie na // PoKeys - if (mvControlled->EngineType != DieselElectric) // Ra 2014-09: czy taki rozdział ma sens? - fHVoltage = mvControlled->RunningTraction - .TractionVoltage; // Winger czy to nie jest zle? *mvControlled->Mains); + if ((mvControlled->EngineType != DieselElectric) && (mvControlled->EngineType != ElectricInductionMotor)) // Ra 2014-09: czy taki rozdzia? ma sens? + fHVoltage = mvControlled->RunningTraction.TractionVoltage; // Winger czy to nie jest zle? + // *mvControlled->Mains); else fHVoltage = mvControlled->Voltage; if (ShowNextCurrent) @@ -2457,8 +2660,8 @@ bool TTrain::Update() fHCurrent[3] = mvSecond->ShowCurrent(3) * 1.05; } else - fHCurrent[0] = fHCurrent[1] = fHCurrent[2] = fHCurrent[3] = 0.0; // gdy nie ma - // człona + fHCurrent[0] = fHCurrent[1] = fHCurrent[2] = fHCurrent[3] = + 0.0; // gdy nie ma człona } else { // normalne pokazywanie @@ -2467,27 +2670,143 @@ bool TTrain::Update() fHCurrent[2] = mvControlled->ShowCurrent(2); fHCurrent[3] = mvControlled->ShowCurrent(3); } + + bool kier = (DynamicObject->DirectionGet()*mvOccupied->ActiveCab > 0); + TDynamicObject *p = DynamicObject->GetFirstDynamic(mvOccupied->ActiveCab < 0 ? 1 : 0, 4); + int in = 0; + fEIMParams[0][6] = 0; + iCarNo = 0; + iPowerNo = 0; + iUnitNo = 1; + + for (int i = 0; i < 8; i++) + { + bMains[i] = false; + fCntVol[i] = 0.0f; + bPants[i][0] = false; + bPants[i][1] = false; + bFuse[i] = false; + bBatt[i] = false; + bConv[i] = false; + bComp[i][0] = false; + bComp[i][1] = false; + bHeat[i] = false; + } + for (int i = 0; i < 20; i++) + { + if (p) + { + fPress[i][0] = p->MoverParameters->BrakePress; + fPress[i][1] = p->MoverParameters->PipePress; + fPress[i][2] = p->MoverParameters->ScndPipePress; + bDoors[i][0] = (p->dDoorMoveL > 0.001) || (p->dDoorMoveR > 0.001); + bDoors[i][1] = (p->dDoorMoveR > 0.001); + bDoors[i][2] = (p->dDoorMoveL > 0.001); + iDoorNo[i] = p->iAnimType[ANIM_DOORS]; + iUnits[i] = iUnitNo; + cCode[i] = p->MoverParameters->TypeName[p->MoverParameters->TypeName.Length()]; + asCarName[i] = p->GetName(); + bPants[iUnitNo - 1][0] = (bPants[iUnitNo - 1][0] || p->MoverParameters->PantFrontUp); + bPants[iUnitNo - 1][1] = (bPants[iUnitNo - 1][1] || p->MoverParameters->PantRearUp); + bComp[iUnitNo - 1][0] = (bComp[iUnitNo - 1][0] || p->MoverParameters->CompressorAllow); + if (p->MoverParameters->CompressorSpeed>0.00001) + { + bComp[iUnitNo - 1][1] = (bComp[iUnitNo - 1][1] || p->MoverParameters->CompressorFlag); + } + if ((in < 8) && (p->MoverParameters->eimc[eimc_p_Pmax] > 1)) + { + fEIMParams[1 + in][0] = p->MoverParameters->eimv[eimv_Fr]; + fEIMParams[1 + in][1] = Max0R(fEIMParams[1 + in][0], 0); + fEIMParams[1 + in][2] = -Min0R(fEIMParams[1 + in][0], 0); + fEIMParams[1 + in][3] = p->MoverParameters->eimv[eimv_Fr] / + Max0R(p->MoverParameters->eimv[eimv_Fful], 1); + fEIMParams[1 + in][4] = Max0R(fEIMParams[1 + in][3], 0); + fEIMParams[1 + in][5] = -Min0R(fEIMParams[1 + in][3], 0); + fEIMParams[1 + in][6] = p->MoverParameters->eimv[eimv_If]; + fEIMParams[1 + in][7] = p->MoverParameters->eimv[eimv_U]; + fEIMParams[1 + in][8] = p->MoverParameters->Itot;//p->MoverParameters->eimv[eimv_Ipoj]; + fEIMParams[1 + in][9] = p->MoverParameters->Voltage; + fEIMParams[0][6] += fEIMParams[1 + in][8]; + bMains[in] = p->MoverParameters->Mains; + fCntVol[in] = p->MoverParameters->BatteryVoltage; + bFuse[in] = p->MoverParameters->FuseFlag; + bBatt[in] = p->MoverParameters->Battery; + bConv[in] = p->MoverParameters->ConverterFlag; + bHeat[in] = p->MoverParameters->Heating; + in++; + iPowerNo = in; + } + // p = p->NextC(4); //prev + if ((kier ? p->NextC(128) : p->PrevC(128)) != (kier ? p->NextC(4) : p->PrevC(4))) + iUnitNo++; + p = (kier ? p->NextC(4) : p->PrevC(4)); + iCarNo = i + 1; + } + else + { + fPress[i][0] = 0; + fPress[i][1] = 0; + fPress[i][2] = 0; + bDoors[i][0] = false; + bDoors[i][1] = false; + bDoors[i][2] = false; + iUnits[i] = 0; + cCode[i] = 0;//'0'; + asCarName[i] = ""; + } + } + + if (mvControlled == mvOccupied) + fEIMParams[0][3] = mvControlled->eimv[eimv_Fzad]; // procent zadany + else + fEIMParams[0][3] = + mvControlled->eimv[eimv_Fzad] - mvOccupied->LocalBrakeRatio(); // procent zadany + fEIMParams[0][4] = Max0R(fEIMParams[0][3], 0); + fEIMParams[0][5] = -Min0R(fEIMParams[0][3], 0); + fEIMParams[0][1] = fEIMParams[0][4] * mvControlled->eimv[eimv_Fful]; + fEIMParams[0][2] = fEIMParams[0][5] * mvControlled->eimv[eimv_Fful]; + fEIMParams[0][0] = fEIMParams[0][1] - fEIMParams[0][2]; + fEIMParams[0][7] = 0; + fEIMParams[0][8] = 0; + fEIMParams[0][9] = 0; + + for (int i = in; i < 8; i++) + { + fEIMParams[1 + i][0] = 0; + fEIMParams[1 + i][1] = 0; + fEIMParams[1 + i][2] = 0; + fEIMParams[1 + i][3] = 0; + fEIMParams[1 + i][4] = 0; + fEIMParams[1 + i][5] = 0; + fEIMParams[1 + i][6] = 0; + fEIMParams[1 + i][7] = 0; + fEIMParams[1 + i][8] = 0; + fEIMParams[1 + i][9] = 0; + } + if (Global::iFeedbackMode == 4) { // wykonywać tylko gdy wyprowadzone na pulpit Console::ValueSet(0, mvOccupied->Compressor); // Ra: sterowanie miernikiem: zbiornik główny - Console::ValueSet(1, mvOccupied->PipePress); // Ra: sterowanie miernikiem: przewód - // główny - Console::ValueSet( - 2, mvOccupied->BrakePress); // Ra: sterowanie miernikiem: cylinder hamulcowy + Console::ValueSet(1, + mvOccupied->PipePress); // Ra: sterowanie miernikiem: przewód główny + Console::ValueSet(2, mvOccupied->BrakePress); // Ra: sterowanie miernikiem: cylinder hamulcowy Console::ValueSet(3, fHVoltage); // woltomierz wysokiego napięcia Console::ValueSet(4, fHCurrent[2]); // Ra: sterowanie miernikiem: drugi amperomierz - Console::ValueSet( - 5, fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]); // pierwszy amperomierz; - // dla EZT prąd całkowity - Console::ValueSet(6, fTachoVelocity); ////Ra: prędkość na pin 43 - wyjście analogowe (to - /// nie jest PWM); skakanie zapewnia mechanika + Console::ValueSet(5, + fHCurrent[(mvControlled->TrainType & dt_EZT) ? 0 : 1]); // pierwszy amperomierz; dla + // EZT prąd całkowity + Console::ValueSet(6, fTachoVelocity); ////Ra: prędkość na pin 43 - wyjście + Console::ValueSet(7, mvControlled->MainCtrlActualPos + mvControlled->ScndCtrlActualPos); //nbmx: Wal kulakowy + /// analogowe (to nie jest PWM); + /// skakanie zapewnia mechanika /// napędu } - // hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia przy dowolnym - // ustawieniu kierunkowego - // Ra: to już jest w T_MoverParameters::TractionForce(), ale zależy od kierunku + // hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia + // przy dowolnym ustawieniu kierunkowego + // Ra: to już jest w T_MoverParameters::TractionForce(), ale zależy od + // kierunku if (mvControlled->EngineType == ElectricSeriesMotor) if (fabs(mvControlled->RunningTraction.TractionVoltage) < 0.5 * @@ -2516,13 +2835,14 @@ bool TTrain::Update() ((mvControlled->EngineType == ElectricSeriesMotor) || (mvControlled->TrainType == dt_EZT)) && (DynamicObject->Controller == Humandriver)) // hunter-110212: poprawka dla EZT - { // hunter-091012: poprawka (zmiana warunku z CompressorPower /rozne od 0/ na /rowne - // 1/) + { // hunter-091012: poprawka (zmiana warunku z CompressorPower /rozne od + // 0/ na /rowne 1/) if (fConverterTimer < fConverterPrzekaznik) { mvControlled->ConvOvldFlag = true; - mvControlled->MainSwitch(false); - } + if (mvControlled->TrainType != dt_EZT) + mvControlled->MainSwitch(false); + } else if (fConverterTimer >= fConverterPrzekaznik) mvControlled->CompressorSwitch(true); } @@ -2790,10 +3110,13 @@ bool TTrain::Update() // McZapkie! - to wazne - SoundFlag wystawiane jest przez moje moduly // gdy zachodza pewne wydarzenia komentowane dzwiekiem. // Mysle ze wystarczy sprawdzac a potem zerowac SoundFlag tutaj - // a nie w DynObject - gdyby cos poszlo zle to po co szarpac dzwiekiem co 10ms. + // a nie w DynObject - gdyby cos poszlo zle to po co szarpac dzwiekiem co + // 10ms. - if (TestFlag(mvOccupied->SoundFlag, - sound_relay)) // przekaznik - gdy bezpiecznik, automatyczny rozruch itp + if (TestFlag(mvOccupied->SoundFlag, sound_relay)) // przekaznik - gdy + // bezpiecznik, + // automatyczny rozruch + // itp { if (mvOccupied->EventFlag || TestFlag(mvOccupied->SoundFlag, sound_loud)) { @@ -2857,7 +3180,8 @@ bool TTrain::Update() mvOccupied->SoundFlag = 0; /* - for (int b=0; b<2; b++) //MC: aby zerowac stukanie przekaznikow w czlonie silnikowym + for (int b=0; b<2; b++) //MC: aby zerowac stukanie przekaznikow w + czlonie silnikowym if (TestFlag(mvControlled->Couplers[b].CouplingFlag,ctrain_controll)) if (mvControlled->Couplers[b].Connected.Power>0.01) mvControlled->Couplers[b]->Connected->SoundFlag=0; @@ -2907,16 +3231,18 @@ bool TTrain::Update() //fHaslerTimer+=dt; //if (fHaslerTimer>fHaslerTime) {//Ra: ryzykowne jest to, gdyż może się nie uaktualniać prędkość - //Ra: prędkość się powinna zaokrąglać tam gdzie się liczy fTachoVelocity + //Ra: prędkość się powinna zaokrąglać tam gdzie się liczy + fTachoVelocity if (ggVelocity.SubModel) - {//ZiomalCl: wskazanie Haslera w kabinie A ze zwloka czasowa oraz odpowiednia - tolerancja - //Nalezy sie zastanowic na przyszlosc nad rozroznieniem predkosciomierzy (dokladnosc - wskazan, zwloka czasowa wskazania, inne funkcje) - //ZiomalCl: W ezt typu stare EN57 wskazania haslera sa mniej dokladne (linka) + {//ZiomalCl: wskazanie Haslera w kabinie A ze zwloka czasowa oraz odpowiednia + tolerancja + //Nalezy sie zastanowic na przyszlosc nad rozroznieniem predkosciomierzy + (dokladnosc wskazan, zwloka czasowa wskazania, inne funkcje) + //ZiomalCl: W ezt typu stare EN57 wskazania haslera sa mniej dokladne + (linka) //ggVelocity.UpdateValue(fTachoVelocity>2?fTachoVelocity+0.5-random(mvControlled->TrainType==dt_EZT?5:2)/2:0); - ggVelocity.UpdateValue(Min0R(fTachoVelocity,mvControlled->Vmax*1.05)); //ograniczenie - maksymalnego wskazania na analogowym + ggVelocity.UpdateValue(Min0R(fTachoVelocity,mvControlled->Vmax*1.05)); + //ograniczenie maksymalnego wskazania na analogowym ggVelocity.Update(); } if (ggVelocityDgt.SubModel) @@ -2925,10 +3251,10 @@ bool TTrain::Update() ggVelocityDgt.Update(); } if (ggVelocity_B.SubModel) - {//ZiomalCl: wskazanie Haslera w kabinie B ze zwloka czasowa oraz odpowiednia - tolerancja - //Nalezy sie zastanowic na przyszlosc nad rozroznieniem predkosciomierzy (dokladnosc - wskazan, zwloka czasowa wskazania, inne funkcje) + {//ZiomalCl: wskazanie Haslera w kabinie B ze zwloka czasowa oraz odpowiednia + tolerancja + //Nalezy sie zastanowic na przyszlosc nad rozroznieniem predkosciomierzy + (dokladnosc wskazan, zwloka czasowa wskazania, inne funkcje) //Velocity_B.UpdateValue(fTachoVelocity>2?fTachoVelocity+0.5-random(mvControlled->TrainType==dt_EZT?5:2)/2:0); ggVelocity_B.UpdateValue(fTachoVelocity); ggVelocity_B.Update(); @@ -3055,11 +3381,12 @@ bool TTrain::Update() } if (mvControlled->SlippingWheels) - { // Ra 2014-12: lokomotywy 181/182 dostają SlippingWheels po zahamowaniu powyżej 2.85 bara - // i buczały + { // Ra 2014-12: lokomotywy 181/182 + // dostają SlippingWheels po zahamowaniu + // powyżej 2.85 bara i buczały double veldiff = (DynamicObject->GetVelocity() - fTachoVelocity) / mvControlled->Vmax; - if (veldiff < - -0.01) // 1% Vmax rezerwy, żeby 181/182 nie buczały po zahamowaniu, ale to proteza + if (veldiff < -0.01) // 1% Vmax rezerwy, żeby 181/182 nie buczały po + // zahamowaniu, ale to proteza { if (fabs(mvControlled->Im) > 10.0) btLampkaPoslizg.TurnOn(); @@ -3091,6 +3418,15 @@ bool TTrain::Update() dsbSlipAlarm->Stop(); } + if ((mvControlled->Mains) || (mvControlled->TrainType == dt_EZT)) + { + btLampkaNadmSil.Turn(mvControlled->FuseFlagCheck()); + } + else + { + btLampkaNadmSil.TurnOff(); + } + if (mvControlled->Mains) { btLampkaWylSzybki.TurnOn(); @@ -3100,8 +3436,8 @@ bool TTrain::Update() (mvControlled->MainCtrlActualPos == 0)); // do EU04 if ((mvControlled->Itot != 0) || (mvOccupied->BrakePress > 2) || (mvOccupied->PipePress < 3.6)) - btLampkaStyczn.TurnOff(); // Ra: czy to jest udawanie działania styczników - // liniowych? + btLampkaStyczn.TurnOff(); // Ra: czy to jest udawanie działania + // styczników liniowych? else if (mvOccupied->BrakePress < 1) btLampkaStyczn.TurnOn(); // mozna prowadzic rozruch if (((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) && @@ -3112,18 +3448,19 @@ bool TTrain::Update() else btLampkaUkrotnienie.TurnOff(); - // if ((TestFlag(mvControlled->BrakeStatus,+b_Rused+b_Ractive)))//Lampka + // if + // ((TestFlag(mvControlled->BrakeStatus,+b_Rused+b_Ractive)))//Lampka // drugiego stopnia hamowania btLampkaHamPosp.Turn((TestFlag(mvOccupied->BrakeStatus, 1))); // lampka drugiego stopnia - // hamowania //TODO: - // youBy wyciągnąć flagę - // wysokiego stopnia + // hamowania //TODO: youBy + // wyciągnąć flagę wysokiego + // stopnia // hunter-111211: wylacznik cisnieniowy - Ra: tutaj? w kabinie? //yBARC - // omujborzegrzesiuzniszczylesmicalydzien // if (mvControlled->TrainType!=dt_EZT) - // if (((mvOccupied->BrakePress > 2) || ( mvOccupied->PipePress < 3.6 )) && ( - // mvControlled->MainCtrlPos != 0 )) + // if (((mvOccupied->BrakePress > 2) || ( mvOccupied->PipePress < + // 3.6 )) && ( mvControlled->MainCtrlPos != 0 )) // mvControlled->StLinFlag=true; //------- @@ -3132,7 +3469,6 @@ bool TTrain::Update() mvControlled->ResistorsFlagCheck()); //------- - btLampkaNadmSil.Turn(mvControlled->FuseFlagCheck()); btLampkaWysRozr.Turn(mvControlled->Imax == mvControlled->ImaxHi); if (((mvControlled->ScndCtrlActualPos > 0) || ((mvControlled->RList[mvControlled->MainCtrlActualPos].ScndAct != 0) && @@ -3147,8 +3483,8 @@ bool TTrain::Update() btLampkaSprezarka.Turn(mvControlled->CompressorFlag); // mutopsitka dziala // boczniki unsigned char scp; // Ra: dopisałem "unsigned" - // Ra: w SU45 boczniki wchodzą na MainCtrlPos, a nie na MainCtrlActualPos - pokićkał - // ktoś? + // Ra: w SU45 boczniki wchodzą na MainCtrlPos, a nie na MainCtrlActualPos + // - pokićkał ktoś? scp = mvControlled->RList[mvControlled->MainCtrlPos].ScndAct; scp = (scp == 255 ? 0 : scp); // Ra: whatta hella is this? if ((mvControlled->ScndCtrlPos > 0) || (mvControlled->ScndInMain) && (scp > 0)) @@ -3169,10 +3505,12 @@ bool TTrain::Update() { //sprezarka w drugim wozie bool comptemp=false; if (DynamicObject->NextConnected) - if (TestFlag(mvControlled->Couplers[1].CouplingFlag,ctrain_controll)) + if + (TestFlag(mvControlled->Couplers[1].CouplingFlag,ctrain_controll)) comptemp=DynamicObject->NextConnected->MoverParameters->CompressorFlag; if ((DynamicObject->PrevConnected) && (!comptemp)) - if (TestFlag(mvControlled->Couplers[0].CouplingFlag,ctrain_controll)) + if + (TestFlag(mvControlled->Couplers[0].CouplingFlag,ctrain_controll)) comptemp=DynamicObject->PrevConnected->MoverParameters->CompressorFlag; btLampkaSprezarkaB.Turn(comptemp); */ @@ -3182,7 +3520,6 @@ bool TTrain::Update() btLampkaWylSzybki.TurnOff(); btLampkaOpory.TurnOff(); btLampkaStyczn.TurnOff(); - btLampkaNadmSil.TurnOff(); btLampkaUkrotnienie.TurnOff(); btLampkaHamPosp.TurnOff(); btLampkaBoczniki.TurnOff(); @@ -3212,8 +3549,8 @@ bool TTrain::Update() false); { // yB - wskazniki drugiego czlonu - TDynamicObject * - tmp; //=mvControlled->mvSecond; //Ra 2014-07: trzeba to jeszcze wyjąć z kabiny... + TDynamicObject *tmp; //=mvControlled->mvSecond; //Ra 2014-07: trzeba to + // jeszcze wyjąć z kabiny... // Ra 2014-07: no nie ma potrzeby szukać tego w każdej klatce tmp = NULL; if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) && @@ -3239,15 +3576,15 @@ bool TTrain::Update() btLampkaStycznB.TurnOn(); // mozna prowadzic rozruch //----------------- - // //hunter-271211: brak jazdy w drugim czlonie, gdy w pierwszym tez nie - // ma (i odwrotnie) - Ra: tutaj? w kabinie? + // //hunter-271211: brak jazdy w drugim czlonie, gdy w + // pierwszym tez nie ma (i odwrotnie) - Ra: tutaj? w kabinie? // if (tmp->MoverParameters->TrainType!=dt_EZT) // if (((tmp->MoverParameters->BrakePress > 2) || ( // tmp->MoverParameters->PipePress < 3.6 )) && ( // tmp->MoverParameters->MainCtrlPos != 0 )) // { - // tmp->MoverParameters->MainCtrlActualPos=0; //inaczej StLinFlag nie - // zmienia sie na false w drugim pojezdzie + // tmp->MoverParameters->MainCtrlActualPos=0; //inaczej + // StLinFlag nie zmienia sie na false w drugim pojezdzie // //tmp->MoverParameters->StLinFlag=true; // mvControlled->StLinFlag=true; // } @@ -3256,8 +3593,8 @@ bool TTrain::Update() // //tmp->MoverParameters->StLinFlag=true; //----------------- - // hunter-271211: sygnalizacja poslizgu w pierwszym pojezdzie, gdy wystapi w - // drugim + // hunter-271211: sygnalizacja poslizgu w pierwszym pojezdzie, gdy + // wystapi w drugim btLampkaPoslizg.Turn(tmp->MoverParameters->SlippingWheels); //----------------- @@ -3317,7 +3654,7 @@ bool TTrain::Update() // KURS90 btLampkaMaxSila.Turn(abs(mvControlled->Im) >= 350); btLampkaPrzekrMaxSila.Turn(abs(mvControlled->Im) >= 450); - btLampkaRadio.Turn(mvControlled->Radio); + btLampkaRadio.Turn(mvOccupied->Radio); btLampkaHamulecReczny.Turn(mvOccupied->ManualBrakePos > 0); // NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu btLampkaDoorLeft.Turn(mvOccupied->DoorLeftOpened); @@ -3360,7 +3697,8 @@ bool TTrain::Update() ggMainCtrlAct.Update(); } if (ggScndCtrl.SubModel) - { // Ra: od byte odejmowane boolean i konwertowane potem na double? + { // Ra: od byte odejmowane boolean i konwertowane + // potem na double? ggScndCtrl.UpdateValue( double(mvControlled->ScndCtrlPos - ((mvControlled->TrainType == dt_ET42) && mvControlled->DynamicBrakeFlag))); @@ -3378,22 +3716,17 @@ bool TTrain::Update() if (ggBrakeCtrl.SubModel) { if (DynamicObject->Mechanik ? - (DynamicObject->Mechanik->AIControllFlag ? false : Global::iFeedbackMode == 4) : + (DynamicObject->Mechanik->AIControllFlag ? false : + Global::iFeedbackMode == 4 ) : false) // nie blokujemy AI { // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba - double b = Console::AnalogGet(0); // odczyt z pulpitu i modyfikacja pozycji kranu - if ((b >= 0.0) && ((mvOccupied->BrakeHandle == FV4a) || - (mvOccupied->BrakeHandle == - FVel6))) // może można usunąć ograniczenie do FV4a i FVel6? + // Firleju: dlatego kasujemy i zastepujemy funkcją w Console + if (((mvOccupied->BrakeHandle == FV4a) || + (mvOccupied->BrakeHandle == FVel6))) // może można usunąć ograniczenie do FV4a i FVel6? { - b = (((Global::fCalibrateIn[0][3] * b) + Global::fCalibrateIn[0][2]) * b + - Global::fCalibrateIn[0][1]) * - b + - Global::fCalibrateIn[0][0]; - if (b < -2.0) - b = -2.0; - else if (b > mvOccupied->BrakeCtrlPosNo) - b = mvOccupied->BrakeCtrlPosNo; + double b = Console::AnalogCalibrateGet(0); + b = Global::CutValueToRange(-2.0, b, mvOccupied->BrakeCtrlPosNo); // przycięcie zmiennej do granic + ggBrakeCtrl.UpdateValue(b); // przesów bez zaokrąglenia mvOccupied->BrakeLevelSet(b); } @@ -3411,17 +3744,11 @@ bool TTrain::Update() (DynamicObject->Mechanik->AIControllFlag ? false : Global::iFeedbackMode == 4) : false) // nie blokujemy AI { // Ra: nie najlepsze miejsce, ale na początek gdzieś to dać trzeba - double b = Console::AnalogGet(1); // odczyt z pulpitu i modyfikacja pozycji kranu - if ((b >= 0.0) && (mvOccupied->BrakeLocHandle == FD1)) + // Firleju: dlatego kasujemy i zastepujemy funkcją w Console + if ((mvOccupied->BrakeLocHandle == FD1)) { - b = (((Global::fCalibrateIn[1][3] * b) + Global::fCalibrateIn[1][2]) * b + - Global::fCalibrateIn[1][1]) * - b + - Global::fCalibrateIn[1][0]; - if (b < 0.0) - b = 0.0; - else if (b > Hamulce::LocalBrakePosNo) - b = Hamulce::LocalBrakePosNo; + double b = Console::AnalogCalibrateGet(1); + b = Global::CutValueToRange(0.0, b, Hamulce::LocalBrakePosNo); // przycięcie zmiennej do granic ggLocalBrake.UpdateValue(b); // przesów bez zaokrąglenia mvOccupied->LocalBrakePos = int(1.09 * b); // sposób zaokrąglania jest do ustalenia @@ -3485,7 +3812,7 @@ bool TTrain::Update() ggMainButton.Update(); if (ggRadioButton.SubModel) { - ggRadioButton.PutValue(mvControlled->Radio ? 1 : 0); + ggRadioButton.PutValue(mvOccupied->Radio ? 1 : 0); ggRadioButton.Update(); } if (ggConverterButton.SubModel) @@ -3669,6 +3996,11 @@ bool TTrain::Update() else ggRearRightLightButton.PutValue(-1); } + if (ggLightsButton.SubModel) + { + ggLightsButton.PutValue(mvOccupied->LightsPos - 1); + ggLightsButton.Update(); + } //--------- // Winger 010304 - pantografy @@ -3691,8 +4023,8 @@ bool TTrain::Update() } // Winger 020304 - ogrzewanie //---------- - // hunter-080812: poprawka na ogrzewanie w elektrykach - usuniete uzaleznienie od - // przetwornicy + // hunter-080812: poprawka na ogrzewanie w elektrykach - usuniete + // uzaleznienie od przetwornicy if (ggTrainHeatingButton.SubModel) { if (mvControlled->Heating) @@ -3763,14 +4095,20 @@ bool TTrain::Update() TestFlag(mvOccupied->SecuritySystem.Status, s_SHPalarm)) { dsbBuzzer->GetStatus(&stat); - if (!(stat & DSBSTATUS_PLAYING)) + if (!(stat & DSBSTATUS_PLAYING)) + { dsbBuzzer->Play(0, 0, DSBPLAY_LOOPING); + Console::BitsSet(1 << 14); // ustawienie bitu 16 na PoKeys + } } else { dsbBuzzer->GetStatus(&stat); - if (stat & DSBSTATUS_PLAYING) + if (stat & DSBSTATUS_PLAYING) + { dsbBuzzer->Stop(); + Console::BitsClear(1 << 14); // ustawienie bitu 16 na PoKeys + } } } else // wylaczone @@ -3778,8 +4116,11 @@ bool TTrain::Update() btLampkaCzuwaka.TurnOff(); btLampkaSHP.TurnOff(); dsbBuzzer->GetStatus(&stat); - if (stat & DSBSTATUS_PLAYING) + if (stat & DSBSTATUS_PLAYING) + { dsbBuzzer->Stop(); + Console::BitsClear(1 << 14); // ustawienie bitu 16 na PoKeys + } } //****************************************** @@ -3816,7 +4157,8 @@ bool TTrain::Update() } //---------------- - // hunter-141211: wyl. szybki zalaczony i wylaczony przeniesiony z OnKeyPress() + // hunter-141211: wyl. szybki zalaczony i wylaczony przeniesiony z + // OnKeyPress() if (Console::Pressed(VK_SHIFT) && Console::Pressed(Global::Keys[k_Main])) { fMainRelayTimer += dt; @@ -3826,10 +4168,10 @@ bool TTrain::Update() if (fMainRelayTimer > mvControlled->InitialCtrlDelay) // wlaczanie WSa z opoznieniem if (mvControlled->MainSwitch(true)) { - // if (mvControlled->MainCtrlPos!=0) //zabezpieczenie, by po wrzuceniu - // pozycji przed wlaczonym - // mvControlled->StLinFlag=true; //WSem nie wrzucilo na ta pozycje po - // jego zalaczeniu //yBARC - co to tutaj robi?! + // if (mvControlled->MainCtrlPos!=0) //zabezpieczenie, by po + // wrzuceniu pozycji przed wlaczonym + // mvControlled->StLinFlag=true; //WSem nie wrzucilo na ta + // pozycje po jego zalaczeniu //yBARC - co to tutaj robi?! if (mvControlled->EngineType == DieselEngine) dsbDieselIgnition->Play(0, 0, 0); } @@ -3839,8 +4181,9 @@ bool TTrain::Update() if (ggConverterButton.GetValue() != 0) // po puszczeniu przycisku od WSa odpalanie potwora mvControlled->ConverterSwitch(true); - // hunter-091012: przeniesione z mover.pas, zeby dzwiek sie nie zapetlal, drugi warunek - // zeby nie odtwarzalo w nieskonczonosc i przeniesienie zerowania timera + // hunter-091012: przeniesione z mover.pas, zeby dzwiek sie nie zapetlal, + // drugi warunek zeby nie odtwarzalo w nieskonczonosc i przeniesienie + // zerowania timera if ((mvControlled->Mains != true) && (fMainRelayTimer > 0)) { dsbRelay->Play(0, 0, 0); @@ -3864,7 +4207,8 @@ bool TTrain::Update() ggMainOnButton.PutValue(1); if (mvControlled->MainSwitch(true)) { - if (mvControlled->MainCtrlPos!=0) //hunter-131211: takie zabezpieczenie + if (mvControlled->MainCtrlPos!=0) //hunter-131211: takie + zabezpieczenie mvControlled->StLinFlag=true; if (mvControlled->EngineType==DieselEngine) @@ -3889,7 +4233,8 @@ bool TTrain::Update() // hunter-131211: czuwak przeniesiony z OnKeyPress // hunter-091012: zrobiony test czuwaka if (Console::Pressed(Global::Keys[k_Czuwak])) - { // czuwak testuje kierunek, ale podobno w EZT nie, więc może być w rozrządczym + { // czuwak testuje kierunek, ale podobno w + // EZT nie, więc może być w rozrządczym fCzuwakTestTimer += dt; ggSecurityResetButton.PutValue(1); if (CAflag == false) @@ -3956,8 +4301,14 @@ bool TTrain::Update() if (Console::Pressed(Global::Keys[k_Sand])) { - mvControlled->SandDose = true; - // mvControlled->SandDoseOn(true); + if (mvControlled->TrainType != dt_EZT && ggSandButton.SubModel != NULL) + { + // dsbPneumaticRelay->SetVolume(-30); + // dsbPneumaticRelay->Play(0,0,0); + ggSandButton.PutValue(1); + mvControlled->SandDose = true; + // mvControlled->SandDoseOn(true); + } } else { @@ -4020,7 +4371,9 @@ bool TTrain::Update() ggConverterButton.PutValue(0); ggConverterOffButton.PutValue(1); mvControlled->ConverterSwitch(false); - } + if ((mvControlled->TrainType == dt_EZT) && (!TestFlag(mvControlled->EngDmgFlag, 4))) + mvControlled->ConvOvldFlag = false; + } // if ( // !Console::Pressed(VK_SHIFT)&&Console::Pressed(Global::Keys[k_Compressor])&&((mvControlled->EngineType==ElectricSeriesMotor)||(mvControlled->TrainType==dt_EZT)) @@ -4055,12 +4408,15 @@ bool TTrain::Update() */ //----------------- - if (!FreeFlyModeFlag) + if ((!FreeFlyModeFlag) && + (!(DynamicObject->Mechanik ? DynamicObject->Mechanik->AIControllFlag : false))) { - if (Console::Pressed(Global::Keys[k_Releaser])) // yB: odluzniacz caly czas trzymany, - // warunki powinny byc takie same, jak - // przy naciskaniu. Wlasciwie stamtad - // mozna wyrzucic sprawdzanie + if (Console::Pressed(Global::Keys[k_Releaser])) // yB: odluzniacz caly + // czas trzymany, warunki + // powinny byc takie same, + // jak przy naciskaniu. + // Wlasciwie stamtad mozna + // wyrzucic sprawdzanie // nacisniecia. { if ((mvControlled->EngineType == ElectricSeriesMotor) || @@ -4122,9 +4478,9 @@ bool TTrain::Update() { if (ggUniversal3Button.SubModel) { - ggUniversal3Button.PutValue(1); // hunter-131211: z UpdateValue na PutValue - // - by zachowywal sie jak pozostale - // przelaczniki + ggUniversal3Button.PutValue(1); // hunter-131211: z UpdateValue na + // PutValue - by zachowywal sie jak + // pozostale przelaczniki if (btLampkaUniversal3.Active()) LampkaUniversal3_st = true; } @@ -4145,9 +4501,9 @@ bool TTrain::Update() { if (ggUniversal3Button.SubModel) { - ggUniversal3Button.PutValue(0); // hunter-131211: z UpdateValue na PutValue - // - by zachowywal sie jak pozostale - // przelaczniki + ggUniversal3Button.PutValue(0); // hunter-131211: z UpdateValue na + // PutValue - by zachowywal sie jak + // pozostale przelaczniki if (btLampkaUniversal3.Active()) LampkaUniversal3_st = false; } @@ -4155,8 +4511,8 @@ bool TTrain::Update() } } - // hunter-091012: to w ogole jest bez sensu i tak namodzone ze nie wiadomo o co chodzi - - // zakomentowalem i zrobilem po swojemu + // hunter-091012: to w ogole jest bez sensu i tak namodzone ze nie wiadomo o + // co chodzi - zakomentowalem i zrobilem po swojemu /* if ( Console::Pressed(Global::Keys[k_Univ3]) ) { @@ -4180,15 +4536,15 @@ bool TTrain::Update() {//bez [Ctrl] przełączamy cośtem if (Console::Pressed(VK_SHIFT)) { - ggUniversal3Button.PutValue(1); //hunter-131211: z UpdateValue na PutValue - by - zachowywal sie jak pozostale przelaczniki + ggUniversal3Button.PutValue(1); //hunter-131211: z UpdateValue na + PutValue - by zachowywal sie jak pozostale przelaczniki if (btLampkaUniversal3.Active()) LampkaUniversal3_st=true; } else { - ggUniversal3Button.PutValue(0); //hunter-131211: z UpdateValue na PutValue - by - zachowywal sie jak pozostale przelaczniki + ggUniversal3Button.PutValue(0); //hunter-131211: z UpdateValue na + PutValue - by zachowywal sie jak pozostale przelaczniki if (btLampkaUniversal3.Active()) LampkaUniversal3_st=false; } @@ -4232,7 +4588,8 @@ bool TTrain::Update() } */ - // hunter-091012: przepisanie univ4 i zrobione z uwzglednieniem przelacznika swiatla + // hunter-091012: przepisanie univ4 i zrobione z uwzglednieniem przelacznika + // swiatla if (Console::Pressed(Global::Keys[k_Univ4])) { if (Console::Pressed(VK_SHIFT)) @@ -4258,9 +4615,9 @@ bool TTrain::Update() bCabLightDim = false; if (ggCabLightDimButton.SubModel) { - ggCabLightDimButton.PutValue(0); // hunter-131211: z UpdateValue na PutValue - // - by zachowywal sie jak pozostale - // przelaczniki + ggCabLightDimButton.PutValue(0); // hunter-131211: z UpdateValue na + // PutValue - by zachowywal sie jak + // pozostale przelaczniki } } else @@ -4289,7 +4646,8 @@ bool TTrain::Update() } // Ra: przeklejka z SPKS - płynne poruszanie hamulcem - // if ((mvOccupied->BrakeHandle==FV4a)&&(Console::Pressed(Global::Keys[k_IncBrakeLevel]))) + // if + // ((mvOccupied->BrakeHandle==FV4a)&&(Console::Pressed(Global::Keys[k_IncBrakeLevel]))) if ((Console::Pressed(Global::Keys[k_IncBrakeLevel]))) { if (Console::Pressed(VK_CONTROL)) @@ -4303,7 +4661,8 @@ bool TTrain::Update() // mvOccupied->BrakeCtrlPos= floor(mvOccupied->BrakeCtrlPosR+0.499); } } - // if ((mvOccupied->BrakeHandle==FV4a)&&(Console::Pressed(Global::Keys[k_DecBrakeLevel]))) + // if + // ((mvOccupied->BrakeHandle==FV4a)&&(Console::Pressed(Global::Keys[k_DecBrakeLevel]))) if ((Console::Pressed(Global::Keys[k_DecBrakeLevel]))) { if (Console::Pressed(VK_CONTROL)) @@ -4332,7 +4691,8 @@ bool TTrain::Update() { // mvOccupied->BrakeCtrlPosR+=(mvOccupied->BrakeCtrlPosR>mvOccupied->BrakeCtrlPosNo?0:dt*2); mvOccupied->BrakeLevelAdd(dt * 2); - // mvOccupied->BrakeCtrlPos= floor(mvOccupied->BrakeCtrlPosR+0.499); + // mvOccupied->BrakeCtrlPos= + // floor(mvOccupied->BrakeCtrlPosR+0.499); } } @@ -4347,7 +4707,8 @@ bool TTrain::Update() else { // mvOccupied->BrakeCtrlPosR-=(mvOccupied->BrakeCtrlPosR<-1?0:dt*2); - // mvOccupied->BrakeCtrlPos= floor(mvOccupied->BrakeCtrlPosR+0.499); + // mvOccupied->BrakeCtrlPos= + // floor(mvOccupied->BrakeCtrlPosR+0.499); mvOccupied->BrakeLevelAdd(-dt * 2); } } @@ -4483,7 +4844,8 @@ bool TTrain::Update() ggPantFrontButtonOff.PutValue(0); } - /* if ((mvControlled->Mains) && (mvControlled->EngineType==ElectricSeriesMotor)) + /* if ((mvControlled->Mains) && + (mvControlled->EngineType==ElectricSeriesMotor)) { //tu dac w przyszlosci zaleznosc od wlaczenia przetwornicy if (mvControlled->ConverterFlag) //NBMX -obsluga przetwornicy @@ -4543,7 +4905,8 @@ bool TTrain::Update() ggSecurityResetButton.Update(); ggReleaserButton.Update(); ggAntiSlipButton.Update(); - ggFuseButton.Update(); + ggSandButton.Update(); + ggFuseButton.Update(); ggConverterFuseButton.Update(); ggStLinOffButton.Update(); ggRadioButton.Update(); @@ -4585,10 +4948,13 @@ bool TTrain::Update() ggMainOnButton.UpdateValue(0); ggSecurityResetButton.UpdateValue(0); ggReleaserButton.UpdateValue(0); - ggAntiSlipButton.UpdateValue(0); + ggSandButton.UpdateValue(0); + ggAntiSlipButton.UpdateValue(0); ggDepartureSignalButton.UpdateValue(0); ggFuseButton.UpdateValue(0); ggConverterFuseButton.UpdateValue(0); + + pyScreens.update(); } // wyprowadzenie sygnałów dla haslera na PoKeys (zaznaczanie na taśmie) btHaslerBrakes.Turn(DynamicObject->MoverParameters->BrakePress > 0.4); // ciśnienie w cylindrach @@ -4618,8 +4984,10 @@ bool TTrain::CabChange(int iDirection) ->CabActivisation(); // załączenie rozrządu (wirtualne kabiny) return true; // udało się zmienić kabinę } - DynamicObject->MoverParameters->CabActivisation(); // aktywizacja poprzedniej, bo jeszcze - // nie wiadomo, czy jakiś pojazd jest + DynamicObject->MoverParameters->CabActivisation(); // aktywizacja + // poprzedniej, bo + // jeszcze nie wiadomo, + // czy jakiś pojazd jest } return false; // ewentualna zmiana pojazdu } @@ -4705,7 +5073,8 @@ bool TTrain::LoadMMediaFile(AnsiString asFileName) } else //--------------- - // hunter-111211: wydzielenie wejscia na bezoporowa i na drugi uklad do pliku + // hunter-111211: wydzielenie wejscia na bezoporowa i na drugi uklad + // do pliku if (str == AnsiString("wejscie_na_bezoporow:")) { str = Parser->GetNextSymbol().LowerCase(); @@ -4879,7 +5248,7 @@ bool TTrain::LoadMMediaFile(AnsiString asFileName) str = Parser->GetNextSymbol().LowerCase(); dsbDoorClose = TSoundsManager::GetFromName(str.c_str(), true); } - else if (str == AnsiString("dooropen:")) // wotwarcie drzwi: + else if (str == AnsiString("dooropen:")) // otwarcie drzwi: { str = Parser->GetNextSymbol().LowerCase(); dsbDoorOpen = TSoundsManager::GetFromName(str.c_str(), true); @@ -4888,20 +5257,24 @@ bool TTrain::LoadMMediaFile(AnsiString asFileName) } else return false; // nie znalazl sekcji internal - delete Parser; // Ra: jak się coś newuje, to trzeba zdeletować, inaczej syf się robi + delete Parser; // Ra: jak się coś newuje, to trzeba zdeletować, inaczej syf + // się robi if (!InitializeCab(mvOccupied->ActiveCab, asFileName)) // zle zainicjowana kabina return false; else { if (DynamicObject->Controller == Humandriver) - DynamicObject->bDisplayCab = true; // McZapkie-030303: mozliwosc wyswietlania kabiny, w - // przyszlosci dac opcje w mmd + DynamicObject->bDisplayCab = true; // McZapkie-030303: mozliwosc + // wyswietlania kabiny, w przyszlosci + // dac opcje w mmd return true; } } bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) { + pyScreens.reset(this); + pyScreens.setLookupPath(DynamicObject->asBaseDir); bool parse = false; double dSDist; TFileStream *fs; @@ -4921,6 +5294,7 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) str = ""; int cabindex = 0; TGauge *gg; // roboczy wsaźnik na obiekt animujący gałkę + TButton *bt; // roboczy wsaźnik na obiekt animujący lampkę DynamicObject->mdKabina = NULL; // likwidacja wskaźnika na dotychczasową kabinę switch (NewCabNo) { // ustalenie numeru kabiny do wczytania @@ -4948,8 +5322,8 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) { Cabine[cabindex].Load(Parser); str = Parser->GetNextSymbol().LowerCase(); - if (AnsiCompareStr(AnsiString("driver") + cabindex + AnsiString("pos:"), str) == - 0) // pozycja poczatkowa maszynisty + if (AnsiCompareStr(AnsiString("driver") + cabindex + AnsiString("pos:"), + str) == 0) // pozycja poczatkowa maszynisty { pMechOffset.x = Parser->GetNextSymbol().ToDouble(); pMechOffset.y = Parser->GetNextSymbol().ToDouble(); @@ -4960,8 +5334,8 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) } // ABu: pozycja siedzaca mechanika str = Parser->GetNextSymbol().LowerCase(); - if (AnsiCompareStr(AnsiString("driver") + cabindex + AnsiString("sitpos:"), str) == - 0) // ABu 180404 pozycja siedzaca maszynisty + if (AnsiCompareStr(AnsiString("driver") + cabindex + AnsiString("sitpos:"), + str) == 0) // ABu 180404 pozycja siedzaca maszynisty { pMechSittingPosition.x = Parser->GetNextSymbol().ToDouble(); pMechSittingPosition.y = Parser->GetNextSymbol().ToDouble(); @@ -4977,12 +5351,12 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) else parse = true; // inicjacja kabiny - // Ra 2014-08: zmieniamy zasady - zamiast przypisywać submodel do istniejących obiektów - // animujących - // będziemy teraz uaktywniać obiekty animujące z tablicy i podawać im submodel oraz - // wskaźnik na parametr - if (AnsiCompareStr(AnsiString("cab") + cabindex + AnsiString("model:"), str) == - 0) // model kabiny + // Ra 2014-08: zmieniamy zasady - zamiast przypisywać submodel do + // istniejących obiektów animujących + // będziemy teraz uaktywniać obiekty animujące z tablicy i podawać im + // submodel oraz wskaźnik na parametr + if (AnsiCompareStr(AnsiString("cab") + cabindex + AnsiString("model:"), + str) == 0) // model kabiny { str = Parser->GetNextSymbol().LowerCase(); if (str != AnsiString("none")) @@ -4997,15 +5371,15 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) // if (DynamicObject->mdKabina!=k) if (k) DynamicObject->mdKabina = k; // nowa kabina - //(mdKabina) może zostać to samo po przejściu do innego członu bez zmiany - // kabiny, przy powrocie musi być wiązanie ponowne + //(mdKabina) może zostać to samo po przejściu do innego członu bez + // zmiany kabiny, przy powrocie musi być wiązanie ponowne // else // break; //wyjście z pętli, bo model zostaje bez zmian } else if (cabindex == 1) // model tylko, gdy nie ma kabiny 1 DynamicObject->mdKabina = - DynamicObject - ->mdModel; // McZapkie-170103: szukaj elementy kabiny w glownym modelu + DynamicObject->mdModel; // McZapkie-170103: szukaj elementy kabiny + // w glownym modelu ActiveUniversal4 = false; ggMainCtrl.Clear(); ggMainCtrlAct.Clear(); @@ -5022,7 +5396,8 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) ggMainOnButton.Clear(); ggSecurityResetButton.Clear(); ggReleaserButton.Clear(); - ggAntiSlipButton.Clear(); + ggSandButton.Clear(); + ggAntiSlipButton.Clear(); ggHornButton.Clear(); ggNextCurrentButton.Clear(); ggUniversal1Button.Clear(); @@ -5063,6 +5438,8 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) // ggEngageRatio.Clear(); ggMainGearStatus.Clear(); ggIgnitionKey.Clear(); + // Jeśli ustawiamy nową wartość dla PoKeys wolna jest 15 + // Numer 14 jest używany dla buczka SHP w innym miejscu btLampkaPoslizg.Clear(6); btLampkaStyczn.Clear(5); btLampkaNadmPrzetw.Clear( @@ -5120,7 +5497,8 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) ggUpperLightButton.Clear(); ggLeftEndLightButton.Clear(); ggRightEndLightButton.Clear(); - // hunter-230112 + ggLightsButton.Clear(); + // hunter-230112 ggRearLeftLightButton.Clear(); ggRearRightLightButton.Clear(); ggRearUpperLightButton.Clear(); @@ -5163,27 +5541,28 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) else if (str == AnsiString("maxcurrent_sw:")) // przelacznik rozruchu ggMaxCurrentCtrl.Load(Parser, DynamicObject->mdKabina); // SEKCJA przyciskow sprezynujacych - else if (str == - AnsiString( - "main_off_bt:")) // przycisk wylaczajacy (w EU07 wyl szybki czerwony) + else if (str == AnsiString("main_off_bt:")) // przycisk wylaczajacy (w + // EU07 wyl szybki czerwony) ggMainOffButton.Load(Parser, DynamicObject->mdKabina); - else if (str == - AnsiString("main_on_bt:")) // przycisk wlaczajacy (w EU07 wyl szybki zielony) + else if (str == AnsiString("main_on_bt:")) // przycisk wlaczajacy (w EU07 + // wyl szybki zielony) ggMainOnButton.Load(Parser, DynamicObject->mdKabina); else if (str == AnsiString("security_reset_bt:")) // przycisk zbijajacy SHP/czuwak ggSecurityResetButton.Load(Parser, DynamicObject->mdKabina); else if (str == AnsiString("releaser_bt:")) // przycisk odluzniacza ggReleaserButton.Load(Parser, DynamicObject->mdKabina); - else if (str == AnsiString("releaser_bt:")) // przycisk odluzniacza - ggReleaserButton.Load(Parser, DynamicObject->mdKabina); + else if (str == AnsiString("sand_bt:")) // przycisk piasecznicy + ggSandButton.Load(Parser, DynamicObject->mdKabina); else if (str == AnsiString("antislip_bt:")) // przycisk antyposlizgowy ggAntiSlipButton.Load(Parser, DynamicObject->mdKabina); else if (str == AnsiString("horn_bt:")) // dzwignia syreny ggHornButton.Load(Parser, DynamicObject->mdKabina); else if (str == AnsiString("fuse_bt:")) // bezp. nadmiarowy ggFuseButton.Load(Parser, DynamicObject->mdKabina); - else if (str == AnsiString("converterfuse_bt:")) // hunter-261211: odblokowanie - // przekaznika nadm. przetw. i ogrz. + else if (str == AnsiString("converterfuse_bt:")) // hunter-261211: + // odblokowanie + // przekaznika nadm. + // przetw. i ogrz. ggConverterFuseButton.Load(Parser, DynamicObject->mdKabina); else if (str == AnsiString("stlinoff_bt:")) // st. liniowe ggStLinOffButton.Load(Parser, DynamicObject->mdKabina); @@ -5203,7 +5582,9 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) ggLeftEndLightButton.Load(Parser, DynamicObject->mdKabina); else if (str == AnsiString("rightend_sw:")) // swiatlo ggRightEndLightButton.Load(Parser, DynamicObject->mdKabina); - //--------------------- + else if (str == AnsiString("lights_sw:")) // swiatla wszystkie + ggLightsButton.Load(Parser, DynamicObject->mdKabina); + //--------------------- // hunter-230112: przelaczniki swiatel tylnich else if (str == AnsiString("rearupperlight_sw:")) // swiatlo ggRearUpperLightButton.Load(Parser, DynamicObject->mdKabina); @@ -5240,7 +5621,7 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) ggSignallingButton.Load(Parser, DynamicObject->mdKabina); else if (str == AnsiString("door_signalling_sw:")) // Sygnalizacja blokady drzwi ggDoorSignallingButton.Load(Parser, DynamicObject->mdKabina); - else if (str == AnsiString("nextcurrent_sw:")) // grzanie skladu + else if (str == AnsiString("nextcurrent_sw:")) // prąd drugiego członu ggNextCurrentButton.Load(Parser, DynamicObject->mdKabina); else if (str == AnsiString("cablight_sw:")) // hunter-091012: swiatlo w kabinie ggCabLightButton.Load(Parser, DynamicObject->mdKabina); @@ -5259,13 +5640,17 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) ggUniversal4Button.Load(Parser, DynamicObject->mdKabina, DynamicObject->mdModel); // SEKCJA WSKAZNIKOW else if ((str == AnsiString("tachometer:")) || (str == AnsiString("tachometerb:"))) - { // predkosciomierz wskazówkowy z szarpaniem + { // predkosciomierz + // wskazówkowy z + // szarpaniem gg = Cabine[cabindex].Gauge(-1); // pierwsza wolna gałka gg->Load(Parser, DynamicObject->mdKabina); gg->AssignFloat(&fTachoVelocityJump); } else if (str == AnsiString("tachometern:")) - { // predkosciomierz wskazówkowy bez szarpania + { // predkosciomierz + // wskazówkowy bez + // szarpania gg = Cabine[cabindex].Gauge(-1); // pierwsza wolna gałka gg->Load(Parser, DynamicObject->mdKabina); gg->AssignFloat(&fTachoVelocity); @@ -5300,8 +5685,27 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) gg->Load(Parser, DynamicObject->mdKabina); gg->AssignFloat(fHCurrent); } - else if ((str == AnsiString("brakepress:")) || (str == AnsiString("brakepressb:"))) - { // manometr cylindrow hamulcowych //Ra 2014-08: przeniesione do TCab + else if (str == AnsiString("eimscreen:")) + { // amperomierz calkowitego pradu + int i = Parser->GetNextSymbol().ToInt(); + int j = Parser->GetNextSymbol().ToInt(); + gg = Cabine[cabindex].Gauge(-1); // pierwsza wolna gałka + gg->Load(Parser, DynamicObject->mdKabina); + gg->AssignFloat(&fEIMParams[i][j]); + } + else if (str == AnsiString("brakes:")) + { // amperomierz calkowitego pradu + int i = Parser->GetNextSymbol().ToInt(); + int j = Parser->GetNextSymbol().ToInt(); + gg = Cabine[cabindex].Gauge(-1); // pierwsza wolna gałka + gg->Load(Parser, DynamicObject->mdKabina); + gg->AssignFloat(&fPress[i - 1][j]); + } + else if ((str == AnsiString("brakepress:")) || (str == AnsiString("brakepressb:"))) + { // manometr cylindrow + // hamulcowych //Ra + // 2014-08: przeniesione + // do TCab gg = Cabine[cabindex].Gauge(-1); // pierwsza wolna gałka gg->Load(Parser, DynamicObject->mdKabina, NULL, 0.1); gg->AssignDouble(&mvOccupied->BrakePress); @@ -5312,9 +5716,9 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) gg->Load(Parser, DynamicObject->mdKabina, NULL, 0.1); gg->AssignDouble(&mvOccupied->PipePress); } - else if (str == - AnsiString( - "limpipepress:")) // manometr zbiornika sterujacego zaworu maszynisty + else if (str == AnsiString("limpipepress:")) // manometr zbiornika + // sterujacego zaworu + // maszynisty ggZbS.Load(Parser, DynamicObject->mdKabina, NULL, 0.1); else if (str == AnsiString("cntrlpress:")) { // manometr zbiornika kontrolnego/rorządu @@ -5323,7 +5727,9 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) gg->AssignDouble(&mvControlled->PantPress); } else if ((str == AnsiString("compressor:")) || (str == AnsiString("compressorb:"))) - { // manometr sprezarki/zbiornika glownego + { // manometr + // sprezarki/zbiornika + // glownego gg = Cabine[cabindex].Gauge(-1); // pierwsza wolna gałka gg->Load(Parser, DynamicObject->mdKabina, NULL, 0.1); gg->AssignDouble(&mvOccupied->Compressor); @@ -5385,8 +5791,8 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) gg->Load(Parser, DynamicObject->mdKabina); gg->AssignDouble(&mvControlled->dizel_engage); } // ggEngageRatio.Load(Parser,DynamicObject->mdKabina); - else if (str == AnsiString("maingearstatus:")) // np. ciśnienie sterownika skrzyni - // biegów + else if (str == AnsiString("maingearstatus:")) // np. ciśnienie sterownika + // skrzyni biegów ggMainGearStatus.Load(Parser, DynamicObject->mdKabina); else if (str == AnsiString("ignitionkey:")) // ggIgnitionKey.Load(Parser, DynamicObject->mdKabina); @@ -5508,6 +5914,15 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) btLampkaBackward.Load(Parser, DynamicObject->mdKabina); else if (str == AnsiString("i-cablight:")) // hunter-171012 btCabLight.Load(Parser, DynamicObject->mdKabina); + else if (str == AnsiString("i-doors:")) + { + int i = Parser->GetNextSymbol().ToInt() - 1; + bt = Cabine[cabindex].Button(-1); // pierwsza wolna lampka + bt->Load(Parser, DynamicObject->mdKabina); + bt->AssignBool(bDoors[0] + 3 * i); + } + else if (str == AnsiString("pyscreen:")) + pyScreens.init(Parser, DynamicObject->mdKabina, DynamicObject->GetName(), NewCabNo); // btLampkaUnknown.Init("unknown",mdKabina,false); } } @@ -5518,17 +5933,19 @@ bool TTrain::InitializeCab(int NewCabNo, AnsiString asFileName) } // ABu 050205: tego wczesniej nie bylo: delete Parser; + pyScreens.start(); if (DynamicObject->mdKabina) { - DynamicObject->mdKabina - ->Init(); // obrócenie modelu oraz optymalizacja, również zapisanie binarnego + DynamicObject->mdKabina->Init(); // obrócenie modelu oraz optymalizacja, + // również zapisanie binarnego return true; } return AnsiCompareStr(str, AnsiString("none")); } void TTrain::MechStop() -{ // likwidacja ruchu kamery w kabinie (po powrocie przez [F4]) +{ // likwidacja ruchu kamery w kabinie (po powrocie + // przez [F4]) pMechPosition = vector3(0, 0, 0); pMechShake = vector3(0, 0, 0); vMechMovement = vector3(0, 0, 0); @@ -5552,15 +5969,19 @@ vector3 TTrain::MirrorPosition(bool lewe) }; void TTrain::DynamicSet(TDynamicObject *d) -{ // taka proteza: chcę podłączyć kabinę EN57 bezpośrednio z silnikowym, aby nie robić tego przez - // ukrotnienie +{ // taka proteza: chcę podłączyć + // kabinę EN57 bezpośrednio z + // silnikowym, aby nie robić tego + // przez ukrotnienie // drugi silnikowy i tak musi być ukrotniony, podobnie jak kolejna jednostka - // problem się robi ze światłami, które będą zapalane w silnikowym, ale muszą świecić się w + // problem się robi ze światłami, które będą zapalane w silnikowym, ale muszą + // świecić się w rozrządczych + // dla EZT światła czołowe będą "zapalane w silnikowym", ale widziane z // rozrządczych - // dla EZT światła czołowe będą "zapalane w silnikowym", ale widziane z rozrządczych // również wczytywanie MMD powinno dotyczyć aktualnego członu // problematyczna może być kwestia wybranej kabiny (w silnikowym...) - // jeśli silnikowy będzie zapięty odwrotnie (tzn. -1), to i tak powinno jeździć dobrze + // jeśli silnikowy będzie zapięty odwrotnie (tzn. -1), to i tak powinno + // jeździć dobrze // również hamowanie wykonuje się zaworem w członie, a nie w silnikowym... DynamicObject = d; // jedyne miejsce zmiany mvOccupied = mvControlled = d ? DynamicObject->MoverParameters : NULL; // albo silnikowy w EZT @@ -5569,7 +5990,8 @@ void TTrain::DynamicSet(TDynamicObject *d) if (mvControlled->TrainType & dt_EZT) // na razie dotyczy to EZT if (DynamicObject->NextConnected ? mvControlled->Couplers[1].AllowedFlag & ctrain_depot : false) - { // gdy jest człon od sprzęgu 1, a sprzęg łączony warsztatowo (powiedzmy) + { // gdy jest człon od sprzęgu 1, a sprzęg łączony + // warsztatowo (powiedzmy) if ((mvControlled->Power < 1.0) && (mvControlled->Couplers[1].Connected->Power > 1.0)) // my nie mamy mocy, ale ten drugi ma mvControlled = @@ -5578,7 +6000,8 @@ void TTrain::DynamicSet(TDynamicObject *d) else if (DynamicObject->PrevConnected ? mvControlled->Couplers[0].AllowedFlag & ctrain_depot : false) - { // gdy jest człon od sprzęgu 0, a sprzęg łączony warsztatowo (powiedzmy) + { // gdy jest człon od sprzęgu 0, a sprzęg łączony + // warsztatowo (powiedzmy) if ((mvControlled->Power < 1.0) && (mvControlled->Couplers[0].Connected->Power > 1.0)) // my nie mamy mocy, ale ten drugi ma mvControlled = @@ -5589,7 +6012,8 @@ void TTrain::DynamicSet(TDynamicObject *d) if (mvOccupied->Couplers[1].Connected ? mvOccupied->Couplers[1].AllowedFlag & ctrain_controll : false) - { // gdy jest człon od sprzęgu 1, a sprzęg łączony warsztatowo (powiedzmy) + { // gdy jest człon od sprzęgu 1, a sprzęg łączony + // warsztatowo (powiedzmy) if (mvOccupied->Couplers[1].Connected->Power > 1.0) // ten drugi ma moc mvSecond = (TMoverParameters *)mvOccupied->Couplers[1].Connected; // wskaźnik na drugiego @@ -5597,7 +6021,8 @@ void TTrain::DynamicSet(TDynamicObject *d) else if (mvOccupied->Couplers[0].Connected ? mvOccupied->Couplers[0].AllowedFlag & ctrain_controll : false) - { // gdy jest człon od sprzęgu 0, a sprzęg łączony warsztatowo (powiedzmy) + { // gdy jest człon od sprzęgu 0, a sprzęg łączony + // warsztatowo (powiedzmy) if (mvOccupied->Couplers[0].Connected->Power > 1.0) // ale ten drugi ma moc mvSecond = (TMoverParameters *)mvOccupied->Couplers[0].Connected; // wskaźnik na drugiego @@ -5664,3 +6089,34 @@ void TTrain::Silence() if (dsbBufferClamp) dsbBufferClamp->Stop(); }; + +void TTrain::SetLights() +{ + TDynamicObject *p = DynamicObject->GetFirstDynamic(mvOccupied->ActiveCab < 0 ? 1 : 0, 4); + bool kier = (DynamicObject->DirectionGet() * mvOccupied->ActiveCab > 0); + int xs = (kier ? 0 : 1); + if (kier ? p->NextC(1) : p->PrevC(1)) // jesli jest nastepny, to tylko przod + { + p->RaLightsSet(mvOccupied->Lights[xs][mvOccupied->LightsPos - 1] * (1 - xs), + mvOccupied->Lights[1 - xs][mvOccupied->LightsPos - 1] * xs); + p = (kier ? p->NextC(4) : p->PrevC(4)); + while (p) + { + if (kier ? p->NextC(1) : p->PrevC(1)) + { + p->RaLightsSet(0, 0); + } + else + { + p->RaLightsSet(mvOccupied->Lights[xs][mvOccupied->LightsPos - 1] * xs, + mvOccupied->Lights[1 - xs][mvOccupied->LightsPos - 1] * (1 - xs)); + } + p = (kier ? p->NextC(4) : p->PrevC(4)); + } + } + else // calosc + { + p->RaLightsSet(mvOccupied->Lights[xs][mvOccupied->LightsPos - 1], + mvOccupied->Lights[1 - xs][mvOccupied->LightsPos - 1]); + } +}; diff --git a/Train.h b/Train.h index e1e442a69..c69cae69d 100644 --- a/Train.h +++ b/Train.h @@ -23,6 +23,7 @@ obtain one at #include "AdvSound.h" #include "RealSound.h" #include "FadeSound.h" +#include "PyInt.h" // typedef enum {st_Off, st_Starting, st_On, st_ShuttingDown} T4State; @@ -61,8 +62,8 @@ class TCab TButton *btList; // Ra 2014-08: lista animacji dwustanowych (lampek) w kabinie int iButtonsMax, iButtons; // ile miejsca w tablicy i ile jest w użyciu public: - TGauge *__fastcall Gauge(int n = -1); // pobranie adresu obiektu - TButton *__fastcall Button(int n = -1); // pobranie adresu obiektu + TGauge * Gauge(int n = -1); // pobranie adresu obiektu + TButton * Button(int n = -1); // pobranie adresu obiektu void Update(); }; @@ -94,9 +95,11 @@ class TTrain void UpdateMechPosition(double dt); bool Update(); void MechStop(); - // virtual bool RenderAlpha(); + void SetLights(); + // virtual bool RenderAlpha(); // McZapkie-310302: ladowanie parametrow z pliku bool LoadMMediaFile(AnsiString asFileName); + PyObject *GetTrainState(); private: //żeby go nic z zewnątrz nie przestawiało TDynamicObject *DynamicObject; // przestawia zmiana pojazdu [F5] @@ -148,10 +151,11 @@ class TTrain TGauge ggMainButton; // EZT TGauge ggSecurityResetButton; TGauge ggReleaserButton; + TGauge ggSandButton; //guzik piasecznicy TGauge ggAntiSlipButton; TGauge ggFuseButton; - TGauge ggConverterFuseButton; // hunter-261211: przycisk odblokowania nadmiarowego przetwornic i - // ogrzewania + TGauge ggConverterFuseButton; // hunter-261211: przycisk odblokowania + // nadmiarowego przetwornic i ogrzewania TGauge ggStLinOffButton; TGauge ggRadioButton; TGauge ggUpperLightButton; @@ -159,6 +163,7 @@ class TTrain TGauge ggRightLightButton; TGauge ggLeftEndLightButton; TGauge ggRightEndLightButton; + TGauge ggLightsButton; //przelacznik reflektorow (wszystkich) // hunter-230112: przelacznik swiatel tylnich TGauge ggRearUpperLightButton; @@ -183,7 +188,8 @@ class TTrain TGauge ggUniversal4Button; TGauge ggCabLightButton; // hunter-091012: przelacznik oswietlania kabiny - TGauge ggCabLightDimButton; // hunter-091012: przelacznik przyciemnienia oswietlenia kabiny + TGauge ggCabLightDimButton; // hunter-091012: przelacznik przyciemnienia + // oswietlenia kabiny // NBMX wrzesien 2003 - obsluga drzwi TGauge ggDoorLeftButton; @@ -231,7 +237,8 @@ class TTrain TButton btLampkaOpory; TButton btLampkaWysRozr; TButton btLampkaUniversal3; - int LampkaUniversal3_typ; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw. + int LampkaUniversal3_typ; // ABu 030405 - swiecenie uzaleznione od: 0-nic, + // 1-obw.gl, 2-przetw. bool LampkaUniversal3_st; TButton btLampkaWentZaluzje; // ET22 TButton btLampkaOgrzewanieSkladu; @@ -332,7 +339,8 @@ class TTrain // TFadeSound sConverter; //przetwornica // TFadeSound sSmallCompressor; //przetwornica - int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne) + int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: + // przyciemnione, 2: pelne) bool bCabLight; // hunter-091012: czy swiatlo jest zapalone? bool bCabLightDim; // hunter-091012: czy przyciemnienie kabiny jest zapalone? @@ -354,6 +362,7 @@ class TTrain float fConverterTimer; // hunter-261211: dla przekaznika float fMainRelayTimer; // hunter-141211: zalaczanie WSa z opoznieniem float fCzuwakTestTimer; // hunter-091012: do testu czuwaka + float fLightsTimer; // yB 150617: timer do swiatel int CAflag; // hunter-131211: dla osobnego zbijania CA i SHP @@ -370,24 +379,42 @@ class TTrain float fTachoVelocityJump; // ze skakaniem float fTachoTimer; float fTachoCount; - float fHVoltage; // napięcie dla dynamicznych gałek - float fHCurrent[4]; // prądy: suma i amperomierze 1,2,3 - float fEngine[4]; // obroty te?trzeba pobra? - // McZapkie: do syczenia + float fHVoltage; // napi?cie dla dynamicznych ga?ek + float fHCurrent[4]; // pr?dy: suma i amperomierze 1,2,3 + float fEngine[4]; // obroty te? trzeba pobra? + int iCarNo, iPowerNo, iUnitNo; //liczba pojazdow, czlonow napednych i jednostek spiętych ze sobą + bool bDoors[20][3]; // drzwi dla wszystkich czlonow + int iUnits[20]; // numer jednostki + int iDoorNo[20]; // liczba drzwi + char cCode[20]; //kod pojazdu + AnsiString asCarName[20]; //nazwa czlonu + bool bMains[8]; //WSy + float fCntVol[8]; //napiecie NN + bool bPants[8][2]; //podniesienie pantografow + bool bFuse[8]; //nadmiarowe + bool bBatt[8]; //baterie + bool bConv[8]; //przetwornice + bool bComp[8][2]; //sprezarki + bool bHeat[8]; //grzanie + // McZapkie: do syczenia float fPPress, fNPress; float fSPPress, fSNPress; - int iSekunda; // Ra: sekunda aktualizacji prędkości - int iRadioChannel; // numer aktualnego kanału radiowego + int iSekunda; // Ra: sekunda aktualizacji pr?dko?ci + int iRadioChannel; // numer aktualnego kana?u radiowego + TPythonScreens pyScreens; + public: + float fPress[20][3]; // cisnienia dla wszystkich czlonow + float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych int RadioChannel() { return iRadioChannel; }; - inline TDynamicObject *__fastcall Dynamic() + inline TDynamicObject * Dynamic() { return DynamicObject; }; - inline TMoverParameters *__fastcall Controlled() + inline TMoverParameters * Controlled() { return mvControlled; }; diff --git a/TrkFoll.cpp b/TrkFoll.cpp index 019c01d47..ee2f3bf5b 100644 --- a/TrkFoll.cpp +++ b/TrkFoll.cpp @@ -53,7 +53,7 @@ bool TTrackFollower::Init(TTrack *pTrack, TDynamicObject *NewOwner, double fDir) return true; } -TTrack *__fastcall TTrackFollower::SetCurrentTrack(TTrack *pTrack, int end) +TTrack * TTrackFollower::SetCurrentTrack(TTrack *pTrack, int end) { // przejechanie na inny odcinkek toru, z ewentualnym rozpruciem if (pTrack) switch (pTrack->eType) diff --git a/TrkFoll.h b/TrkFoll.h index 5c8c126ac..4366f73ab 100644 --- a/TrkFoll.h +++ b/TrkFoll.h @@ -33,9 +33,9 @@ class TTrackFollower vector3 vAngles; // x:przechyłka, y:pochylenie, z:kierunek w planie (w radianach) TTrackFollower(); ~TTrackFollower(); - TTrack *__fastcall SetCurrentTrack(TTrack *pTrack, int end); + TTrack * SetCurrentTrack(TTrack *pTrack, int end); bool Move(double fDistance, bool bPrimary); - inline TTrack *__fastcall GetTrack() + inline TTrack * GetTrack() { return pCurrentTrack; }; diff --git a/World.cpp b/World.cpp index 41ec5c476..999829d3c 100644 --- a/World.cpp +++ b/World.cpp @@ -274,9 +274,9 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) glLoadIdentity(); // WriteLog("glClearColor (FogColor[0], FogColor[1], FogColor[2], 0.0); "); // glClearColor (1.0, 0.0, 0.0, 0.0); // Background Color - // glClearColor (FogColor[0], FogColor[1], FogColor[2], 0.0); // Background - // Color - glClearColor(0.2, 0.4, 0.33, 1.0); // Background Color + // glClearColor (FogColor[0], FogColor[1], FogColor[2], 0.0); + // Background // Color + glClearColor(Global::Background[0], Global::Background[1], Global::Background[2], 1.0); // Background Color WriteLog("glFogfv(GL_FOG_COLOR, FogColor);"); glFogfv(GL_FOG_COLOR, FogColor); // Set Fog Color @@ -664,7 +664,7 @@ bool TWorld::Init(HWND NhWnd, HDC hDC) } // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //{Texture blends with object // background} - light = TTexturesManager::GetTextureID(szTexturePath, szSceneryPath, "smuga.tga"); + light = TTexturesManager::GetTextureID(szTexturePath, szSceneryPath, "smuga2.tga"); // Camera.Reset(); ResetTimers(); WriteLog("Load time: " + FloatToStrF((86400.0 * ((double)Now() - time)), ffFixed, 7, 1) + @@ -846,8 +846,9 @@ void TWorld::OnKeyDown(int cKey) } else if (cKey == 3) //[Ctrl]+[Break] { // hamowanie wszystkich pojazdów w okolicy - Ground.RadioStop(Camera.Pos); - } + if (Controlled->MoverParameters->Radio) + Ground.RadioStop(Camera.Pos); + } else if (!Global::iPause) //||(cKey==VK_F4)) //podczas pauzy sterownaie nie działa, F4 tak if (Train) if (Controlled) @@ -1496,44 +1497,52 @@ bool TWorld::Update() // 3. jeśli smuga właczona, wyrenderować pojazd użytkownia po dodaniu smugi do sceny if (Train->Controlled()->Battery) { // trochę na skróty z tą baterią - glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE); - // glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_DST_COLOR); + glBlendFunc(GL_DST_COLOR, GL_ONE); + // glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE); + // glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE); + // glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_DST_COLOR); // glBlendFunc(GL_SRC_ALPHA_SATURATE,GL_ONE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); + glDepthFunc(GL_GEQUAL); + glAlphaFunc(GL_GREATER, 0.004); + // glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); glDisable(GL_FOG); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - glBindTexture(GL_TEXTURE_2D, light); // Select our texture + glColor4f(0.15f, 0.15f, 0.15f, 0.25f); + glBindTexture(GL_TEXTURE_2D, light); // Select our texture glBegin(GL_QUADS); float fSmudge = Train->Dynamic()->MoverParameters->DimHalf.y + 7; // gdzie zaczynać smugę if (Train->Controlled()->iLights[0] & 21) { // wystarczy jeden zapalony z przodu - glTexCoord2f(0, 0); - glVertex3f(15.0, 0.0, +fSmudge); // rysowanie względem położenia modelu - glTexCoord2f(1, 0); - glVertex3f(-15.0, 0.0, +fSmudge); - glTexCoord2f(1, 1); - glVertex3f(-15.0, 2.5, 250.0); - glTexCoord2f(0, 1); - glVertex3f(15.0, 2.5, 250.0); - } + for (int i = 15; i <= 35; i++) + { + float z = i * i * i * 0.01f;//25/4; + float C = (36 - i*0.5)*0.05*0.1; + glColor4f(C, C, C, 0.25f); + glTexCoord2f(0, 0); glVertex3f(-10 / 2 - 2 * i / 4, 6.0 + 0.3*z, 13 + 1.7*z / 3); + glTexCoord2f(1, 0); glVertex3f(10 / 2 + 2 * i / 4, 6.0 + 0.3*z, 13 + 1.7*z / 3); + glTexCoord2f(1, 1); glVertex3f(10 / 2 + 2 * i / 4, -5.0 - 0.5*z, 13 + 1.7*z / 3); + glTexCoord2f(0, 1); glVertex3f(-10 / 2 - 2 * i / 4, -5.0 - 0.5*z, 13 + 1.7*z / 3); + } + } if (Train->Controlled()->iLights[1] & 21) { // wystarczy jeden zapalony z tyłu - glTexCoord2f(0, 0); - glVertex3f(-15.0, 0.0, -fSmudge); - glTexCoord2f(1, 0); - glVertex3f(15.0, 0.0, -fSmudge); - glTexCoord2f(1, 1); - glVertex3f(15.0, 2.5, -250.0); - glTexCoord2f(0, 1); - glVertex3f(-15.0, 2.5, -250.0); - } + for (int i = 15; i <= 35; i++) + { + float z = i * i * i * 0.01f;//25/4; + glTexCoord2f(0, 0); glVertex3f(10 / 2 + 3 * i / 4, 6.0 + 0.3*z, -13 - 1.7*z / 3); + glTexCoord2f(1, 0); glVertex3f(-10 / 2 - 3 * i / 4, 6.0 + 0.3*z, -13 - 1.7*z / 3); + glTexCoord2f(1, 1); glVertex3f(-10 / 2 - 3 * i / 4, -5.0 - 0.5*z, -13 - 1.7*z / 3); + glTexCoord2f(0, 1); glVertex3f(10 / 2 + 3 * i / 4, -5.0 - 0.5*z, -13 - 1.7*z / 3); + } + } glEnd(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_DEPTH_TEST); - // glEnable(GL_LIGHTING); //i tak się włączy potem + // glEnable(GL_DEPTH_TEST); + glAlphaFunc(GL_GREATER, 0.04); + glDepthFunc(GL_LEQUAL); + glEnable(GL_LIGHTING); //i tak się włączy potem glEnable(GL_FOG); } glEnable(GL_LIGHTING); // po renderowaniu smugi jest to wyłączone @@ -1739,7 +1748,9 @@ bool TWorld::Update() Train->Dynamic()->Controller = AIdriver; // Train->Dynamic()->MoverParameters->SecuritySystem.Status=0; //rozwala CA w EZT Train->Dynamic()->MoverParameters->ActiveCab = 0; - Train->Dynamic()->MoverParameters->BrakeLevelSet(-2); + Train->Dynamic()->MoverParameters->BrakeLevelSet( + Train->Dynamic()->MoverParameters->Handle->GetPos( + bh_NP)); //rozwala sterowanie hamulcem GF 04-2016 Train->Dynamic()->MechInside = false; } // int CabNr; @@ -1900,9 +1911,23 @@ bool TWorld::Update() // u:")+FloatToStrF(tmp->MoverParameters->u,ffFixed,3,3); // OutText2+=AnsiString(", // N:")+FloatToStrF(tmp->MoverParameters->Ntotal,ffFixed,4,0); - OutText2 += - AnsiString(", Ft:") + FloatToStrF(tmp->MoverParameters->Ft, ffFixed, 4, 0); - // OutText3= AnsiString("BP: + OutText2 += AnsiString(", MED:") + + FloatToStrF(tmp->MoverParameters->LocalBrakePosA, ffFixed, 6, 2); + OutText2 += AnsiString("+") + + FloatToStrF(tmp->MoverParameters->AnPos, ffFixed, 6, 2); + OutText2 += AnsiString(", Ft:") + + FloatToStrF(tmp->MoverParameters->Ft * 0.001f, ffFixed, 4, 0); + OutText2 += AnsiString(", HV0:") + + FloatToStrF(tmp->MoverParameters->HVCouplers[0][1], ffFixed, 4, 0); + OutText2 += AnsiString("@") + + FloatToStrF(tmp->MoverParameters->HVCouplers[0][0], ffFixed, 4, 0); + OutText2 += AnsiString("+HV1:") + + FloatToStrF(tmp->MoverParameters->HVCouplers[1][1], ffFixed, 4, 0); + OutText2 += AnsiString("@") + + FloatToStrF(tmp->MoverParameters->HVCouplers[1][0], ffFixed, 4, 0); + OutText2 += AnsiString(" TC:") + + FloatToStrF(tmp->MoverParameters->TotalCurrent, ffFixed, 4, 0); + // OutText3= AnsiString("BP: // ")+FloatToStrF(tmp->MoverParameters->BrakePress,ffFixed,5,2)+AnsiString(", // "); // OutText3+= AnsiString("PP: @@ -2010,12 +2035,15 @@ bool TWorld::Update() if (tmp->Mechanik->DrivigFlags() & j) // jak bit ustawiony flags[i + 1] ^= 0x20; // to zmiana na wielką literę OutText4 = flags; - OutText4 += - AnsiString("Driver: Vd=") + - FloatToStrF(tmp->Mechanik->VelDesired, ffFixed, 4, 0) + AnsiString(" ad=") + - FloatToStrF(tmp->Mechanik->AccDesired, ffFixed, 5, 2) + AnsiString(" Pd=") + - FloatToStrF(tmp->Mechanik->ActualProximityDist, ffFixed, 4, 0) + - AnsiString(" Vn=") + FloatToStrF(tmp->Mechanik->VelNext, ffFixed, 4, 0); + OutText4 += + AnsiString("Driver: Vd=") + + FloatToStrF(tmp->Mechanik->VelDesired, ffFixed, 4, 0) + AnsiString(" ad=") + + FloatToStrF(tmp->Mechanik->AccDesired, ffFixed, 5, 2) + AnsiString(" Pd=") + + FloatToStrF(tmp->Mechanik->ActualProximityDist, ffFixed, 4, 0) + + AnsiString(" Vn=") + FloatToStrF(tmp->Mechanik->VelNext, ffFixed, 4, 0) + + AnsiString(" VSm=") + FloatToStrF(tmp->Mechanik->VelSignalLast, ffFixed, 4, 0) + + AnsiString(" VLm=") + FloatToStrF(tmp->Mechanik->VelLimitLast, ffFixed, 4, 0) + + AnsiString(" VRd=") + FloatToStrF(tmp->Mechanik->VelRoad, ffFixed, 4, 0); if (tmp->Mechanik->VelNext == 0.0) if (tmp->Mechanik->eSignNext) { // jeśli ma zapamiętany event semafora @@ -2050,7 +2078,7 @@ bool TWorld::Update() { // ekran drugi, czyli tabelka skanowania AI if (tmp->Mechanik) //żeby była tabelka, musi być AI { // tabelka jest na użytek testujących scenerie, więc nie musi być "ładna" - glColor3f(0.0f, 1.0f, 0.0f); // a, damy zielony + glColor3f(1.0f, 1.0f, 1.0f); // a, damy zielony. GF: jednak biały // glTranslatef(0.0f,0.0f,-0.50f); glRasterPos2f(-0.25f, 0.20f); // OutText1="Scan distance: "+AnsiString(tmp->Mechanik->scanmax)+", back: @@ -2081,7 +2109,11 @@ bool TWorld::Update() FloatToStrF(tmp->Mechanik->VelDesired, ffFixed, 4, 0) + AnsiString(" ad=") + FloatToStrF(tmp->Mechanik->AccDesired, ffFixed, 5, 2) + AnsiString(" Pd=") + FloatToStrF(tmp->Mechanik->ActualProximityDist, ffFixed, 4, 0) + - AnsiString(" Vn=") + FloatToStrF(tmp->Mechanik->VelNext, ffFixed, 4, 0); + AnsiString(" Vn=") + FloatToStrF(tmp->Mechanik->VelNext, ffFixed, 4, 0) + + AnsiString("\n VSm=") + FloatToStrF(tmp->Mechanik->VelSignalLast, ffFixed, 4, 0) + + AnsiString(" VLm=") + FloatToStrF(tmp->Mechanik->VelLimitLast, ffFixed, 4, 0) + + AnsiString(" VRd=") + FloatToStrF(tmp->Mechanik->VelRoad, ffFixed, 4, 0) + + AnsiString(" VSig=") + FloatToStrF(tmp->Mechanik->VelSignal, ffFixed, 4, 0); if (tmp->Mechanik->VelNext == 0.0) if (tmp->Mechanik->eSignNext) { // jeśli ma zapamiętany event semafora @@ -2196,8 +2228,10 @@ bool TWorld::Update() FloatToStrF(Controlled->MoverParameters->dizel_engagedeltaomega, ffFixed, 6, 3); OutText2 = AnsiString("HamZ=") + FloatToStrF(Controlled->MoverParameters->fBrakeCtrlPos, ffFixed, 6, 1); - OutText2 += AnsiString("; HamP=") + AnsiString(Controlled->MoverParameters->LocalBrakePos); - // mvControlled->MainCtrlPos; + OutText2 += AnsiString("; HamP=") + AnsiString(mvControlled->LocalBrakePos); + OutText2 += AnsiString("/") + + FloatToStrF(Controlled->MoverParameters->LocalBrakePosA, ffFixed, 6, 2); + // mvControlled->MainCtrlPos; // if (mvControlled->MainCtrlPos<0) // OutText2+= AnsiString("; nastawnik 0"); // if (mvControlled->MainCtrlPos>iPozSzereg) @@ -2221,8 +2255,14 @@ bool TWorld::Update() FloatToStrF(Controlled->MoverParameters->RunningShape.R, ffFixed, 4, 1); OutText2 += AnsiString(" An=") + FloatToStrF(Controlled->MoverParameters->AccN, ffFixed, 4, 2); // przyspieszenie poprzeczne - OutText2 += AnsiString("; As=") + FloatToStrF(Controlled->MoverParameters->AccS, ffFixed, 4, - 2); // przyspieszenie wzdłużne + if (tprev != int(GlobalTime->mr)) + { + tprev = GlobalTime->mr; + Acc = (Controlled->MoverParameters->Vel - VelPrev) / 3.6; + VelPrev = Controlled->MoverParameters->Vel; + } + OutText2 += AnsiString("; As=") + FloatToStrF(Acc/*Controlled->MoverParameters->AccS*/, ffFixed, 4, + 2); // przyspieszenie wzdłużne // OutText2+=AnsiString("; P=")+FloatToStrF(mvControlled->EnginePower,ffFixed,6,1); OutText3 += AnsiString("cyl.ham. ") + FloatToStrF(Controlled->MoverParameters->BrakePress, ffFixed, 5, 2); @@ -2234,32 +2274,53 @@ bool TWorld::Update() OutText3 += AnsiString("; p.zas. ") + FloatToStrF(Controlled->MoverParameters->ScndPipePress, ffFixed, 6, 2); - if (Controlled->MoverParameters->EngineType == ElectricInductionMotor) - { - // glTranslatef(0.0f,0.0f,-0.50f); - glColor3f(1.0f, 1.0f, 1.0f); // a, damy białym - for (int i = 0; i <= 20; i++) - { - glRasterPos2f(-0.25f, 0.16f - 0.01f * i); - if (Controlled->MoverParameters->eimc[i] < 10) - OutText4 = FloatToStrF(Controlled->MoverParameters->eimc[i], ffFixed, 6, 3); - else - OutText4 = FloatToStrF(Controlled->MoverParameters->eimc[i], ffGeneral, 5, 3); - glPrint(OutText4.c_str()); - } - for (int i = 0; i <= 20; i++) - { - glRasterPos2f(-0.2f, 0.16f - 0.01f * i); - if (Controlled->MoverParameters->eimv[i] < 10) - OutText4 = FloatToStrF(Controlled->MoverParameters->eimv[i], ffFixed, 6, 3); - else - OutText4 = FloatToStrF(Controlled->MoverParameters->eimv[i], ffGeneral, 5, 3); - glPrint(OutText4.c_str()); - } - OutText4 = ""; - // glTranslatef(0.0f,0.0f,+0.50f); - glColor3f(1.0f, 0.0f, 0.0f); // a, damy czerwonym - } + if (Controlled->MoverParameters->EngineType == ElectricInductionMotor) + { + // glTranslatef(0.0f,0.0f,-0.50f); + glColor3f(1.0f, 1.0f, 1.0f); // a, damy białym + for (int i = 0; i <= 20; i++) + { + glRasterPos2f(-0.25f, 0.16f - 0.01f * i); + if (Controlled->MoverParameters->eimc[i] < 10) + OutText4 = FloatToStrF(Controlled->MoverParameters->eimc[i], ffFixed, 6, 3); + else + OutText4 = FloatToStrF(Controlled->MoverParameters->eimc[i], ffGeneral, 5, 3); + glPrint(OutText4.c_str()); + } + for (int i = 0; i <= 20; i++) + { + glRasterPos2f(-0.2f, 0.16f - 0.01f * i); + if (Controlled->MoverParameters->eimv[i] < 10) + OutText4 = FloatToStrF(Controlled->MoverParameters->eimv[i], ffFixed, 6, 3); + else + OutText4 = FloatToStrF(Controlled->MoverParameters->eimv[i], ffGeneral, 5, 3); + glPrint(OutText4.c_str()); + } + for (int i = 0; i <= 10; i++) + { + glRasterPos2f(-0.15f, 0.16f - 0.01f * i); + OutText4 = FloatToStrF(Train->fPress[i][0], ffFixed, 6, 3); + glPrint(OutText4.c_str()); + } + for (int i = 0; i <= 8; i++) + { + glRasterPos2f(-0.15f, 0.04f - 0.01f * i); + OutText4 = FloatToStrF(Controlled->MED[0][i], ffFixed, 6, 3); + glPrint(OutText4.c_str()); + } + for (int i = 0; i <= 8; i++) + { + for (int j = 0; j <= 9; j++) + { + glRasterPos2f(0.05f + 0.03f * i, 0.16f - 0.01f * j); + OutText4 = FloatToStrF(Train->fEIMParams[i][j], ffGeneral, 4, 2); + glPrint(OutText4.c_str()); + } + } + OutText4 = ""; + // glTranslatef(0.0f,0.0f,+0.50f); + glColor3f(1.0f, 0.0f, 0.0f); // a, damy czerwonym + } // ABu: testy sprzegow-> (potem przeniesc te zmienne z public do protected!) // OutText3+=AnsiString("; EnginePwr=")+FloatToStrF(mvControlled->EnginePower,ffFixed,1,5); @@ -2685,12 +2746,16 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz) switch (pRozkaz->iComm) { case 0: // odesłanie identyfikatora wersji - Ground.WyslijString(Global::asVersion, 0); // przedsatwienie się + CommLog(AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " version" + " rcvd"); + Ground.WyslijString(Global::asVersion, 0); // przedsatwienie się break; case 1: // odesłanie identyfikatora wersji - Ground.WyslijString(Global::szSceneryFile, 1); // nazwa scenerii + CommLog(AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " scenery" + " rcvd"); + Ground.WyslijString(Global::szSceneryFile, 1); // nazwa scenerii break; case 2: // event + CommLog(AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " " + + AnsiString(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])) + " rcvd"); if (Global::iMultiplayer) { // WriteLog("Komunikat: "+AnsiString(pRozkaz->Name1)); TEvent *e = Ground.FindEvent( @@ -2707,6 +2772,10 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz) { int i = int(pRozkaz->cString[8]); // długość pierwszego łańcucha (z przodu dwa floaty) + CommLog( + AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " " + + AnsiString(pRozkaz->cString + 11 + i, (unsigned)(pRozkaz->cString[10 + i])) + + " rcvd"); TGroundNode *t = Ground.DynamicFind( AnsiString(pRozkaz->cString + 11 + i, (unsigned)pRozkaz->cString[10 + i])); // nazwa pojazdu jest druga @@ -2722,6 +2791,8 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz) break; case 4: // badanie zajętości toru { + CommLog(AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " " + + AnsiString(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])) + " rcvd"); TGroundNode *t = Ground.FindGroundNode( AnsiString(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])), TP_TRACK); if (t) @@ -2731,19 +2802,22 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz) break; case 5: // ustawienie parametrów { - if (*pRozkaz->iPar & 1) // ustawienie czasu - { - double t = pRozkaz->fPar[1]; - GlobalTime->dd = floor(t); // niby nie powinno być dnia, ale... - if (Global::fMoveLight >= 0) - Global::fMoveLight = t; // trzeba by deklinację Słońca przeliczyć - GlobalTime->hh = floor(24 * t) - 24.0 * GlobalTime->dd; - GlobalTime->mm = - floor(60 * 24 * t) - 60.0 * (24.0 * GlobalTime->dd + GlobalTime->hh); - GlobalTime->mr = - floor(60 * 60 * 24 * t) - - 60.0 * (60.0 * (24.0 * GlobalTime->dd + GlobalTime->hh) + GlobalTime->mm); - } + CommLog(AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " params " + + IntToStr(*pRozkaz->iPar) + " rcvd"); + if (*pRozkaz->iPar == 0) // sprawdzenie czasu + if (*pRozkaz->iPar & 1) // ustawienie czasu + { + double t = pRozkaz->fPar[1]; + GlobalTime->dd = floor(t); // niby nie powinno być dnia, ale... + if (Global::fMoveLight >= 0) + Global::fMoveLight = t; // trzeba by deklinację Słońca przeliczyć + GlobalTime->hh = floor(24 * t) - 24.0 * GlobalTime->dd; + GlobalTime->mm = + floor(60 * 24 * t) - 60.0 * (24.0 * GlobalTime->dd + GlobalTime->hh); + GlobalTime->mr = + floor(60 * 60 * 24 * t) - + 60.0 * (60.0 * (24.0 * GlobalTime->dd + GlobalTime->hh) + GlobalTime->mm); + } if (*pRozkaz->iPar & 2) { // ustawienie flag zapauzowania Global::iPause = pRozkaz->fPar[2]; // zakładamy, że wysyłający wie, co robi @@ -2753,6 +2827,9 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz) case 6: // pobranie parametrów ruchu pojazdu if (Global::iMultiplayer) { // Ra 2014-12: to ma działać również dla pojazdów bez obsady + CommLog(AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " " + + AnsiString(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])) + + " rcvd"); if (pRozkaz->cString[0]) // jeśli długość nazwy jest niezerowa { // szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #7 TGroundNode *t; @@ -2773,18 +2850,62 @@ void TWorld::OnCommandGet(DaneRozkaz *pRozkaz) } break; case 8: // ponowne wysłanie informacji o zajętych odcinkach toru - Ground.TrackBusyList(); + CommLog(AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " all busy track" + " rcvd"); + Ground.TrackBusyList(); break; case 9: // ponowne wysłanie informacji o zajętych odcinkach izolowanych - Ground.IsolatedBusyList(); + CommLog(AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " all busy isolated" + " rcvd"); + Ground.IsolatedBusyList(); break; case 10: // badanie zajętości jednego odcinka izolowanego + CommLog(AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " " + + AnsiString(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])) + " rcvd"); Ground.IsolatedBusy(AnsiString(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0]))); break; - case 11: // ustawienie paerametrów ruchu pojazdu + case 11: // ustawienie parametrów ruchu pojazdu // Ground.IsolatedBusy(AnsiString(pRozkaz->cString+1,(unsigned)(pRozkaz->cString[0]))); break; - } + case 12: // skrocona ramka parametrow pojazdow AI (wszystkich!!) + CommLog(AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " obsadzone" + " rcvd"); + Ground.WyslijObsadzone(); + // Ground.IsolatedBusy(AnsiString(pRozkaz->cString+1,(unsigned)(pRozkaz->cString[0]))); + break; + case 13: // ramka uszkodzenia i innych stanow pojazdu, np. wylaczenie CA, wlaczenie recznego itd. + // WriteLog("Przyszlo 13!"); + // WriteLog(pRozkaz->cString); + CommLog(AnsiString(Now()) + " " + IntToStr(pRozkaz->iComm) + " " + + AnsiString(pRozkaz->cString + 1, (unsigned)(pRozkaz->cString[0])) + + " rcvd"); + if (pRozkaz->cString[1]) // jeśli długość nazwy jest niezerowa + { // szukamy pierwszego pojazdu o takiej nazwie i odsyłamy parametry ramką #13 + TGroundNode *t; + if (pRozkaz->cString[2] == '*') + t = Ground.DynamicFind( + Global::asHumanCtrlVehicle); // nazwa pojazdu użytkownika + else + t = Ground.DynamicFindAny( + AnsiString(pRozkaz->cString + 2, + (unsigned)pRozkaz->cString[1])); // nazwa pojazdu + if (t) + { + TDynamicObject *d = t->DynamicObject; + while (d) + { + d->Damage(pRozkaz->cString[0]); + d = d->Next(); // pozostałe też + } + d = t->DynamicObject->Prev(); + while (d) + { + d->Damage(pRozkaz->cString[0]); + d = d->Prev(); // w drugą stronę też + } + Ground.WyslijUszkodzenia(t->asName, t->DynamicObject->MoverParameters->EngDmgFlag); // zwrot informacji o pojeździe + } + } + // Ground.IsolatedBusy(AnsiString(pRozkaz->cString+1,(unsigned)(pRozkaz->cString[0]))); + break; + } }; //--------------------------------------------------------------------------- diff --git a/World.h b/World.h index c35ffeca2..c9ca570a0 100644 --- a/World.h +++ b/World.h @@ -62,6 +62,9 @@ class TWorld double fTimeBuffer; // bufor czasu aktualizacji dla stałego kroku fizyki double fMaxDt; //[s] krok czasowy fizyki (0.01 dla normalnych warunków) int iPause; // wykrywanie zmian w zapauzowaniu + double VelPrev; // poprzednia prędkość + int tprev; // poprzedni czas + double Acc; // przyspieszenie styczne public: void ModifyTGA(const AnsiString &dir = ""); void CreateE3D(const AnsiString &dir = "", bool dyn = false); diff --git a/geometry.cpp b/geometry.cpp index a4ef3a133..ced642a88 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -16,15 +16,15 @@ inline double sqr(double a) return (a * a); }; -__fastcall TLine::TLine(){}; + TLine::TLine(){}; -__fastcall TLine::TLine(vector3 NPoint, vector3 NVector) + TLine::TLine(vector3 NPoint, vector3 NVector) { Vector = NVector; Point = NPoint; }; -__fastcall TLine::~TLine(){}; + TLine::~TLine(){}; TPlane TLine::GetPlane() { @@ -42,31 +42,31 @@ double TLine::GetDistance(vector3 Point1) //--------------------------------------------------------------------------- -__fastcall TPlane::TPlane() + TPlane::TPlane() { Vector = vector3(0, 0, 0); d = 0; }; -__fastcall TPlane::TPlane(vector3 NVector, double nd) + TPlane::TPlane(vector3 NVector, double nd) { Vector = NVector; d = nd; } -__fastcall TPlane::TPlane(vector3 Point, vector3 NVector) + TPlane::TPlane(vector3 Point, vector3 NVector) { Vector = NVector; d = -NVector.x * Point.x - NVector.y * Point.y - NVector.z * Point.z; }; -__fastcall TPlane::TPlane(vector3 Point1, vector3 Vector1, vector3 Vector2) + TPlane::TPlane(vector3 Point1, vector3 Vector1, vector3 Vector2) { Vector = CrossProduct(Vector1, Vector2); d = -Vector.x * Point1.x - Vector.y * Point1.y - Vector.z * Point1.z; }; -__fastcall TPlane::~TPlane(){}; + TPlane::~TPlane(){}; void TPlane::Normalize() { diff --git a/python/include/Python-ast.h b/python/include/Python-ast.h new file mode 100644 index 000000000..3f35bbb63 --- /dev/null +++ b/python/include/Python-ast.h @@ -0,0 +1,535 @@ +/* File automatically generated by Parser/asdl_c.py. */ + +#include "asdl.h" + +typedef struct _mod *mod_ty; + +typedef struct _stmt *stmt_ty; + +typedef struct _expr *expr_ty; + +typedef enum _expr_context { Load=1, Store=2, Del=3, AugLoad=4, AugStore=5, + Param=6 } expr_context_ty; + +typedef struct _slice *slice_ty; + +typedef enum _boolop { And=1, Or=2 } boolop_ty; + +typedef enum _operator { Add=1, Sub=2, Mult=3, Div=4, Mod=5, Pow=6, LShift=7, + RShift=8, BitOr=9, BitXor=10, BitAnd=11, FloorDiv=12 } + operator_ty; + +typedef enum _unaryop { Invert=1, Not=2, UAdd=3, USub=4 } unaryop_ty; + +typedef enum _cmpop { Eq=1, NotEq=2, Lt=3, LtE=4, Gt=5, GtE=6, Is=7, IsNot=8, + In=9, NotIn=10 } cmpop_ty; + +typedef struct _comprehension *comprehension_ty; + +typedef struct _excepthandler *excepthandler_ty; + +typedef struct _arguments *arguments_ty; + +typedef struct _keyword *keyword_ty; + +typedef struct _alias *alias_ty; + + +enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3, + Suite_kind=4}; +struct _mod { + enum _mod_kind kind; + union { + struct { + asdl_seq *body; + } Module; + + struct { + asdl_seq *body; + } Interactive; + + struct { + expr_ty body; + } Expression; + + struct { + asdl_seq *body; + } Suite; + + } v; +}; + +enum _stmt_kind {FunctionDef_kind=1, ClassDef_kind=2, Return_kind=3, + Delete_kind=4, Assign_kind=5, AugAssign_kind=6, Print_kind=7, + For_kind=8, While_kind=9, If_kind=10, With_kind=11, + Raise_kind=12, TryExcept_kind=13, TryFinally_kind=14, + Assert_kind=15, Import_kind=16, ImportFrom_kind=17, + Exec_kind=18, Global_kind=19, Expr_kind=20, Pass_kind=21, + Break_kind=22, Continue_kind=23}; +struct _stmt { + enum _stmt_kind kind; + union { + struct { + identifier name; + arguments_ty args; + asdl_seq *body; + asdl_seq *decorator_list; + } FunctionDef; + + struct { + identifier name; + asdl_seq *bases; + asdl_seq *body; + asdl_seq *decorator_list; + } ClassDef; + + struct { + expr_ty value; + } Return; + + struct { + asdl_seq *targets; + } Delete; + + struct { + asdl_seq *targets; + expr_ty value; + } Assign; + + struct { + expr_ty target; + operator_ty op; + expr_ty value; + } AugAssign; + + struct { + expr_ty dest; + asdl_seq *values; + bool nl; + } Print; + + struct { + expr_ty target; + expr_ty iter; + asdl_seq *body; + asdl_seq *orelse; + } For; + + struct { + expr_ty test; + asdl_seq *body; + asdl_seq *orelse; + } While; + + struct { + expr_ty test; + asdl_seq *body; + asdl_seq *orelse; + } If; + + struct { + expr_ty context_expr; + expr_ty optional_vars; + asdl_seq *body; + } With; + + struct { + expr_ty type; + expr_ty inst; + expr_ty tback; + } Raise; + + struct { + asdl_seq *body; + asdl_seq *handlers; + asdl_seq *orelse; + } TryExcept; + + struct { + asdl_seq *body; + asdl_seq *finalbody; + } TryFinally; + + struct { + expr_ty test; + expr_ty msg; + } Assert; + + struct { + asdl_seq *names; + } Import; + + struct { + identifier module; + asdl_seq *names; + int level; + } ImportFrom; + + struct { + expr_ty body; + expr_ty globals; + expr_ty locals; + } Exec; + + struct { + asdl_seq *names; + } Global; + + struct { + expr_ty value; + } Expr; + + } v; + int lineno; + int col_offset; +}; + +enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4, + IfExp_kind=5, Dict_kind=6, Set_kind=7, ListComp_kind=8, + SetComp_kind=9, DictComp_kind=10, GeneratorExp_kind=11, + Yield_kind=12, Compare_kind=13, Call_kind=14, Repr_kind=15, + Num_kind=16, Str_kind=17, Attribute_kind=18, + Subscript_kind=19, Name_kind=20, List_kind=21, Tuple_kind=22}; +struct _expr { + enum _expr_kind kind; + union { + struct { + boolop_ty op; + asdl_seq *values; + } BoolOp; + + struct { + expr_ty left; + operator_ty op; + expr_ty right; + } BinOp; + + struct { + unaryop_ty op; + expr_ty operand; + } UnaryOp; + + struct { + arguments_ty args; + expr_ty body; + } Lambda; + + struct { + expr_ty test; + expr_ty body; + expr_ty orelse; + } IfExp; + + struct { + asdl_seq *keys; + asdl_seq *values; + } Dict; + + struct { + asdl_seq *elts; + } Set; + + struct { + expr_ty elt; + asdl_seq *generators; + } ListComp; + + struct { + expr_ty elt; + asdl_seq *generators; + } SetComp; + + struct { + expr_ty key; + expr_ty value; + asdl_seq *generators; + } DictComp; + + struct { + expr_ty elt; + asdl_seq *generators; + } GeneratorExp; + + struct { + expr_ty value; + } Yield; + + struct { + expr_ty left; + asdl_int_seq *ops; + asdl_seq *comparators; + } Compare; + + struct { + expr_ty func; + asdl_seq *args; + asdl_seq *keywords; + expr_ty starargs; + expr_ty kwargs; + } Call; + + struct { + expr_ty value; + } Repr; + + struct { + object n; + } Num; + + struct { + string s; + } Str; + + struct { + expr_ty value; + identifier attr; + expr_context_ty ctx; + } Attribute; + + struct { + expr_ty value; + slice_ty slice; + expr_context_ty ctx; + } Subscript; + + struct { + identifier id; + expr_context_ty ctx; + } Name; + + struct { + asdl_seq *elts; + expr_context_ty ctx; + } List; + + struct { + asdl_seq *elts; + expr_context_ty ctx; + } Tuple; + + } v; + int lineno; + int col_offset; +}; + +enum _slice_kind {Ellipsis_kind=1, Slice_kind=2, ExtSlice_kind=3, Index_kind=4}; +struct _slice { + enum _slice_kind kind; + union { + struct { + expr_ty lower; + expr_ty upper; + expr_ty step; + } Slice; + + struct { + asdl_seq *dims; + } ExtSlice; + + struct { + expr_ty value; + } Index; + + } v; +}; + +struct _comprehension { + expr_ty target; + expr_ty iter; + asdl_seq *ifs; +}; + +enum _excepthandler_kind {ExceptHandler_kind=1}; +struct _excepthandler { + enum _excepthandler_kind kind; + union { + struct { + expr_ty type; + expr_ty name; + asdl_seq *body; + } ExceptHandler; + + } v; + int lineno; + int col_offset; +}; + +struct _arguments { + asdl_seq *args; + identifier vararg; + identifier kwarg; + asdl_seq *defaults; +}; + +struct _keyword { + identifier arg; + expr_ty value; +}; + +struct _alias { + identifier name; + identifier asname; +}; + + +#define Module(a0, a1) _Py_Module(a0, a1) +mod_ty _Py_Module(asdl_seq * body, PyArena *arena); +#define Interactive(a0, a1) _Py_Interactive(a0, a1) +mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena); +#define Expression(a0, a1) _Py_Expression(a0, a1) +mod_ty _Py_Expression(expr_ty body, PyArena *arena); +#define Suite(a0, a1) _Py_Suite(a0, a1) +mod_ty _Py_Suite(asdl_seq * body, PyArena *arena); +#define FunctionDef(a0, a1, a2, a3, a4, a5, a6) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body, + asdl_seq * decorator_list, int lineno, int col_offset, + PyArena *arena); +#define ClassDef(a0, a1, a2, a3, a4, a5, a6) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, + asdl_seq * decorator_list, int lineno, int col_offset, + PyArena *arena); +#define Return(a0, a1, a2, a3) _Py_Return(a0, a1, a2, a3) +stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Delete(a0, a1, a2, a3) _Py_Delete(a0, a1, a2, a3) +stmt_ty _Py_Delete(asdl_seq * targets, int lineno, int col_offset, PyArena + *arena); +#define Assign(a0, a1, a2, a3, a4) _Py_Assign(a0, a1, a2, a3, a4) +stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, int lineno, int + col_offset, PyArena *arena); +#define AugAssign(a0, a1, a2, a3, a4, a5) _Py_AugAssign(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int + lineno, int col_offset, PyArena *arena); +#define Print(a0, a1, a2, a3, a4, a5) _Py_Print(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, int + col_offset, PyArena *arena); +#define For(a0, a1, a2, a3, a4, a5, a6) _Py_For(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * + orelse, int lineno, int col_offset, PyArena *arena); +#define While(a0, a1, a2, a3, a4, a5) _Py_While(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, + int col_offset, PyArena *arena); +#define If(a0, a1, a2, a3, a4, a5) _Py_If(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, + int col_offset, PyArena *arena); +#define With(a0, a1, a2, a3, a4, a5) _Py_With(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, + int lineno, int col_offset, PyArena *arena); +#define Raise(a0, a1, a2, a3, a4, a5) _Py_Raise(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, int + col_offset, PyArena *arena); +#define TryExcept(a0, a1, a2, a3, a4, a5) _Py_TryExcept(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, + int lineno, int col_offset, PyArena *arena); +#define TryFinally(a0, a1, a2, a3, a4) _Py_TryFinally(a0, a1, a2, a3, a4) +stmt_ty _Py_TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, int + col_offset, PyArena *arena); +#define Assert(a0, a1, a2, a3, a4) _Py_Assert(a0, a1, a2, a3, a4) +stmt_ty _Py_Assert(expr_ty test, expr_ty msg, int lineno, int col_offset, + PyArena *arena); +#define Import(a0, a1, a2, a3) _Py_Import(a0, a1, a2, a3) +stmt_ty _Py_Import(asdl_seq * names, int lineno, int col_offset, PyArena + *arena); +#define ImportFrom(a0, a1, a2, a3, a4, a5) _Py_ImportFrom(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_ImportFrom(identifier module, asdl_seq * names, int level, int + lineno, int col_offset, PyArena *arena); +#define Exec(a0, a1, a2, a3, a4, a5) _Py_Exec(a0, a1, a2, a3, a4, a5) +stmt_ty _Py_Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, int + col_offset, PyArena *arena); +#define Global(a0, a1, a2, a3) _Py_Global(a0, a1, a2, a3) +stmt_ty _Py_Global(asdl_seq * names, int lineno, int col_offset, PyArena + *arena); +#define Expr(a0, a1, a2, a3) _Py_Expr(a0, a1, a2, a3) +stmt_ty _Py_Expr(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Pass(a0, a1, a2) _Py_Pass(a0, a1, a2) +stmt_ty _Py_Pass(int lineno, int col_offset, PyArena *arena); +#define Break(a0, a1, a2) _Py_Break(a0, a1, a2) +stmt_ty _Py_Break(int lineno, int col_offset, PyArena *arena); +#define Continue(a0, a1, a2) _Py_Continue(a0, a1, a2) +stmt_ty _Py_Continue(int lineno, int col_offset, PyArena *arena); +#define BoolOp(a0, a1, a2, a3, a4) _Py_BoolOp(a0, a1, a2, a3, a4) +expr_ty _Py_BoolOp(boolop_ty op, asdl_seq * values, int lineno, int col_offset, + PyArena *arena); +#define BinOp(a0, a1, a2, a3, a4, a5) _Py_BinOp(a0, a1, a2, a3, a4, a5) +expr_ty _Py_BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, int + col_offset, PyArena *arena); +#define UnaryOp(a0, a1, a2, a3, a4) _Py_UnaryOp(a0, a1, a2, a3, a4) +expr_ty _Py_UnaryOp(unaryop_ty op, expr_ty operand, int lineno, int col_offset, + PyArena *arena); +#define Lambda(a0, a1, a2, a3, a4) _Py_Lambda(a0, a1, a2, a3, a4) +expr_ty _Py_Lambda(arguments_ty args, expr_ty body, int lineno, int col_offset, + PyArena *arena); +#define IfExp(a0, a1, a2, a3, a4, a5) _Py_IfExp(a0, a1, a2, a3, a4, a5) +expr_ty _Py_IfExp(expr_ty test, expr_ty body, expr_ty orelse, int lineno, int + col_offset, PyArena *arena); +#define Dict(a0, a1, a2, a3, a4) _Py_Dict(a0, a1, a2, a3, a4) +expr_ty _Py_Dict(asdl_seq * keys, asdl_seq * values, int lineno, int + col_offset, PyArena *arena); +#define Set(a0, a1, a2, a3) _Py_Set(a0, a1, a2, a3) +expr_ty _Py_Set(asdl_seq * elts, int lineno, int col_offset, PyArena *arena); +#define ListComp(a0, a1, a2, a3, a4) _Py_ListComp(a0, a1, a2, a3, a4) +expr_ty _Py_ListComp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, PyArena *arena); +#define SetComp(a0, a1, a2, a3, a4) _Py_SetComp(a0, a1, a2, a3, a4) +expr_ty _Py_SetComp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, PyArena *arena); +#define DictComp(a0, a1, a2, a3, a4, a5) _Py_DictComp(a0, a1, a2, a3, a4, a5) +expr_ty _Py_DictComp(expr_ty key, expr_ty value, asdl_seq * generators, int + lineno, int col_offset, PyArena *arena); +#define GeneratorExp(a0, a1, a2, a3, a4) _Py_GeneratorExp(a0, a1, a2, a3, a4) +expr_ty _Py_GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, int + col_offset, PyArena *arena); +#define Yield(a0, a1, a2, a3) _Py_Yield(a0, a1, a2, a3) +expr_ty _Py_Yield(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Compare(a0, a1, a2, a3, a4, a5) _Py_Compare(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Compare(expr_ty left, asdl_int_seq * ops, asdl_seq * comparators, + int lineno, int col_offset, PyArena *arena); +#define Call(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Call(a0, a1, a2, a3, a4, a5, a6, a7) +expr_ty _Py_Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty + starargs, expr_ty kwargs, int lineno, int col_offset, PyArena + *arena); +#define Repr(a0, a1, a2, a3) _Py_Repr(a0, a1, a2, a3) +expr_ty _Py_Repr(expr_ty value, int lineno, int col_offset, PyArena *arena); +#define Num(a0, a1, a2, a3) _Py_Num(a0, a1, a2, a3) +expr_ty _Py_Num(object n, int lineno, int col_offset, PyArena *arena); +#define Str(a0, a1, a2, a3) _Py_Str(a0, a1, a2, a3) +expr_ty _Py_Str(string s, int lineno, int col_offset, PyArena *arena); +#define Attribute(a0, a1, a2, a3, a4, a5) _Py_Attribute(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int + lineno, int col_offset, PyArena *arena); +#define Subscript(a0, a1, a2, a3, a4, a5) _Py_Subscript(a0, a1, a2, a3, a4, a5) +expr_ty _Py_Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int + lineno, int col_offset, PyArena *arena); +#define Name(a0, a1, a2, a3, a4) _Py_Name(a0, a1, a2, a3, a4) +expr_ty _Py_Name(identifier id, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define List(a0, a1, a2, a3, a4) _Py_List(a0, a1, a2, a3, a4) +expr_ty _Py_List(asdl_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define Tuple(a0, a1, a2, a3, a4) _Py_Tuple(a0, a1, a2, a3, a4) +expr_ty _Py_Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, int + col_offset, PyArena *arena); +#define Ellipsis(a0) _Py_Ellipsis(a0) +slice_ty _Py_Ellipsis(PyArena *arena); +#define Slice(a0, a1, a2, a3) _Py_Slice(a0, a1, a2, a3) +slice_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena); +#define ExtSlice(a0, a1) _Py_ExtSlice(a0, a1) +slice_ty _Py_ExtSlice(asdl_seq * dims, PyArena *arena); +#define Index(a0, a1) _Py_Index(a0, a1) +slice_ty _Py_Index(expr_ty value, PyArena *arena); +#define comprehension(a0, a1, a2, a3) _Py_comprehension(a0, a1, a2, a3) +comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_seq * + ifs, PyArena *arena); +#define ExceptHandler(a0, a1, a2, a3, a4, a5) _Py_ExceptHandler(a0, a1, a2, a3, a4, a5) +excepthandler_ty _Py_ExceptHandler(expr_ty type, expr_ty name, asdl_seq * body, + int lineno, int col_offset, PyArena *arena); +#define arguments(a0, a1, a2, a3, a4) _Py_arguments(a0, a1, a2, a3, a4) +arguments_ty _Py_arguments(asdl_seq * args, identifier vararg, identifier + kwarg, asdl_seq * defaults, PyArena *arena); +#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2) +keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena); +#define alias(a0, a1, a2) _Py_alias(a0, a1, a2) +alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); + +PyObject* PyAST_mod2obj(mod_ty t); +mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode); +int PyAST_Check(PyObject* obj); diff --git a/python/include/Python.h b/python/include/Python.h new file mode 100644 index 000000000..775412b8c --- /dev/null +++ b/python/include/Python.h @@ -0,0 +1,178 @@ +#ifndef Py_PYTHON_H +#define Py_PYTHON_H +/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */ + +/* Include nearly all Python header files */ + +#include "patchlevel.h" +#include "pyconfig.h" +#include "pymacconfig.h" + +/* Cyclic gc is always enabled, starting with release 2.3a1. Supply the + * old symbol for the benefit of extension modules written before then + * that may be conditionalizing on it. The core doesn't use it anymore. + */ +#ifndef WITH_CYCLE_GC +#define WITH_CYCLE_GC 1 +#endif + +#include + +#ifndef UCHAR_MAX +#error "Something's broken. UCHAR_MAX should be defined in limits.h." +#endif + +#if UCHAR_MAX != 255 +#error "Python's source code assumes C's unsigned char is an 8-bit type." +#endif + +#if defined(__sgi) && defined(WITH_THREAD) && !defined(_SGI_MP_SOURCE) +#define _SGI_MP_SOURCE +#endif + +#include +#ifndef NULL +# error "Python.h requires that stdio.h define NULL." +#endif + +#include +#ifdef HAVE_ERRNO_H +#include +#endif +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +/* For size_t? */ +#ifdef HAVE_STDDEF_H +#include +#endif + +/* CAUTION: Build setups should ensure that NDEBUG is defined on the + * compiler command line when building Python in release mode; else + * assert() calls won't be removed. + */ +#include + +#include "pyport.h" + +/* pyconfig.h or pyport.h may or may not define DL_IMPORT */ +#ifndef DL_IMPORT /* declarations for DLL import/export */ +#define DL_IMPORT(RTYPE) RTYPE +#endif +#ifndef DL_EXPORT /* declarations for DLL import/export */ +#define DL_EXPORT(RTYPE) RTYPE +#endif + +/* Debug-mode build with pymalloc implies PYMALLOC_DEBUG. + * PYMALLOC_DEBUG is in error if pymalloc is not in use. + */ +#if defined(Py_DEBUG) && defined(WITH_PYMALLOC) && !defined(PYMALLOC_DEBUG) +#define PYMALLOC_DEBUG +#endif +#if defined(PYMALLOC_DEBUG) && !defined(WITH_PYMALLOC) +#error "PYMALLOC_DEBUG requires WITH_PYMALLOC" +#endif +#include "pymath.h" +#include "pymem.h" + +#include "object.h" +#include "objimpl.h" + +#include "pydebug.h" + +#include "unicodeobject.h" +#include "intobject.h" +#include "boolobject.h" +#include "longobject.h" +#include "floatobject.h" +#ifndef WITHOUT_COMPLEX +#include "complexobject.h" +#endif +#include "rangeobject.h" +#include "stringobject.h" +#include "memoryobject.h" +#include "bufferobject.h" +#include "bytesobject.h" +#include "bytearrayobject.h" +#include "tupleobject.h" +#include "listobject.h" +#include "dictobject.h" +#include "enumobject.h" +#include "setobject.h" +#include "methodobject.h" +#include "moduleobject.h" +#include "funcobject.h" +#include "classobject.h" +#include "fileobject.h" +#include "cobject.h" +#include "pycapsule.h" +#include "traceback.h" +#include "sliceobject.h" +#include "cellobject.h" +#include "iterobject.h" +#include "genobject.h" +#include "descrobject.h" +#include "warnings.h" +#include "weakrefobject.h" + +#include "codecs.h" +#include "pyerrors.h" + +#include "pystate.h" + +#include "pyarena.h" +#include "modsupport.h" +#include "pythonrun.h" +#include "ceval.h" +#include "sysmodule.h" +#include "intrcheck.h" +#include "import.h" + +#include "abstract.h" + +#include "compile.h" +#include "eval.h" + +#include "pyctype.h" +#include "pystrtod.h" +#include "pystrcmp.h" +#include "dtoa.h" + +/* _Py_Mangle is defined in compile.c */ +PyAPI_FUNC(PyObject*) _Py_Mangle(PyObject *p, PyObject *name); + +/* PyArg_GetInt is deprecated and should not be used, use PyArg_Parse(). */ +#define PyArg_GetInt(v, a) PyArg_Parse((v), "i", (a)) + +/* PyArg_NoArgs should not be necessary. + Set ml_flags in the PyMethodDef to METH_NOARGS. */ +#define PyArg_NoArgs(v) PyArg_Parse(v, "") + +/* Argument must be a char or an int in [-128, 127] or [0, 255]. */ +#define Py_CHARMASK(c) ((unsigned char)((c) & 0xff)) + +#include "pyfpe.h" + +/* These definitions must match corresponding definitions in graminit.h. + There's code in compile.c that checks that they are the same. */ +#define Py_single_input 256 +#define Py_file_input 257 +#define Py_eval_input 258 + +#ifdef HAVE_PTH +/* GNU pth user-space thread support */ +#include +#endif + +/* Define macros for inline documentation. */ +#define PyDoc_VAR(name) static char name[] +#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str) +#ifdef WITH_DOC_STRINGS +#define PyDoc_STR(str) str +#else +#define PyDoc_STR(str) "" +#endif + +#endif /* !Py_PYTHON_H */ diff --git a/python/include/abstract.h b/python/include/abstract.h new file mode 100644 index 000000000..a37742386 --- /dev/null +++ b/python/include/abstract.h @@ -0,0 +1,1396 @@ +#ifndef Py_ABSTRACTOBJECT_H +#define Py_ABSTRACTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef PY_SSIZE_T_CLEAN +#define PyObject_CallFunction _PyObject_CallFunction_SizeT +#define PyObject_CallMethod _PyObject_CallMethod_SizeT +#endif + +/* Abstract Object Interface (many thanks to Jim Fulton) */ + +/* + PROPOSAL: A Generic Python Object Interface for Python C Modules + +Problem + + Python modules written in C that must access Python objects must do + so through routines whose interfaces are described by a set of + include files. Unfortunately, these routines vary according to the + object accessed. To use these routines, the C programmer must check + the type of the object being used and must call a routine based on + the object type. For example, to access an element of a sequence, + the programmer must determine whether the sequence is a list or a + tuple: + + if(is_tupleobject(o)) + e=gettupleitem(o,i) + else if(is_listitem(o)) + e=getlistitem(o,i) + + If the programmer wants to get an item from another type of object + that provides sequence behavior, there is no clear way to do it + correctly. + + The persistent programmer may peruse object.h and find that the + _typeobject structure provides a means of invoking up to (currently + about) 41 special operators. So, for example, a routine can get an + item from any object that provides sequence behavior. However, to + use this mechanism, the programmer must make their code dependent on + the current Python implementation. + + Also, certain semantics, especially memory management semantics, may + differ by the type of object being used. Unfortunately, these + semantics are not clearly described in the current include files. + An abstract interface providing more consistent semantics is needed. + +Proposal + + I propose the creation of a standard interface (with an associated + library of routines and/or macros) for generically obtaining the + services of Python objects. This proposal can be viewed as one + components of a Python C interface consisting of several components. + + From the viewpoint of C access to Python services, we have (as + suggested by Guido in off-line discussions): + + - "Very high level layer": two or three functions that let you exec or + eval arbitrary Python code given as a string in a module whose name is + given, passing C values in and getting C values out using + mkvalue/getargs style format strings. This does not require the user + to declare any variables of type "PyObject *". This should be enough + to write a simple application that gets Python code from the user, + execs it, and returns the output or errors. (Error handling must also + be part of this API.) + + - "Abstract objects layer": which is the subject of this proposal. + It has many functions operating on objects, and lest you do many + things from C that you can also write in Python, without going + through the Python parser. + + - "Concrete objects layer": This is the public type-dependent + interface provided by the standard built-in types, such as floats, + strings, and lists. This interface exists and is currently + documented by the collection of include files provided with the + Python distributions. + + From the point of view of Python accessing services provided by C + modules: + + - "Python module interface": this interface consist of the basic + routines used to define modules and their members. Most of the + current extensions-writing guide deals with this interface. + + - "Built-in object interface": this is the interface that a new + built-in type must provide and the mechanisms and rules that a + developer of a new built-in type must use and follow. + + This proposal is a "first-cut" that is intended to spur + discussion. See especially the lists of notes. + + The Python C object interface will provide four protocols: object, + numeric, sequence, and mapping. Each protocol consists of a + collection of related operations. If an operation that is not + provided by a particular type is invoked, then a standard exception, + NotImplementedError is raised with a operation name as an argument. + In addition, for convenience this interface defines a set of + constructors for building objects of built-in types. This is needed + so new objects can be returned from C functions that otherwise treat + objects generically. + +Memory Management + + For all of the functions described in this proposal, if a function + retains a reference to a Python object passed as an argument, then the + function will increase the reference count of the object. It is + unnecessary for the caller to increase the reference count of an + argument in anticipation of the object's retention. + + All Python objects returned from functions should be treated as new + objects. Functions that return objects assume that the caller will + retain a reference and the reference count of the object has already + been incremented to account for this fact. A caller that does not + retain a reference to an object that is returned from a function + must decrement the reference count of the object (using + DECREF(object)) to prevent memory leaks. + + Note that the behavior mentioned here is different from the current + behavior for some objects (e.g. lists and tuples) when certain + type-specific routines are called directly (e.g. setlistitem). The + proposed abstraction layer will provide a consistent memory + management interface, correcting for inconsistent behavior for some + built-in types. + +Protocols + +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ + +/* Object Protocol: */ + + /* Implemented elsewhere: + + int PyObject_Print(PyObject *o, FILE *fp, int flags); + + Print an object, o, on file, fp. Returns -1 on + error. The flags argument is used to enable certain printing + options. The only option currently supported is Py_Print_RAW. + + (What should be said about Py_Print_RAW?) + + */ + + /* Implemented elsewhere: + + int PyObject_HasAttrString(PyObject *o, char *attr_name); + + Returns 1 if o has the attribute attr_name, and 0 otherwise. + This is equivalent to the Python expression: + hasattr(o,attr_name). + + This function always succeeds. + + */ + + /* Implemented elsewhere: + + PyObject* PyObject_GetAttrString(PyObject *o, char *attr_name); + + Retrieve an attributed named attr_name form object o. + Returns the attribute value on success, or NULL on failure. + This is the equivalent of the Python expression: o.attr_name. + + */ + + /* Implemented elsewhere: + + int PyObject_HasAttr(PyObject *o, PyObject *attr_name); + + Returns 1 if o has the attribute attr_name, and 0 otherwise. + This is equivalent to the Python expression: + hasattr(o,attr_name). + + This function always succeeds. + + */ + + /* Implemented elsewhere: + + PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name); + + Retrieve an attributed named attr_name form object o. + Returns the attribute value on success, or NULL on failure. + This is the equivalent of the Python expression: o.attr_name. + + */ + + + /* Implemented elsewhere: + + int PyObject_SetAttrString(PyObject *o, char *attr_name, PyObject *v); + + Set the value of the attribute named attr_name, for object o, + to the value, v. Returns -1 on failure. This is + the equivalent of the Python statement: o.attr_name=v. + + */ + + /* Implemented elsewhere: + + int PyObject_SetAttr(PyObject *o, PyObject *attr_name, PyObject *v); + + Set the value of the attribute named attr_name, for object o, + to the value, v. Returns -1 on failure. This is + the equivalent of the Python statement: o.attr_name=v. + + */ + + /* implemented as a macro: + + int PyObject_DelAttrString(PyObject *o, char *attr_name); + + Delete attribute named attr_name, for object o. Returns + -1 on failure. This is the equivalent of the Python + statement: del o.attr_name. + + */ +#define PyObject_DelAttrString(O,A) PyObject_SetAttrString((O),(A),NULL) + + /* implemented as a macro: + + int PyObject_DelAttr(PyObject *o, PyObject *attr_name); + + Delete attribute named attr_name, for object o. Returns -1 + on failure. This is the equivalent of the Python + statement: del o.attr_name. + + */ +#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A),NULL) + + PyAPI_FUNC(int) PyObject_Cmp(PyObject *o1, PyObject *o2, int *result); + + /* + Compare the values of o1 and o2 using a routine provided by + o1, if one exists, otherwise with a routine provided by o2. + The result of the comparison is returned in result. Returns + -1 on failure. This is the equivalent of the Python + statement: result=cmp(o1,o2). + + */ + + /* Implemented elsewhere: + + int PyObject_Compare(PyObject *o1, PyObject *o2); + + Compare the values of o1 and o2 using a routine provided by + o1, if one exists, otherwise with a routine provided by o2. + Returns the result of the comparison on success. On error, + the value returned is undefined. This is equivalent to the + Python expression: cmp(o1,o2). + + */ + + /* Implemented elsewhere: + + PyObject *PyObject_Repr(PyObject *o); + + Compute the string representation of object, o. Returns the + string representation on success, NULL on failure. This is + the equivalent of the Python expression: repr(o). + + Called by the repr() built-in function and by reverse quotes. + + */ + + /* Implemented elsewhere: + + PyObject *PyObject_Str(PyObject *o); + + Compute the string representation of object, o. Returns the + string representation on success, NULL on failure. This is + the equivalent of the Python expression: str(o).) + + Called by the str() built-in function and by the print + statement. + + */ + + /* Implemented elsewhere: + + PyObject *PyObject_Unicode(PyObject *o); + + Compute the unicode representation of object, o. Returns the + unicode representation on success, NULL on failure. This is + the equivalent of the Python expression: unistr(o).) + + Called by the unistr() built-in function. + + */ + + /* Declared elsewhere + + PyAPI_FUNC(int) PyCallable_Check(PyObject *o); + + Determine if the object, o, is callable. Return 1 if the + object is callable and 0 otherwise. + + This function always succeeds. + + */ + + + + PyAPI_FUNC(PyObject *) PyObject_Call(PyObject *callable_object, + PyObject *args, PyObject *kw); + + /* + Call a callable Python object, callable_object, with + arguments and keywords arguments. The 'args' argument can not be + NULL, but the 'kw' argument can be NULL. + + */ + + PyAPI_FUNC(PyObject *) PyObject_CallObject(PyObject *callable_object, + PyObject *args); + + /* + Call a callable Python object, callable_object, with + arguments given by the tuple, args. If no arguments are + needed, then args may be NULL. Returns the result of the + call on success, or NULL on failure. This is the equivalent + of the Python expression: apply(o,args). + + */ + + PyAPI_FUNC(PyObject *) PyObject_CallFunction(PyObject *callable_object, + char *format, ...); + + /* + Call a callable Python object, callable_object, with a + variable number of C arguments. The C arguments are described + using a mkvalue-style format string. The format may be NULL, + indicating that no arguments are provided. Returns the + result of the call on success, or NULL on failure. This is + the equivalent of the Python expression: apply(o,args). + + */ + + + PyAPI_FUNC(PyObject *) PyObject_CallMethod(PyObject *o, char *m, + char *format, ...); + + /* + Call the method named m of object o with a variable number of + C arguments. The C arguments are described by a mkvalue + format string. The format may be NULL, indicating that no + arguments are provided. Returns the result of the call on + success, or NULL on failure. This is the equivalent of the + Python expression: o.method(args). + */ + + PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable, + char *format, ...); + PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *o, + char *name, + char *format, ...); + + PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable, + ...); + + /* + Call a callable Python object, callable_object, with a + variable number of C arguments. The C arguments are provided + as PyObject * values, terminated by a NULL. Returns the + result of the call on success, or NULL on failure. This is + the equivalent of the Python expression: apply(o,args). + */ + + + PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs(PyObject *o, + PyObject *m, ...); + + /* + Call the method named m of object o with a variable number of + C arguments. The C arguments are provided as PyObject * + values, terminated by NULL. Returns the result of the call + on success, or NULL on failure. This is the equivalent of + the Python expression: o.method(args). + */ + + + /* Implemented elsewhere: + + long PyObject_Hash(PyObject *o); + + Compute and return the hash, hash_value, of an object, o. On + failure, return -1. This is the equivalent of the Python + expression: hash(o). + + */ + + + /* Implemented elsewhere: + + int PyObject_IsTrue(PyObject *o); + + Returns 1 if the object, o, is considered to be true, 0 if o is + considered to be false and -1 on failure. This is equivalent to the + Python expression: not not o + + */ + + /* Implemented elsewhere: + + int PyObject_Not(PyObject *o); + + Returns 0 if the object, o, is considered to be true, 1 if o is + considered to be false and -1 on failure. This is equivalent to the + Python expression: not o + + */ + + PyAPI_FUNC(PyObject *) PyObject_Type(PyObject *o); + + /* + On success, returns a type object corresponding to the object + type of object o. On failure, returns NULL. This is + equivalent to the Python expression: type(o). + */ + + PyAPI_FUNC(Py_ssize_t) PyObject_Size(PyObject *o); + + /* + Return the size of object o. If the object, o, provides + both sequence and mapping protocols, the sequence size is + returned. On error, -1 is returned. This is the equivalent + to the Python expression: len(o). + + */ + + /* For DLL compatibility */ +#undef PyObject_Length + PyAPI_FUNC(Py_ssize_t) PyObject_Length(PyObject *o); +#define PyObject_Length PyObject_Size + + PyAPI_FUNC(Py_ssize_t) _PyObject_LengthHint(PyObject *o, Py_ssize_t); + + /* + Guess the size of object o using len(o) or o.__length_hint__(). + If neither of those return a non-negative value, then return the + default value. If one of the calls fails, this function returns -1. + */ + + PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key); + + /* + Return element of o corresponding to the object, key, or NULL + on failure. This is the equivalent of the Python expression: + o[key]. + + */ + + PyAPI_FUNC(int) PyObject_SetItem(PyObject *o, PyObject *key, PyObject *v); + + /* + Map the object, key, to the value, v. Returns + -1 on failure. This is the equivalent of the Python + statement: o[key]=v. + */ + + PyAPI_FUNC(int) PyObject_DelItemString(PyObject *o, char *key); + + /* + Remove the mapping for object, key, from the object *o. + Returns -1 on failure. This is equivalent to + the Python statement: del o[key]. + */ + + PyAPI_FUNC(int) PyObject_DelItem(PyObject *o, PyObject *key); + + /* + Delete the mapping for key from *o. Returns -1 on failure. + This is the equivalent of the Python statement: del o[key]. + */ + + PyAPI_FUNC(int) PyObject_AsCharBuffer(PyObject *obj, + const char **buffer, + Py_ssize_t *buffer_len); + + /* + Takes an arbitrary object which must support the (character, + single segment) buffer interface and returns a pointer to a + read-only memory location useable as character based input + for subsequent processing. + + 0 is returned on success. buffer and buffer_len are only + set in case no error occurs. Otherwise, -1 is returned and + an exception set. + + */ + + PyAPI_FUNC(int) PyObject_CheckReadBuffer(PyObject *obj); + + /* + Checks whether an arbitrary object supports the (character, + single segment) buffer interface. Returns 1 on success, 0 + on failure. + + */ + + PyAPI_FUNC(int) PyObject_AsReadBuffer(PyObject *obj, + const void **buffer, + Py_ssize_t *buffer_len); + + /* + Same as PyObject_AsCharBuffer() except that this API expects + (readable, single segment) buffer interface and returns a + pointer to a read-only memory location which can contain + arbitrary data. + + 0 is returned on success. buffer and buffer_len are only + set in case no error occurs. Otherwise, -1 is returned and + an exception set. + + */ + + PyAPI_FUNC(int) PyObject_AsWriteBuffer(PyObject *obj, + void **buffer, + Py_ssize_t *buffer_len); + + /* + Takes an arbitrary object which must support the (writeable, + single segment) buffer interface and returns a pointer to a + writeable memory location in buffer of size buffer_len. + + 0 is returned on success. buffer and buffer_len are only + set in case no error occurs. Otherwise, -1 is returned and + an exception set. + + */ + + /* new buffer API */ + +#define PyObject_CheckBuffer(obj) \ + (((obj)->ob_type->tp_as_buffer != NULL) && \ + (PyType_HasFeature((obj)->ob_type, Py_TPFLAGS_HAVE_NEWBUFFER)) && \ + ((obj)->ob_type->tp_as_buffer->bf_getbuffer != NULL)) + + /* Return 1 if the getbuffer function is available, otherwise + return 0 */ + + PyAPI_FUNC(int) PyObject_GetBuffer(PyObject *obj, Py_buffer *view, + int flags); + + /* This is a C-API version of the getbuffer function call. It checks + to make sure object has the required function pointer and issues the + call. Returns -1 and raises an error on failure and returns 0 on + success + */ + + + PyAPI_FUNC(void *) PyBuffer_GetPointer(Py_buffer *view, Py_ssize_t *indices); + + /* Get the memory area pointed to by the indices for the buffer given. + Note that view->ndim is the assumed size of indices + */ + + PyAPI_FUNC(int) PyBuffer_SizeFromFormat(const char *); + + /* Return the implied itemsize of the data-format area from a + struct-style description */ + + + + PyAPI_FUNC(int) PyBuffer_ToContiguous(void *buf, Py_buffer *view, + Py_ssize_t len, char fort); + + PyAPI_FUNC(int) PyBuffer_FromContiguous(Py_buffer *view, void *buf, + Py_ssize_t len, char fort); + + + /* Copy len bytes of data from the contiguous chunk of memory + pointed to by buf into the buffer exported by obj. Return + 0 on success and return -1 and raise a PyBuffer_Error on + error (i.e. the object does not have a buffer interface or + it is not working). + + If fort is 'F' and the object is multi-dimensional, + then the data will be copied into the array in + Fortran-style (first dimension varies the fastest). If + fort is 'C', then the data will be copied into the array + in C-style (last dimension varies the fastest). If fort + is 'A', then it does not matter and the copy will be made + in whatever way is more efficient. + + */ + + PyAPI_FUNC(int) PyObject_CopyData(PyObject *dest, PyObject *src); + + /* Copy the data from the src buffer to the buffer of destination + */ + + PyAPI_FUNC(int) PyBuffer_IsContiguous(Py_buffer *view, char fort); + + + PyAPI_FUNC(void) PyBuffer_FillContiguousStrides(int ndims, + Py_ssize_t *shape, + Py_ssize_t *strides, + int itemsize, + char fort); + + /* Fill the strides array with byte-strides of a contiguous + (Fortran-style if fort is 'F' or C-style otherwise) + array of the given shape with the given number of bytes + per element. + */ + + PyAPI_FUNC(int) PyBuffer_FillInfo(Py_buffer *view, PyObject *o, void *buf, + Py_ssize_t len, int readonly, + int flags); + + /* Fills in a buffer-info structure correctly for an exporter + that can only share a contiguous chunk of memory of + "unsigned bytes" of the given length. Returns 0 on success + and -1 (with raising an error) on error. + */ + + PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view); + + /* Releases a Py_buffer obtained from getbuffer ParseTuple's s*. + */ + + PyAPI_FUNC(PyObject *) PyObject_Format(PyObject* obj, + PyObject *format_spec); + /* + Takes an arbitrary object and returns the result of + calling obj.__format__(format_spec). + */ + +/* Iterators */ + + PyAPI_FUNC(PyObject *) PyObject_GetIter(PyObject *); + /* Takes an object and returns an iterator for it. + This is typically a new iterator but if the argument + is an iterator, this returns itself. */ + +#define PyIter_Check(obj) \ + (PyType_HasFeature((obj)->ob_type, Py_TPFLAGS_HAVE_ITER) && \ + (obj)->ob_type->tp_iternext != NULL && \ + (obj)->ob_type->tp_iternext != &_PyObject_NextNotImplemented) + + PyAPI_FUNC(PyObject *) PyIter_Next(PyObject *); + /* Takes an iterator object and calls its tp_iternext slot, + returning the next value. If the iterator is exhausted, + this returns NULL without setting an exception. + NULL with an exception means an error occurred. */ + +/* Number Protocol:*/ + + PyAPI_FUNC(int) PyNumber_Check(PyObject *o); + + /* + Returns 1 if the object, o, provides numeric protocols, and + false otherwise. + + This function always succeeds. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Add(PyObject *o1, PyObject *o2); + + /* + Returns the result of adding o1 and o2, or null on failure. + This is the equivalent of the Python expression: o1+o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Subtract(PyObject *o1, PyObject *o2); + + /* + Returns the result of subtracting o2 from o1, or null on + failure. This is the equivalent of the Python expression: + o1-o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Multiply(PyObject *o1, PyObject *o2); + + /* + Returns the result of multiplying o1 and o2, or null on + failure. This is the equivalent of the Python expression: + o1*o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Divide(PyObject *o1, PyObject *o2); + + /* + Returns the result of dividing o1 by o2, or null on failure. + This is the equivalent of the Python expression: o1/o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_FloorDivide(PyObject *o1, PyObject *o2); + + /* + Returns the result of dividing o1 by o2 giving an integral result, + or null on failure. + This is the equivalent of the Python expression: o1//o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_TrueDivide(PyObject *o1, PyObject *o2); + + /* + Returns the result of dividing o1 by o2 giving a float result, + or null on failure. + This is the equivalent of the Python expression: o1/o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Remainder(PyObject *o1, PyObject *o2); + + /* + Returns the remainder of dividing o1 by o2, or null on + failure. This is the equivalent of the Python expression: + o1%o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Divmod(PyObject *o1, PyObject *o2); + + /* + See the built-in function divmod. Returns NULL on failure. + This is the equivalent of the Python expression: + divmod(o1,o2). + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Power(PyObject *o1, PyObject *o2, + PyObject *o3); + + /* + See the built-in function pow. Returns NULL on failure. + This is the equivalent of the Python expression: + pow(o1,o2,o3), where o3 is optional. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Negative(PyObject *o); + + /* + Returns the negation of o on success, or null on failure. + This is the equivalent of the Python expression: -o. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Positive(PyObject *o); + + /* + Returns the (what?) of o on success, or NULL on failure. + This is the equivalent of the Python expression: +o. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Absolute(PyObject *o); + + /* + Returns the absolute value of o, or null on failure. This is + the equivalent of the Python expression: abs(o). + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Invert(PyObject *o); + + /* + Returns the bitwise negation of o on success, or NULL on + failure. This is the equivalent of the Python expression: + ~o. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Lshift(PyObject *o1, PyObject *o2); + + /* + Returns the result of left shifting o1 by o2 on success, or + NULL on failure. This is the equivalent of the Python + expression: o1 << o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Rshift(PyObject *o1, PyObject *o2); + + /* + Returns the result of right shifting o1 by o2 on success, or + NULL on failure. This is the equivalent of the Python + expression: o1 >> o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_And(PyObject *o1, PyObject *o2); + + /* + Returns the result of bitwise and of o1 and o2 on success, or + NULL on failure. This is the equivalent of the Python + expression: o1&o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Xor(PyObject *o1, PyObject *o2); + + /* + Returns the bitwise exclusive or of o1 by o2 on success, or + NULL on failure. This is the equivalent of the Python + expression: o1^o2. + + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Or(PyObject *o1, PyObject *o2); + + /* + Returns the result of bitwise or on o1 and o2 on success, or + NULL on failure. This is the equivalent of the Python + expression: o1|o2. + + */ + + /* Implemented elsewhere: + + int PyNumber_Coerce(PyObject **p1, PyObject **p2); + + This function takes the addresses of two variables of type + PyObject*. + + If the objects pointed to by *p1 and *p2 have the same type, + increment their reference count and return 0 (success). + If the objects can be converted to a common numeric type, + replace *p1 and *p2 by their converted value (with 'new' + reference counts), and return 0. + If no conversion is possible, or if some other error occurs, + return -1 (failure) and don't increment the reference counts. + The call PyNumber_Coerce(&o1, &o2) is equivalent to the Python + statement o1, o2 = coerce(o1, o2). + + */ + +#define PyIndex_Check(obj) \ + ((obj)->ob_type->tp_as_number != NULL && \ + PyType_HasFeature((obj)->ob_type, Py_TPFLAGS_HAVE_INDEX) && \ + (obj)->ob_type->tp_as_number->nb_index != NULL) + + PyAPI_FUNC(PyObject *) PyNumber_Index(PyObject *o); + + /* + Returns the object converted to a Python long or int + or NULL with an error raised on failure. + */ + + PyAPI_FUNC(Py_ssize_t) PyNumber_AsSsize_t(PyObject *o, PyObject *exc); + + /* + Returns the Integral instance converted to an int. The + instance is expected to be int or long or have an __int__ + method. Steals integral's reference. error_format will be + used to create the TypeError if integral isn't actually an + Integral instance. error_format should be a format string + that can accept a char* naming integral's type. + */ + + PyAPI_FUNC(PyObject *) _PyNumber_ConvertIntegralToInt( + PyObject *integral, + const char* error_format); + + /* + Returns the object converted to Py_ssize_t by going through + PyNumber_Index first. If an overflow error occurs while + converting the int-or-long to Py_ssize_t, then the second argument + is the error-type to return. If it is NULL, then the overflow error + is cleared and the value is clipped. + */ + + PyAPI_FUNC(PyObject *) PyNumber_Int(PyObject *o); + + /* + Returns the o converted to an integer object on success, or + NULL on failure. This is the equivalent of the Python + expression: int(o). + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Long(PyObject *o); + + /* + Returns the o converted to a long integer object on success, + or NULL on failure. This is the equivalent of the Python + expression: long(o). + + */ + + PyAPI_FUNC(PyObject *) PyNumber_Float(PyObject *o); + + /* + Returns the o converted to a float object on success, or NULL + on failure. This is the equivalent of the Python expression: + float(o). + */ + +/* In-place variants of (some of) the above number protocol functions */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceAdd(PyObject *o1, PyObject *o2); + + /* + Returns the result of adding o2 to o1, possibly in-place, or null + on failure. This is the equivalent of the Python expression: + o1 += o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceSubtract(PyObject *o1, PyObject *o2); + + /* + Returns the result of subtracting o2 from o1, possibly in-place or + null on failure. This is the equivalent of the Python expression: + o1 -= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceMultiply(PyObject *o1, PyObject *o2); + + /* + Returns the result of multiplying o1 by o2, possibly in-place, or + null on failure. This is the equivalent of the Python expression: + o1 *= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceDivide(PyObject *o1, PyObject *o2); + + /* + Returns the result of dividing o1 by o2, possibly in-place, or null + on failure. This is the equivalent of the Python expression: + o1 /= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceFloorDivide(PyObject *o1, + PyObject *o2); + + /* + Returns the result of dividing o1 by o2 giving an integral result, + possibly in-place, or null on failure. + This is the equivalent of the Python expression: + o1 /= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceTrueDivide(PyObject *o1, + PyObject *o2); + + /* + Returns the result of dividing o1 by o2 giving a float result, + possibly in-place, or null on failure. + This is the equivalent of the Python expression: + o1 /= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceRemainder(PyObject *o1, PyObject *o2); + + /* + Returns the remainder of dividing o1 by o2, possibly in-place, or + null on failure. This is the equivalent of the Python expression: + o1 %= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlacePower(PyObject *o1, PyObject *o2, + PyObject *o3); + + /* + Returns the result of raising o1 to the power of o2, possibly + in-place, or null on failure. This is the equivalent of the Python + expression: o1 **= o2, or pow(o1, o2, o3) if o3 is present. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceLshift(PyObject *o1, PyObject *o2); + + /* + Returns the result of left shifting o1 by o2, possibly in-place, or + null on failure. This is the equivalent of the Python expression: + o1 <<= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceRshift(PyObject *o1, PyObject *o2); + + /* + Returns the result of right shifting o1 by o2, possibly in-place or + null on failure. This is the equivalent of the Python expression: + o1 >>= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceAnd(PyObject *o1, PyObject *o2); + + /* + Returns the result of bitwise and of o1 and o2, possibly in-place, + or null on failure. This is the equivalent of the Python + expression: o1 &= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceXor(PyObject *o1, PyObject *o2); + + /* + Returns the bitwise exclusive or of o1 by o2, possibly in-place, or + null on failure. This is the equivalent of the Python expression: + o1 ^= o2. + + */ + + PyAPI_FUNC(PyObject *) PyNumber_InPlaceOr(PyObject *o1, PyObject *o2); + + /* + Returns the result of bitwise or of o1 and o2, possibly in-place, + or null on failure. This is the equivalent of the Python + expression: o1 |= o2. + + */ + + + PyAPI_FUNC(PyObject *) PyNumber_ToBase(PyObject *n, int base); + + /* + Returns the integer n converted to a string with a base, with a base + marker of 0b, 0o or 0x prefixed if applicable. + If n is not an int object, it is converted with PyNumber_Index first. + */ + + +/* Sequence protocol:*/ + + PyAPI_FUNC(int) PySequence_Check(PyObject *o); + + /* + Return 1 if the object provides sequence protocol, and zero + otherwise. + + This function always succeeds. + + */ + + PyAPI_FUNC(Py_ssize_t) PySequence_Size(PyObject *o); + + /* + Return the size of sequence object o, or -1 on failure. + + */ + + /* For DLL compatibility */ +#undef PySequence_Length + PyAPI_FUNC(Py_ssize_t) PySequence_Length(PyObject *o); +#define PySequence_Length PySequence_Size + + + PyAPI_FUNC(PyObject *) PySequence_Concat(PyObject *o1, PyObject *o2); + + /* + Return the concatenation of o1 and o2 on success, and NULL on + failure. This is the equivalent of the Python + expression: o1+o2. + + */ + + PyAPI_FUNC(PyObject *) PySequence_Repeat(PyObject *o, Py_ssize_t count); + + /* + Return the result of repeating sequence object o count times, + or NULL on failure. This is the equivalent of the Python + expression: o1*count. + + */ + + PyAPI_FUNC(PyObject *) PySequence_GetItem(PyObject *o, Py_ssize_t i); + + /* + Return the ith element of o, or NULL on failure. This is the + equivalent of the Python expression: o[i]. + */ + + PyAPI_FUNC(PyObject *) PySequence_GetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2); + + /* + Return the slice of sequence object o between i1 and i2, or + NULL on failure. This is the equivalent of the Python + expression: o[i1:i2]. + + */ + + PyAPI_FUNC(int) PySequence_SetItem(PyObject *o, Py_ssize_t i, PyObject *v); + + /* + Assign object v to the ith element of o. Returns + -1 on failure. This is the equivalent of the Python + statement: o[i]=v. + + */ + + PyAPI_FUNC(int) PySequence_DelItem(PyObject *o, Py_ssize_t i); + + /* + Delete the ith element of object v. Returns + -1 on failure. This is the equivalent of the Python + statement: del o[i]. + */ + + PyAPI_FUNC(int) PySequence_SetSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2, + PyObject *v); + + /* + Assign the sequence object, v, to the slice in sequence + object, o, from i1 to i2. Returns -1 on failure. This is the + equivalent of the Python statement: o[i1:i2]=v. + */ + + PyAPI_FUNC(int) PySequence_DelSlice(PyObject *o, Py_ssize_t i1, Py_ssize_t i2); + + /* + Delete the slice in sequence object, o, from i1 to i2. + Returns -1 on failure. This is the equivalent of the Python + statement: del o[i1:i2]. + */ + + PyAPI_FUNC(PyObject *) PySequence_Tuple(PyObject *o); + + /* + Returns the sequence, o, as a tuple on success, and NULL on failure. + This is equivalent to the Python expression: tuple(o) + */ + + + PyAPI_FUNC(PyObject *) PySequence_List(PyObject *o); + /* + Returns the sequence, o, as a list on success, and NULL on failure. + This is equivalent to the Python expression: list(o) + */ + + PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); + /* + Returns the sequence, o, as a tuple, unless it's already a + tuple or list. Use PySequence_Fast_GET_ITEM to access the + members of this list, and PySequence_Fast_GET_SIZE to get its length. + + Returns NULL on failure. If the object does not support iteration, + raises a TypeError exception with m as the message text. + */ + +#define PySequence_Fast_GET_SIZE(o) \ + (PyList_Check(o) ? PyList_GET_SIZE(o) : PyTuple_GET_SIZE(o)) + /* + Return the size of o, assuming that o was returned by + PySequence_Fast and is not NULL. + */ + +#define PySequence_Fast_GET_ITEM(o, i)\ + (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) + /* + Return the ith element of o, assuming that o was returned by + PySequence_Fast, and that i is within bounds. + */ + +#define PySequence_ITEM(o, i)\ + ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) ) + /* Assume tp_as_sequence and sq_item exist and that i does not + need to be corrected for a negative index + */ + +#define PySequence_Fast_ITEMS(sf) \ + (PyList_Check(sf) ? ((PyListObject *)(sf))->ob_item \ + : ((PyTupleObject *)(sf))->ob_item) + /* Return a pointer to the underlying item array for + an object retured by PySequence_Fast */ + + PyAPI_FUNC(Py_ssize_t) PySequence_Count(PyObject *o, PyObject *value); + + /* + Return the number of occurrences on value on o, that is, + return the number of keys for which o[key]==value. On + failure, return -1. This is equivalent to the Python + expression: o.count(value). + */ + + PyAPI_FUNC(int) PySequence_Contains(PyObject *seq, PyObject *ob); + /* + Return -1 if error; 1 if ob in seq; 0 if ob not in seq. + Use __contains__ if possible, else _PySequence_IterSearch(). + */ + +#define PY_ITERSEARCH_COUNT 1 +#define PY_ITERSEARCH_INDEX 2 +#define PY_ITERSEARCH_CONTAINS 3 + PyAPI_FUNC(Py_ssize_t) _PySequence_IterSearch(PyObject *seq, + PyObject *obj, int operation); + /* + Iterate over seq. Result depends on the operation: + PY_ITERSEARCH_COUNT: return # of times obj appears in seq; -1 if + error. + PY_ITERSEARCH_INDEX: return 0-based index of first occurrence of + obj in seq; set ValueError and return -1 if none found; + also return -1 on error. + PY_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on + error. + */ + +/* For DLL-level backwards compatibility */ +#undef PySequence_In + PyAPI_FUNC(int) PySequence_In(PyObject *o, PyObject *value); + +/* For source-level backwards compatibility */ +#define PySequence_In PySequence_Contains + + /* + Determine if o contains value. If an item in o is equal to + X, return 1, otherwise return 0. On error, return -1. This + is equivalent to the Python expression: value in o. + */ + + PyAPI_FUNC(Py_ssize_t) PySequence_Index(PyObject *o, PyObject *value); + + /* + Return the first index for which o[i]=value. On error, + return -1. This is equivalent to the Python + expression: o.index(value). + */ + +/* In-place versions of some of the above Sequence functions. */ + + PyAPI_FUNC(PyObject *) PySequence_InPlaceConcat(PyObject *o1, PyObject *o2); + + /* + Append o2 to o1, in-place when possible. Return the resulting + object, which could be o1, or NULL on failure. This is the + equivalent of the Python expression: o1 += o2. + + */ + + PyAPI_FUNC(PyObject *) PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count); + + /* + Repeat o1 by count, in-place when possible. Return the resulting + object, which could be o1, or NULL on failure. This is the + equivalent of the Python expression: o1 *= count. + + */ + +/* Mapping protocol:*/ + + PyAPI_FUNC(int) PyMapping_Check(PyObject *o); + + /* + Return 1 if the object provides mapping protocol, and zero + otherwise. + + This function always succeeds. + */ + + PyAPI_FUNC(Py_ssize_t) PyMapping_Size(PyObject *o); + + /* + Returns the number of keys in object o on success, and -1 on + failure. For objects that do not provide sequence protocol, + this is equivalent to the Python expression: len(o). + */ + + /* For DLL compatibility */ +#undef PyMapping_Length + PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o); +#define PyMapping_Length PyMapping_Size + + + /* implemented as a macro: + + int PyMapping_DelItemString(PyObject *o, char *key); + + Remove the mapping for object, key, from the object *o. + Returns -1 on failure. This is equivalent to + the Python statement: del o[key]. + */ +#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K)) + + /* implemented as a macro: + + int PyMapping_DelItem(PyObject *o, PyObject *key); + + Remove the mapping for object, key, from the object *o. + Returns -1 on failure. This is equivalent to + the Python statement: del o[key]. + */ +#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K)) + + PyAPI_FUNC(int) PyMapping_HasKeyString(PyObject *o, char *key); + + /* + On success, return 1 if the mapping object has the key, key, + and 0 otherwise. This is equivalent to the Python expression: + o.has_key(key). + + This function always succeeds. + */ + + PyAPI_FUNC(int) PyMapping_HasKey(PyObject *o, PyObject *key); + + /* + Return 1 if the mapping object has the key, key, + and 0 otherwise. This is equivalent to the Python expression: + o.has_key(key). + + This function always succeeds. + + */ + + /* Implemented as macro: + + PyObject *PyMapping_Keys(PyObject *o); + + On success, return a list of the keys in object o. On + failure, return NULL. This is equivalent to the Python + expression: o.keys(). + */ +#define PyMapping_Keys(O) PyObject_CallMethod(O,"keys",NULL) + + /* Implemented as macro: + + PyObject *PyMapping_Values(PyObject *o); + + On success, return a list of the values in object o. On + failure, return NULL. This is equivalent to the Python + expression: o.values(). + */ +#define PyMapping_Values(O) PyObject_CallMethod(O,"values",NULL) + + /* Implemented as macro: + + PyObject *PyMapping_Items(PyObject *o); + + On success, return a list of the items in object o, where + each item is a tuple containing a key-value pair. On + failure, return NULL. This is equivalent to the Python + expression: o.items(). + + */ +#define PyMapping_Items(O) PyObject_CallMethod(O,"items",NULL) + + PyAPI_FUNC(PyObject *) PyMapping_GetItemString(PyObject *o, char *key); + + /* + Return element of o corresponding to the object, key, or NULL + on failure. This is the equivalent of the Python expression: + o[key]. + */ + + PyAPI_FUNC(int) PyMapping_SetItemString(PyObject *o, char *key, + PyObject *value); + + /* + Map the object, key, to the value, v. Returns + -1 on failure. This is the equivalent of the Python + statement: o[key]=v. + */ + + +PyAPI_FUNC(int) PyObject_IsInstance(PyObject *object, PyObject *typeorclass); + /* isinstance(object, typeorclass) */ + +PyAPI_FUNC(int) PyObject_IsSubclass(PyObject *object, PyObject *typeorclass); + /* issubclass(object, typeorclass) */ + + +PyAPI_FUNC(int) _PyObject_RealIsInstance(PyObject *inst, PyObject *cls); + +PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls); + + +/* For internal use by buffer API functions */ +PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index, + const Py_ssize_t *shape); +PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index, + const Py_ssize_t *shape); + + +#ifdef __cplusplus +} +#endif +#endif /* Py_ABSTRACTOBJECT_H */ diff --git a/python/include/asdl.h b/python/include/asdl.h new file mode 100644 index 000000000..84e837e75 --- /dev/null +++ b/python/include/asdl.h @@ -0,0 +1,45 @@ +#ifndef Py_ASDL_H +#define Py_ASDL_H + +typedef PyObject * identifier; +typedef PyObject * string; +typedef PyObject * object; + +#ifndef __cplusplus +typedef enum {false, true} bool; +#endif + +/* It would be nice if the code generated by asdl_c.py was completely + independent of Python, but it is a goal the requires too much work + at this stage. So, for example, I'll represent identifiers as + interned Python strings. +*/ + +/* XXX A sequence should be typed so that its use can be typechecked. */ + +typedef struct { + int size; + void *elements[1]; +} asdl_seq; + +typedef struct { + int size; + int elements[1]; +} asdl_int_seq; + +asdl_seq *asdl_seq_new(int size, PyArena *arena); +asdl_int_seq *asdl_int_seq_new(int size, PyArena *arena); + +#define asdl_seq_GET(S, I) (S)->elements[(I)] +#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size) +#ifdef Py_DEBUG +#define asdl_seq_SET(S, I, V) { \ + int _asdl_i = (I); \ + assert((S) && _asdl_i < (S)->size); \ + (S)->elements[_asdl_i] = (V); \ +} +#else +#define asdl_seq_SET(S, I, V) (S)->elements[I] = (V) +#endif + +#endif /* !Py_ASDL_H */ diff --git a/python/include/ast.h b/python/include/ast.h new file mode 100644 index 000000000..cc14b7fd7 --- /dev/null +++ b/python/include/ast.h @@ -0,0 +1,13 @@ +#ifndef Py_AST_H +#define Py_AST_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(mod_ty) PyAST_FromNode(const node *, PyCompilerFlags *flags, + const char *, PyArena *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_AST_H */ diff --git a/python/include/bitset.h b/python/include/bitset.h new file mode 100644 index 000000000..faeb41913 --- /dev/null +++ b/python/include/bitset.h @@ -0,0 +1,32 @@ + +#ifndef Py_BITSET_H +#define Py_BITSET_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Bitset interface */ + +#define BYTE char + +typedef BYTE *bitset; + +bitset newbitset(int nbits); +void delbitset(bitset bs); +#define testbit(ss, ibit) (((ss)[BIT2BYTE(ibit)] & BIT2MASK(ibit)) != 0) +int addbit(bitset bs, int ibit); /* Returns 0 if already set */ +int samebitset(bitset bs1, bitset bs2, int nbits); +void mergebitset(bitset bs1, bitset bs2, int nbits); + +#define BITSPERBYTE (8*sizeof(BYTE)) +#define NBYTES(nbits) (((nbits) + BITSPERBYTE - 1) / BITSPERBYTE) + +#define BIT2BYTE(ibit) ((ibit) / BITSPERBYTE) +#define BIT2SHIFT(ibit) ((ibit) % BITSPERBYTE) +#define BIT2MASK(ibit) (1 << BIT2SHIFT(ibit)) +#define BYTE2BIT(ibyte) ((ibyte) * BITSPERBYTE) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BITSET_H */ diff --git a/python/include/boolobject.h b/python/include/boolobject.h new file mode 100644 index 000000000..74e854f70 --- /dev/null +++ b/python/include/boolobject.h @@ -0,0 +1,36 @@ +/* Boolean object interface */ + +#ifndef Py_BOOLOBJECT_H +#define Py_BOOLOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +typedef PyIntObject PyBoolObject; + +PyAPI_DATA(PyTypeObject) PyBool_Type; + +#define PyBool_Check(x) (Py_TYPE(x) == &PyBool_Type) + +/* Py_False and Py_True are the only two bools in existence. +Don't forget to apply Py_INCREF() when returning either!!! */ + +/* Don't use these directly */ +PyAPI_DATA(PyIntObject) _Py_ZeroStruct, _Py_TrueStruct; + +/* Use these macros */ +#define Py_False ((PyObject *) &_Py_ZeroStruct) +#define Py_True ((PyObject *) &_Py_TrueStruct) + +/* Macros for returning Py_True or Py_False, respectively */ +#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True +#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False + +/* Function to return a bool from a C long */ +PyAPI_FUNC(PyObject *) PyBool_FromLong(long); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BOOLOBJECT_H */ diff --git a/python/include/bufferobject.h b/python/include/bufferobject.h new file mode 100644 index 000000000..6dd83458c --- /dev/null +++ b/python/include/bufferobject.h @@ -0,0 +1,33 @@ + +/* Buffer object interface */ + +/* Note: the object's structure is private */ + +#ifndef Py_BUFFEROBJECT_H +#define Py_BUFFEROBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +PyAPI_DATA(PyTypeObject) PyBuffer_Type; + +#define PyBuffer_Check(op) (Py_TYPE(op) == &PyBuffer_Type) + +#define Py_END_OF_BUFFER (-1) + +PyAPI_FUNC(PyObject *) PyBuffer_FromObject(PyObject *base, + Py_ssize_t offset, Py_ssize_t size); +PyAPI_FUNC(PyObject *) PyBuffer_FromReadWriteObject(PyObject *base, + Py_ssize_t offset, + Py_ssize_t size); + +PyAPI_FUNC(PyObject *) PyBuffer_FromMemory(void *ptr, Py_ssize_t size); +PyAPI_FUNC(PyObject *) PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size); + +PyAPI_FUNC(PyObject *) PyBuffer_New(Py_ssize_t size); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BUFFEROBJECT_H */ diff --git a/python/include/bytearrayobject.h b/python/include/bytearrayobject.h new file mode 100644 index 000000000..e1281a628 --- /dev/null +++ b/python/include/bytearrayobject.h @@ -0,0 +1,57 @@ +/* ByteArray object interface */ + +#ifndef Py_BYTEARRAYOBJECT_H +#define Py_BYTEARRAYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Type PyByteArrayObject represents a mutable array of bytes. + * The Python API is that of a sequence; + * the bytes are mapped to ints in [0, 256). + * Bytes are not characters; they may be used to encode characters. + * The only way to go between bytes and str/unicode is via encoding + * and decoding. + * For the convenience of C programmers, the bytes type is considered + * to contain a char pointer, not an unsigned char pointer. + */ + +/* Object layout */ +typedef struct { + PyObject_VAR_HEAD + /* XXX(nnorwitz): should ob_exports be Py_ssize_t? */ + int ob_exports; /* how many buffer exports */ + Py_ssize_t ob_alloc; /* How many bytes allocated */ + char *ob_bytes; +} PyByteArrayObject; + +/* Type object */ +PyAPI_DATA(PyTypeObject) PyByteArray_Type; +PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type; + +/* Type check macros */ +#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type) +#define PyByteArray_CheckExact(self) (Py_TYPE(self) == &PyByteArray_Type) + +/* Direct API functions */ +PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *); +PyAPI_FUNC(PyObject *) PyByteArray_Concat(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyByteArray_FromStringAndSize(const char *, Py_ssize_t); +PyAPI_FUNC(Py_ssize_t) PyByteArray_Size(PyObject *); +PyAPI_FUNC(char *) PyByteArray_AsString(PyObject *); +PyAPI_FUNC(int) PyByteArray_Resize(PyObject *, Py_ssize_t); + +/* Macros, trading safety for speed */ +#define PyByteArray_AS_STRING(self) \ + (assert(PyByteArray_Check(self)), \ + Py_SIZE(self) ? ((PyByteArrayObject *)(self))->ob_bytes : _PyByteArray_empty_string) +#define PyByteArray_GET_SIZE(self) (assert(PyByteArray_Check(self)),Py_SIZE(self)) + +PyAPI_DATA(char) _PyByteArray_empty_string[]; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_BYTEARRAYOBJECT_H */ diff --git a/python/include/bytes_methods.h b/python/include/bytes_methods.h new file mode 100644 index 000000000..412566621 --- /dev/null +++ b/python/include/bytes_methods.h @@ -0,0 +1,75 @@ +#ifndef Py_BYTES_CTYPE_H +#define Py_BYTES_CTYPE_H + +/* + * The internal implementation behind PyString (bytes) and PyBytes (buffer) + * methods of the given names, they operate on ASCII byte strings. + */ +extern PyObject* _Py_bytes_isspace(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isalpha(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isalnum(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isdigit(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_islower(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_isupper(const char *cptr, Py_ssize_t len); +extern PyObject* _Py_bytes_istitle(const char *cptr, Py_ssize_t len); + +/* These store their len sized answer in the given preallocated *result arg. */ +extern void _Py_bytes_lower(char *result, const char *cptr, Py_ssize_t len); +extern void _Py_bytes_upper(char *result, const char *cptr, Py_ssize_t len); +extern void _Py_bytes_title(char *result, char *s, Py_ssize_t len); +extern void _Py_bytes_capitalize(char *result, char *s, Py_ssize_t len); +extern void _Py_bytes_swapcase(char *result, char *s, Py_ssize_t len); + +/* Shared __doc__ strings. */ +extern const char _Py_isspace__doc__[]; +extern const char _Py_isalpha__doc__[]; +extern const char _Py_isalnum__doc__[]; +extern const char _Py_isdigit__doc__[]; +extern const char _Py_islower__doc__[]; +extern const char _Py_isupper__doc__[]; +extern const char _Py_istitle__doc__[]; +extern const char _Py_lower__doc__[]; +extern const char _Py_upper__doc__[]; +extern const char _Py_title__doc__[]; +extern const char _Py_capitalize__doc__[]; +extern const char _Py_swapcase__doc__[]; + +/* These are left in for backward compatibility and will be removed + in 2.8/3.2 */ +#define ISLOWER(c) Py_ISLOWER(c) +#define ISUPPER(c) Py_ISUPPER(c) +#define ISALPHA(c) Py_ISALPHA(c) +#define ISDIGIT(c) Py_ISDIGIT(c) +#define ISXDIGIT(c) Py_ISXDIGIT(c) +#define ISALNUM(c) Py_ISALNUM(c) +#define ISSPACE(c) Py_ISSPACE(c) + +#undef islower +#define islower(c) undefined_islower(c) +#undef isupper +#define isupper(c) undefined_isupper(c) +#undef isalpha +#define isalpha(c) undefined_isalpha(c) +#undef isdigit +#define isdigit(c) undefined_isdigit(c) +#undef isxdigit +#define isxdigit(c) undefined_isxdigit(c) +#undef isalnum +#define isalnum(c) undefined_isalnum(c) +#undef isspace +#define isspace(c) undefined_isspace(c) + +/* These are left in for backward compatibility and will be removed + in 2.8/3.2 */ +#define TOLOWER(c) Py_TOLOWER(c) +#define TOUPPER(c) Py_TOUPPER(c) + +#undef tolower +#define tolower(c) undefined_tolower(c) +#undef toupper +#define toupper(c) undefined_toupper(c) + +/* this is needed because some docs are shared from the .o, not static */ +#define PyDoc_STRVAR_shared(name,str) const char name[] = PyDoc_STR(str) + +#endif /* !Py_BYTES_CTYPE_H */ diff --git a/python/include/bytesobject.h b/python/include/bytesobject.h new file mode 100644 index 000000000..1083da9c8 --- /dev/null +++ b/python/include/bytesobject.h @@ -0,0 +1,27 @@ +#define PyBytesObject PyStringObject +#define PyBytes_Type PyString_Type + +#define PyBytes_Check PyString_Check +#define PyBytes_CheckExact PyString_CheckExact +#define PyBytes_CHECK_INTERNED PyString_CHECK_INTERNED +#define PyBytes_AS_STRING PyString_AS_STRING +#define PyBytes_GET_SIZE PyString_GET_SIZE +#define Py_TPFLAGS_BYTES_SUBCLASS Py_TPFLAGS_STRING_SUBCLASS + +#define PyBytes_FromStringAndSize PyString_FromStringAndSize +#define PyBytes_FromString PyString_FromString +#define PyBytes_FromFormatV PyString_FromFormatV +#define PyBytes_FromFormat PyString_FromFormat +#define PyBytes_Size PyString_Size +#define PyBytes_AsString PyString_AsString +#define PyBytes_Repr PyString_Repr +#define PyBytes_Concat PyString_Concat +#define PyBytes_ConcatAndDel PyString_ConcatAndDel +#define _PyBytes_Resize _PyString_Resize +#define _PyBytes_Eq _PyString_Eq +#define PyBytes_Format PyString_Format +#define _PyBytes_FormatLong _PyString_FormatLong +#define PyBytes_DecodeEscape PyString_DecodeEscape +#define _PyBytes_Join _PyString_Join +#define PyBytes_AsStringAndSize PyString_AsStringAndSize +#define _PyBytes_InsertThousandsGrouping _PyString_InsertThousandsGrouping diff --git a/python/include/cStringIO.h b/python/include/cStringIO.h new file mode 100644 index 000000000..6ca44a830 --- /dev/null +++ b/python/include/cStringIO.h @@ -0,0 +1,73 @@ +#ifndef Py_CSTRINGIO_H +#define Py_CSTRINGIO_H +#ifdef __cplusplus +extern "C" { +#endif +/* + + This header provides access to cStringIO objects from C. + Functions are provided for calling cStringIO objects and + macros are provided for testing whether you have cStringIO + objects. + + Before calling any of the functions or macros, you must initialize + the routines with: + + PycString_IMPORT + + This would typically be done in your init function. + +*/ + +#define PycStringIO_CAPSULE_NAME "cStringIO.cStringIO_CAPI" + +#define PycString_IMPORT \ + PycStringIO = ((struct PycStringIO_CAPI*)PyCapsule_Import(\ + PycStringIO_CAPSULE_NAME, 0)) + +/* Basic functions to manipulate cStringIO objects from C */ + +static struct PycStringIO_CAPI { + + /* Read a string from an input object. If the last argument + is -1, the remainder will be read. + */ + int(*cread)(PyObject *, char **, Py_ssize_t); + + /* Read a line from an input object. Returns the length of the read + line as an int and a pointer inside the object buffer as char** (so + the caller doesn't have to provide its own buffer as destination). + */ + int(*creadline)(PyObject *, char **); + + /* Write a string to an output object*/ + int(*cwrite)(PyObject *, const char *, Py_ssize_t); + + /* Get the output object as a Python string (returns new reference). */ + PyObject *(*cgetvalue)(PyObject *); + + /* Create a new output object */ + PyObject *(*NewOutput)(int); + + /* Create an input object from a Python string + (copies the Python string reference). + */ + PyObject *(*NewInput)(PyObject *); + + /* The Python types for cStringIO input and output objects. + Note that you can do input on an output object. + */ + PyTypeObject *InputType, *OutputType; + +} *PycStringIO; + +/* These can be used to test if you have one */ +#define PycStringIO_InputCheck(O) \ + (Py_TYPE(O)==PycStringIO->InputType) +#define PycStringIO_OutputCheck(O) \ + (Py_TYPE(O)==PycStringIO->OutputType) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CSTRINGIO_H */ diff --git a/python/include/cellobject.h b/python/include/cellobject.h new file mode 100644 index 000000000..c927ee5da --- /dev/null +++ b/python/include/cellobject.h @@ -0,0 +1,28 @@ +/* Cell object interface */ + +#ifndef Py_CELLOBJECT_H +#define Py_CELLOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + PyObject *ob_ref; /* Content of the cell or NULL when empty */ +} PyCellObject; + +PyAPI_DATA(PyTypeObject) PyCell_Type; + +#define PyCell_Check(op) (Py_TYPE(op) == &PyCell_Type) + +PyAPI_FUNC(PyObject *) PyCell_New(PyObject *); +PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *); +PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *); + +#define PyCell_GET(op) (((PyCellObject *)(op))->ob_ref) +#define PyCell_SET(op, v) (((PyCellObject *)(op))->ob_ref = v) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TUPLEOBJECT_H */ diff --git a/python/include/ceval.h b/python/include/ceval.h new file mode 100644 index 000000000..0e8bd2ab1 --- /dev/null +++ b/python/include/ceval.h @@ -0,0 +1,153 @@ +#ifndef Py_CEVAL_H +#define Py_CEVAL_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Interface to random parts in ceval.c */ + +PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( + PyObject *, PyObject *, PyObject *); + +/* Inline this */ +#define PyEval_CallObject(func,arg) \ + PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL) + +PyAPI_FUNC(PyObject *) PyEval_CallFunction(PyObject *obj, + const char *format, ...); +PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj, + const char *methodname, + const char *format, ...); + +PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); + +struct _frame; /* Avoid including frameobject.h */ + +PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void); +PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void); +PyAPI_FUNC(PyObject *) PyEval_GetLocals(void); +PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void); +PyAPI_FUNC(int) PyEval_GetRestricted(void); + +/* Look at the current frame's (if any) code's co_flags, and turn on + the corresponding compiler flags in cf->cf_flags. Return 1 if any + flag was set, else return 0. */ +PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); + +PyAPI_FUNC(int) Py_FlushLine(void); + +PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg); +PyAPI_FUNC(int) Py_MakePendingCalls(void); + +/* Protection against deeply nested recursive calls */ +PyAPI_FUNC(void) Py_SetRecursionLimit(int); +PyAPI_FUNC(int) Py_GetRecursionLimit(void); + +#define Py_EnterRecursiveCall(where) \ + (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ + _Py_CheckRecursiveCall(where)) +#define Py_LeaveRecursiveCall() \ + (--PyThreadState_GET()->recursion_depth) +PyAPI_FUNC(int) _Py_CheckRecursiveCall(char *where); +PyAPI_DATA(int) _Py_CheckRecursionLimit; +#ifdef USE_STACKCHECK +# define _Py_MakeRecCheck(x) (++(x) > --_Py_CheckRecursionLimit) +#else +# define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit) +#endif + +PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); +PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); + +PyAPI_FUNC(PyObject *) PyEval_GetCallStats(PyObject *); +PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *); +PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc); + +/* this used to be handled on a per-thread basis - now just two globals */ +PyAPI_DATA(volatile int) _Py_Ticker; +PyAPI_DATA(int) _Py_CheckInterval; + +/* Interface for threads. + + A module that plans to do a blocking system call (or something else + that lasts a long time and doesn't touch Python data) can allow other + threads to run as follows: + + ...preparations here... + Py_BEGIN_ALLOW_THREADS + ...blocking system call here... + Py_END_ALLOW_THREADS + ...interpret result here... + + The Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS pair expands to a + {}-surrounded block. + To leave the block in the middle (e.g., with return), you must insert + a line containing Py_BLOCK_THREADS before the return, e.g. + + if (...premature_exit...) { + Py_BLOCK_THREADS + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + + An alternative is: + + Py_BLOCK_THREADS + if (...premature_exit...) { + PyErr_SetFromErrno(PyExc_IOError); + return NULL; + } + Py_UNBLOCK_THREADS + + For convenience, that the value of 'errno' is restored across + Py_END_ALLOW_THREADS and Py_BLOCK_THREADS. + + WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND + Py_END_ALLOW_THREADS!!! + + The function PyEval_InitThreads() should be called only from + initthread() in "threadmodule.c". + + Note that not yet all candidates have been converted to use this + mechanism! +*/ + +PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void); +PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); + +#ifdef WITH_THREAD + +PyAPI_FUNC(int) PyEval_ThreadsInitialized(void); +PyAPI_FUNC(void) PyEval_InitThreads(void); +PyAPI_FUNC(void) PyEval_AcquireLock(void); +PyAPI_FUNC(void) PyEval_ReleaseLock(void); +PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); +PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); +PyAPI_FUNC(void) PyEval_ReInitThreads(void); + +#define Py_BEGIN_ALLOW_THREADS { \ + PyThreadState *_save; \ + _save = PyEval_SaveThread(); +#define Py_BLOCK_THREADS PyEval_RestoreThread(_save); +#define Py_UNBLOCK_THREADS _save = PyEval_SaveThread(); +#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ + } + +#else /* !WITH_THREAD */ + +#define Py_BEGIN_ALLOW_THREADS { +#define Py_BLOCK_THREADS +#define Py_UNBLOCK_THREADS +#define Py_END_ALLOW_THREADS } + +#endif /* !WITH_THREAD */ + +PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CEVAL_H */ diff --git a/python/include/classobject.h b/python/include/classobject.h new file mode 100644 index 000000000..bc03e0d02 --- /dev/null +++ b/python/include/classobject.h @@ -0,0 +1,83 @@ + +/* Class object interface */ + +/* Revealing some structures (not for general use) */ + +#ifndef Py_CLASSOBJECT_H +#define Py_CLASSOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + PyObject *cl_bases; /* A tuple of class objects */ + PyObject *cl_dict; /* A dictionary */ + PyObject *cl_name; /* A string */ + /* The following three are functions or NULL */ + PyObject *cl_getattr; + PyObject *cl_setattr; + PyObject *cl_delattr; + PyObject *cl_weakreflist; /* List of weak references */ +} PyClassObject; + +typedef struct { + PyObject_HEAD + PyClassObject *in_class; /* The class object */ + PyObject *in_dict; /* A dictionary */ + PyObject *in_weakreflist; /* List of weak references */ +} PyInstanceObject; + +typedef struct { + PyObject_HEAD + PyObject *im_func; /* The callable object implementing the method */ + PyObject *im_self; /* The instance it is bound to, or NULL */ + PyObject *im_class; /* The class that asked for the method */ + PyObject *im_weakreflist; /* List of weak references */ +} PyMethodObject; + +PyAPI_DATA(PyTypeObject) PyClass_Type, PyInstance_Type, PyMethod_Type; + +#define PyClass_Check(op) ((op)->ob_type == &PyClass_Type) +#define PyInstance_Check(op) ((op)->ob_type == &PyInstance_Type) +#define PyMethod_Check(op) ((op)->ob_type == &PyMethod_Type) + +PyAPI_FUNC(PyObject *) PyClass_New(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyInstance_New(PyObject *, PyObject *, + PyObject *); +PyAPI_FUNC(PyObject *) PyInstance_NewRaw(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *); +PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *); +PyAPI_FUNC(PyObject *) PyMethod_Class(PyObject *); + +/* Look up attribute with name (a string) on instance object pinst, using + * only the instance and base class dicts. If a descriptor is found in + * a class dict, the descriptor is returned without calling it. + * Returns NULL if nothing found, else a borrowed reference to the + * value associated with name in the dict in which name was found. + * The point of this routine is that it never calls arbitrary Python + * code, so is always "safe": all it does is dict lookups. The function + * can't fail, never sets an exception, and NULL is not an error (it just + * means "not found"). + */ +PyAPI_FUNC(PyObject *) _PyInstance_Lookup(PyObject *pinst, PyObject *name); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyMethod_GET_FUNCTION(meth) \ + (((PyMethodObject *)meth) -> im_func) +#define PyMethod_GET_SELF(meth) \ + (((PyMethodObject *)meth) -> im_self) +#define PyMethod_GET_CLASS(meth) \ + (((PyMethodObject *)meth) -> im_class) + +PyAPI_FUNC(int) PyClass_IsSubclass(PyObject *, PyObject *); + +PyAPI_FUNC(int) PyMethod_ClearFreeList(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CLASSOBJECT_H */ diff --git a/python/include/cobject.h b/python/include/cobject.h new file mode 100644 index 000000000..ad3cd9c98 --- /dev/null +++ b/python/include/cobject.h @@ -0,0 +1,89 @@ +/* + CObjects are marked Pending Deprecation as of Python 2.7. + The full schedule for 2.x is as follows: + - CObjects are marked Pending Deprecation in Python 2.7. + - CObjects will be marked Deprecated in Python 2.8 + (if there is one). + - CObjects will be removed in Python 2.9 (if there is one). + + Additionally, for the Python 3.x series: + - CObjects were marked Deprecated in Python 3.1. + - CObjects will be removed in Python 3.2. + + You should switch all use of CObjects to capsules. Capsules + have a safer and more consistent API. For more information, + see Include/pycapsule.h, or read the "Capsules" topic in + the "Python/C API Reference Manual". + + Python 2.7 no longer uses CObjects itself; all objects which + were formerly CObjects are now capsules. Note that this change + does not by itself break binary compatibility with extensions + built for previous versions of Python--PyCObject_AsVoidPtr() + has been changed to also understand capsules. + +*/ + +/* original file header comment follows: */ + +/* C objects to be exported from one extension module to another. + + C objects are used for communication between extension modules. + They provide a way for an extension module to export a C interface + to other extension modules, so that extension modules can use the + Python import mechanism to link to one another. + +*/ + +#ifndef Py_COBJECT_H +#define Py_COBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyCObject_Type; + +#define PyCObject_Check(op) (Py_TYPE(op) == &PyCObject_Type) + +/* Create a PyCObject from a pointer to a C object and an optional + destructor function. If the second argument is non-null, then it + will be called with the first argument if and when the PyCObject is + destroyed. + +*/ +PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtr( + void *cobj, void (*destruct)(void*)); + + +/* Create a PyCObject from a pointer to a C object, a description object, + and an optional destructor function. If the third argument is non-null, + then it will be called with the first and second arguments if and when + the PyCObject is destroyed. +*/ +PyAPI_FUNC(PyObject *) PyCObject_FromVoidPtrAndDesc( + void *cobj, void *desc, void (*destruct)(void*,void*)); + +/* Retrieve a pointer to a C object from a PyCObject. */ +PyAPI_FUNC(void *) PyCObject_AsVoidPtr(PyObject *); + +/* Retrieve a pointer to a description object from a PyCObject. */ +PyAPI_FUNC(void *) PyCObject_GetDesc(PyObject *); + +/* Import a pointer to a C object from a module using a PyCObject. */ +PyAPI_FUNC(void *) PyCObject_Import(char *module_name, char *cobject_name); + +/* Modify a C object. Fails (==0) if object has a destructor. */ +PyAPI_FUNC(int) PyCObject_SetVoidPtr(PyObject *self, void *cobj); + + +typedef struct { + PyObject_HEAD + void *cobject; + void *desc; + void (*destructor)(void *); +} PyCObject; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_COBJECT_H */ diff --git a/python/include/code.h b/python/include/code.h new file mode 100644 index 000000000..38b295804 --- /dev/null +++ b/python/include/code.h @@ -0,0 +1,107 @@ +/* Definitions for bytecode */ + +#ifndef Py_CODE_H +#define Py_CODE_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Bytecode object */ +typedef struct { + PyObject_HEAD + int co_argcount; /* #arguments, except *args */ + int co_nlocals; /* #local variables */ + int co_stacksize; /* #entries needed for evaluation stack */ + int co_flags; /* CO_..., see below */ + PyObject *co_code; /* instruction opcodes */ + PyObject *co_consts; /* list (constants used) */ + PyObject *co_names; /* list of strings (names used) */ + PyObject *co_varnames; /* tuple of strings (local variable names) */ + PyObject *co_freevars; /* tuple of strings (free variable names) */ + PyObject *co_cellvars; /* tuple of strings (cell variable names) */ + /* The rest doesn't count for hash/cmp */ + PyObject *co_filename; /* string (where it was loaded from) */ + PyObject *co_name; /* string (name, for reference) */ + int co_firstlineno; /* first source line number */ + PyObject *co_lnotab; /* string (encoding addr<->lineno mapping) See + Objects/lnotab_notes.txt for details. */ + void *co_zombieframe; /* for optimization only (see frameobject.c) */ + PyObject *co_weakreflist; /* to support weakrefs to code objects */ +} PyCodeObject; + +/* Masks for co_flags above */ +#define CO_OPTIMIZED 0x0001 +#define CO_NEWLOCALS 0x0002 +#define CO_VARARGS 0x0004 +#define CO_VARKEYWORDS 0x0008 +#define CO_NESTED 0x0010 +#define CO_GENERATOR 0x0020 +/* The CO_NOFREE flag is set if there are no free or cell variables. + This information is redundant, but it allows a single flag test + to determine whether there is any extra work to be done when the + call frame it setup. +*/ +#define CO_NOFREE 0x0040 + +#if 0 +/* This is no longer used. Stopped defining in 2.5, do not re-use. */ +#define CO_GENERATOR_ALLOWED 0x1000 +#endif +#define CO_FUTURE_DIVISION 0x2000 +#define CO_FUTURE_ABSOLUTE_IMPORT 0x4000 /* do absolute imports by default */ +#define CO_FUTURE_WITH_STATEMENT 0x8000 +#define CO_FUTURE_PRINT_FUNCTION 0x10000 +#define CO_FUTURE_UNICODE_LITERALS 0x20000 + +/* This should be defined if a future statement modifies the syntax. + For example, when a keyword is added. +*/ +#if 1 +#define PY_PARSER_REQUIRES_FUTURE_KEYWORD +#endif + +#define CO_MAXBLOCKS 20 /* Max static block nesting within a function */ + +PyAPI_DATA(PyTypeObject) PyCode_Type; + +#define PyCode_Check(op) (Py_TYPE(op) == &PyCode_Type) +#define PyCode_GetNumFree(op) (PyTuple_GET_SIZE((op)->co_freevars)) + +/* Public interface */ +PyAPI_FUNC(PyCodeObject *) PyCode_New( + int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *, + PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *); + /* same as struct above */ + +/* Creates a new empty code object with the specified source location. */ +PyAPI_FUNC(PyCodeObject *) +PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno); + +/* Return the line number associated with the specified bytecode index + in this code object. If you just need the line number of a frame, + use PyFrame_GetLineNumber() instead. */ +PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int); + +/* for internal use only */ +#define _PyCode_GETCODEPTR(co, pp) \ + ((*Py_TYPE((co)->co_code)->tp_as_buffer->bf_getreadbuffer) \ + ((co)->co_code, 0, (void **)(pp))) + +typedef struct _addr_pair { + int ap_lower; + int ap_upper; +} PyAddrPair; + +/* Update *bounds to describe the first and one-past-the-last instructions in the + same line as lasti. Return the number of that line. +*/ +PyAPI_FUNC(int) _PyCode_CheckLineNumber(PyCodeObject* co, + int lasti, PyAddrPair *bounds); + +PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts, + PyObject *names, PyObject *lineno_obj); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CODE_H */ diff --git a/python/include/codecs.h b/python/include/codecs.h new file mode 100644 index 000000000..c038c6a92 --- /dev/null +++ b/python/include/codecs.h @@ -0,0 +1,167 @@ +#ifndef Py_CODECREGISTRY_H +#define Py_CODECREGISTRY_H +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------------------------------------------------------ + + Python Codec Registry and support functions + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +Copyright (c) Corporation for National Research Initiatives. + + ------------------------------------------------------------------------ */ + +/* Register a new codec search function. + + As side effect, this tries to load the encodings package, if not + yet done, to make sure that it is always first in the list of + search functions. + + The search_function's refcount is incremented by this function. */ + +PyAPI_FUNC(int) PyCodec_Register( + PyObject *search_function + ); + +/* Codec register lookup API. + + Looks up the given encoding and returns a CodecInfo object with + function attributes which implement the different aspects of + processing the encoding. + + The encoding string is looked up converted to all lower-case + characters. This makes encodings looked up through this mechanism + effectively case-insensitive. + + If no codec is found, a KeyError is set and NULL returned. + + As side effect, this tries to load the encodings package, if not + yet done. This is part of the lazy load strategy for the encodings + package. + + */ + +PyAPI_FUNC(PyObject *) _PyCodec_Lookup( + const char *encoding + ); + +/* Generic codec based encoding API. + + object is passed through the encoder function found for the given + encoding using the error handling method defined by errors. errors + may be NULL to use the default method defined for the codec. + + Raises a LookupError in case no encoder can be found. + + */ + +PyAPI_FUNC(PyObject *) PyCodec_Encode( + PyObject *object, + const char *encoding, + const char *errors + ); + +/* Generic codec based decoding API. + + object is passed through the decoder function found for the given + encoding using the error handling method defined by errors. errors + may be NULL to use the default method defined for the codec. + + Raises a LookupError in case no encoder can be found. + + */ + +PyAPI_FUNC(PyObject *) PyCodec_Decode( + PyObject *object, + const char *encoding, + const char *errors + ); + +/* --- Codec Lookup APIs -------------------------------------------------- + + All APIs return a codec object with incremented refcount and are + based on _PyCodec_Lookup(). The same comments w/r to the encoding + name also apply to these APIs. + +*/ + +/* Get an encoder function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_Encoder( + const char *encoding + ); + +/* Get a decoder function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_Decoder( + const char *encoding + ); + +/* Get a IncrementalEncoder object for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder( + const char *encoding, + const char *errors + ); + +/* Get a IncrementalDecoder object function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder( + const char *encoding, + const char *errors + ); + +/* Get a StreamReader factory function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_StreamReader( + const char *encoding, + PyObject *stream, + const char *errors + ); + +/* Get a StreamWriter factory function for the given encoding. */ + +PyAPI_FUNC(PyObject *) PyCodec_StreamWriter( + const char *encoding, + PyObject *stream, + const char *errors + ); + +/* Unicode encoding error handling callback registry API */ + +/* Register the error handling callback function error under the given + name. This function will be called by the codec when it encounters + unencodable characters/undecodable bytes and doesn't know the + callback name, when name is specified as the error parameter + in the call to the encode/decode function. + Return 0 on success, -1 on error */ +PyAPI_FUNC(int) PyCodec_RegisterError(const char *name, PyObject *error); + +/* Lookup the error handling callback function registered under the given + name. As a special case NULL can be passed, in which case + the error handling callback for "strict" will be returned. */ +PyAPI_FUNC(PyObject *) PyCodec_LookupError(const char *name); + +/* raise exc as an exception */ +PyAPI_FUNC(PyObject *) PyCodec_StrictErrors(PyObject *exc); + +/* ignore the unicode error, skipping the faulty input */ +PyAPI_FUNC(PyObject *) PyCodec_IgnoreErrors(PyObject *exc); + +/* replace the unicode encode error with ? or U+FFFD */ +PyAPI_FUNC(PyObject *) PyCodec_ReplaceErrors(PyObject *exc); + +/* replace the unicode encode error with XML character references */ +PyAPI_FUNC(PyObject *) PyCodec_XMLCharRefReplaceErrors(PyObject *exc); + +/* replace the unicode encode error with backslash escapes (\x, \u and \U) */ +PyAPI_FUNC(PyObject *) PyCodec_BackslashReplaceErrors(PyObject *exc); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CODECREGISTRY_H */ diff --git a/python/include/compile.h b/python/include/compile.h new file mode 100644 index 000000000..61001016a --- /dev/null +++ b/python/include/compile.h @@ -0,0 +1,40 @@ + +#ifndef Py_COMPILE_H +#define Py_COMPILE_H + +#include "code.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Public interface */ +struct _node; /* Declare the existence of this type */ +PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *); + +/* Future feature support */ + +typedef struct { + int ff_features; /* flags set by future statements */ + int ff_lineno; /* line number of last future statement */ +} PyFutureFeatures; + +#define FUTURE_NESTED_SCOPES "nested_scopes" +#define FUTURE_GENERATORS "generators" +#define FUTURE_DIVISION "division" +#define FUTURE_ABSOLUTE_IMPORT "absolute_import" +#define FUTURE_WITH_STATEMENT "with_statement" +#define FUTURE_PRINT_FUNCTION "print_function" +#define FUTURE_UNICODE_LITERALS "unicode_literals" + + +struct _mod; /* Declare the existence of this type */ +PyAPI_FUNC(PyCodeObject *) PyAST_Compile(struct _mod *, const char *, + PyCompilerFlags *, PyArena *); +PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST(struct _mod *, const char *); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_COMPILE_H */ diff --git a/python/include/complexobject.h b/python/include/complexobject.h new file mode 100644 index 000000000..c9a9500fd --- /dev/null +++ b/python/include/complexobject.h @@ -0,0 +1,66 @@ +/* Complex number structure */ + +#ifndef Py_COMPLEXOBJECT_H +#define Py_COMPLEXOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + double real; + double imag; +} Py_complex; + +/* Operations on complex numbers from complexmodule.c */ + +#define c_sum _Py_c_sum +#define c_diff _Py_c_diff +#define c_neg _Py_c_neg +#define c_prod _Py_c_prod +#define c_quot _Py_c_quot +#define c_pow _Py_c_pow +#define c_abs _Py_c_abs + +PyAPI_FUNC(Py_complex) c_sum(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) c_diff(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) c_neg(Py_complex); +PyAPI_FUNC(Py_complex) c_prod(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) c_quot(Py_complex, Py_complex); +PyAPI_FUNC(Py_complex) c_pow(Py_complex, Py_complex); +PyAPI_FUNC(double) c_abs(Py_complex); + + +/* Complex object interface */ + +/* +PyComplexObject represents a complex number with double-precision +real and imaginary parts. +*/ + +typedef struct { + PyObject_HEAD + Py_complex cval; +} PyComplexObject; + +PyAPI_DATA(PyTypeObject) PyComplex_Type; + +#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) +#define PyComplex_CheckExact(op) (Py_TYPE(op) == &PyComplex_Type) + +PyAPI_FUNC(PyObject *) PyComplex_FromCComplex(Py_complex); +PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag); + +PyAPI_FUNC(double) PyComplex_RealAsDouble(PyObject *op); +PyAPI_FUNC(double) PyComplex_ImagAsDouble(PyObject *op); +PyAPI_FUNC(Py_complex) PyComplex_AsCComplex(PyObject *op); + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(PyObject *) _PyComplex_FormatAdvanced(PyObject *obj, + char *format_spec, + Py_ssize_t format_spec_len); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_COMPLEXOBJECT_H */ diff --git a/python/include/datetime.h b/python/include/datetime.h new file mode 100644 index 000000000..47abe5cb8 --- /dev/null +++ b/python/include/datetime.h @@ -0,0 +1,239 @@ +/* datetime.h + */ + +#ifndef DATETIME_H +#define DATETIME_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Fields are packed into successive bytes, each viewed as unsigned and + * big-endian, unless otherwise noted: + * + * byte offset + * 0 year 2 bytes, 1-9999 + * 2 month 1 byte, 1-12 + * 3 day 1 byte, 1-31 + * 4 hour 1 byte, 0-23 + * 5 minute 1 byte, 0-59 + * 6 second 1 byte, 0-59 + * 7 usecond 3 bytes, 0-999999 + * 10 + */ + +/* # of bytes for year, month, and day. */ +#define _PyDateTime_DATE_DATASIZE 4 + +/* # of bytes for hour, minute, second, and usecond. */ +#define _PyDateTime_TIME_DATASIZE 6 + +/* # of bytes for year, month, day, hour, minute, second, and usecond. */ +#define _PyDateTime_DATETIME_DATASIZE 10 + + +typedef struct +{ + PyObject_HEAD + long hashcode; /* -1 when unknown */ + int days; /* -MAX_DELTA_DAYS <= days <= MAX_DELTA_DAYS */ + int seconds; /* 0 <= seconds < 24*3600 is invariant */ + int microseconds; /* 0 <= microseconds < 1000000 is invariant */ +} PyDateTime_Delta; + +typedef struct +{ + PyObject_HEAD /* a pure abstract base clase */ +} PyDateTime_TZInfo; + + +/* The datetime and time types have hashcodes, and an optional tzinfo member, + * present if and only if hastzinfo is true. + */ +#define _PyTZINFO_HEAD \ + PyObject_HEAD \ + long hashcode; \ + char hastzinfo; /* boolean flag */ + +/* No _PyDateTime_BaseTZInfo is allocated; it's just to have something + * convenient to cast to, when getting at the hastzinfo member of objects + * starting with _PyTZINFO_HEAD. + */ +typedef struct +{ + _PyTZINFO_HEAD +} _PyDateTime_BaseTZInfo; + +/* All time objects are of PyDateTime_TimeType, but that can be allocated + * in two ways, with or without a tzinfo member. Without is the same as + * tzinfo == None, but consumes less memory. _PyDateTime_BaseTime is an + * internal struct used to allocate the right amount of space for the + * "without" case. + */ +#define _PyDateTime_TIMEHEAD \ + _PyTZINFO_HEAD \ + unsigned char data[_PyDateTime_TIME_DATASIZE]; + +typedef struct +{ + _PyDateTime_TIMEHEAD +} _PyDateTime_BaseTime; /* hastzinfo false */ + +typedef struct +{ + _PyDateTime_TIMEHEAD + PyObject *tzinfo; +} PyDateTime_Time; /* hastzinfo true */ + + +/* All datetime objects are of PyDateTime_DateTimeType, but that can be + * allocated in two ways too, just like for time objects above. In addition, + * the plain date type is a base class for datetime, so it must also have + * a hastzinfo member (although it's unused there). + */ +typedef struct +{ + _PyTZINFO_HEAD + unsigned char data[_PyDateTime_DATE_DATASIZE]; +} PyDateTime_Date; + +#define _PyDateTime_DATETIMEHEAD \ + _PyTZINFO_HEAD \ + unsigned char data[_PyDateTime_DATETIME_DATASIZE]; + +typedef struct +{ + _PyDateTime_DATETIMEHEAD +} _PyDateTime_BaseDateTime; /* hastzinfo false */ + +typedef struct +{ + _PyDateTime_DATETIMEHEAD + PyObject *tzinfo; +} PyDateTime_DateTime; /* hastzinfo true */ + + +/* Apply for date and datetime instances. */ +#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \ + ((PyDateTime_Date*)o)->data[1]) +#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2]) +#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)o)->data[3]) + +#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)o)->data[4]) +#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5]) +#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6]) +#define PyDateTime_DATE_GET_MICROSECOND(o) \ + ((((PyDateTime_DateTime*)o)->data[7] << 16) | \ + (((PyDateTime_DateTime*)o)->data[8] << 8) | \ + ((PyDateTime_DateTime*)o)->data[9]) + +/* Apply for time instances. */ +#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0]) +#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1]) +#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2]) +#define PyDateTime_TIME_GET_MICROSECOND(o) \ + ((((PyDateTime_Time*)o)->data[3] << 16) | \ + (((PyDateTime_Time*)o)->data[4] << 8) | \ + ((PyDateTime_Time*)o)->data[5]) + + +/* Define structure for C API. */ +typedef struct { + /* type objects */ + PyTypeObject *DateType; + PyTypeObject *DateTimeType; + PyTypeObject *TimeType; + PyTypeObject *DeltaType; + PyTypeObject *TZInfoType; + + /* constructors */ + PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*); + PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int, + PyObject*, PyTypeObject*); + PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*); + PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*); + + /* constructors for the DB API */ + PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*); + PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*); + +} PyDateTime_CAPI; + +#define PyDateTime_CAPSULE_NAME "datetime.datetime_CAPI" + + +/* "magic" constant used to partially protect against developer mistakes. */ +#define DATETIME_API_MAGIC 0x414548d5 + +#ifdef Py_BUILD_CORE + +/* Macros for type checking when building the Python core. */ +#define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType) +#define PyDate_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateType) + +#define PyDateTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateTimeType) +#define PyDateTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DateTimeType) + +#define PyTime_Check(op) PyObject_TypeCheck(op, &PyDateTime_TimeType) +#define PyTime_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TimeType) + +#define PyDelta_Check(op) PyObject_TypeCheck(op, &PyDateTime_DeltaType) +#define PyDelta_CheckExact(op) (Py_TYPE(op) == &PyDateTime_DeltaType) + +#define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType) +#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == &PyDateTime_TZInfoType) + +#else + +/* Define global variable for the C API and a macro for setting it. */ +static PyDateTime_CAPI *PyDateTimeAPI = NULL; + +#define PyDateTime_IMPORT \ + PyDateTimeAPI = (PyDateTime_CAPI *)PyCapsule_Import(PyDateTime_CAPSULE_NAME, 0) + +/* Macros for type checking when not building the Python core. */ +#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) +#define PyDate_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateType) + +#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType) +#define PyDateTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DateTimeType) + +#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType) +#define PyTime_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TimeType) + +#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType) +#define PyDelta_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->DeltaType) + +#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType) +#define PyTZInfo_CheckExact(op) (Py_TYPE(op) == PyDateTimeAPI->TZInfoType) + +/* Macros for accessing constructors in a simplified fashion. */ +#define PyDate_FromDate(year, month, day) \ + PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType) + +#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \ + PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \ + min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType) + +#define PyTime_FromTime(hour, minute, second, usecond) \ + PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \ + Py_None, PyDateTimeAPI->TimeType) + +#define PyDelta_FromDSU(days, seconds, useconds) \ + PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \ + PyDateTimeAPI->DeltaType) + +/* Macros supporting the DB API. */ +#define PyDateTime_FromTimestamp(args) \ + PyDateTimeAPI->DateTime_FromTimestamp( \ + (PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL) + +#define PyDate_FromTimestamp(args) \ + PyDateTimeAPI->Date_FromTimestamp( \ + (PyObject*) (PyDateTimeAPI->DateType), args) + +#endif /* Py_BUILD_CORE */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/python/include/descrobject.h b/python/include/descrobject.h new file mode 100644 index 000000000..b542732b1 --- /dev/null +++ b/python/include/descrobject.h @@ -0,0 +1,94 @@ +/* Descriptors */ +#ifndef Py_DESCROBJECT_H +#define Py_DESCROBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef PyObject *(*getter)(PyObject *, void *); +typedef int (*setter)(PyObject *, PyObject *, void *); + +typedef struct PyGetSetDef { + char *name; + getter get; + setter set; + char *doc; + void *closure; +} PyGetSetDef; + +typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, + void *wrapped); + +typedef PyObject *(*wrapperfunc_kwds)(PyObject *self, PyObject *args, + void *wrapped, PyObject *kwds); + +struct wrapperbase { + char *name; + int offset; + void *function; + wrapperfunc wrapper; + char *doc; + int flags; + PyObject *name_strobj; +}; + +/* Flags for above struct */ +#define PyWrapperFlag_KEYWORDS 1 /* wrapper function takes keyword args */ + +/* Various kinds of descriptor objects */ + +#define PyDescr_COMMON \ + PyObject_HEAD \ + PyTypeObject *d_type; \ + PyObject *d_name + +typedef struct { + PyDescr_COMMON; +} PyDescrObject; + +typedef struct { + PyDescr_COMMON; + PyMethodDef *d_method; +} PyMethodDescrObject; + +typedef struct { + PyDescr_COMMON; + struct PyMemberDef *d_member; +} PyMemberDescrObject; + +typedef struct { + PyDescr_COMMON; + PyGetSetDef *d_getset; +} PyGetSetDescrObject; + +typedef struct { + PyDescr_COMMON; + struct wrapperbase *d_base; + void *d_wrapped; /* This can be any function pointer */ +} PyWrapperDescrObject; + +PyAPI_DATA(PyTypeObject) PyWrapperDescr_Type; +PyAPI_DATA(PyTypeObject) PyDictProxy_Type; +PyAPI_DATA(PyTypeObject) PyGetSetDescr_Type; +PyAPI_DATA(PyTypeObject) PyMemberDescr_Type; + +PyAPI_FUNC(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewClassMethod(PyTypeObject *, PyMethodDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewMember(PyTypeObject *, + struct PyMemberDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, + struct PyGetSetDef *); +PyAPI_FUNC(PyObject *) PyDescr_NewWrapper(PyTypeObject *, + struct wrapperbase *, void *); +#define PyDescr_IsData(d) (Py_TYPE(d)->tp_descr_set != NULL) + +PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *); +PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *); + + +PyAPI_DATA(PyTypeObject) PyProperty_Type; +#ifdef __cplusplus +} +#endif +#endif /* !Py_DESCROBJECT_H */ + diff --git a/python/include/dictobject.h b/python/include/dictobject.h new file mode 100644 index 000000000..ece01c64d --- /dev/null +++ b/python/include/dictobject.h @@ -0,0 +1,156 @@ +#ifndef Py_DICTOBJECT_H +#define Py_DICTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Dictionary object type -- mapping from hashable object to object */ + +/* The distribution includes a separate file, Objects/dictnotes.txt, + describing explorations into dictionary design and optimization. + It covers typical dictionary use patterns, the parameters for + tuning dictionaries, and several ideas for possible optimizations. +*/ + +/* +There are three kinds of slots in the table: + +1. Unused. me_key == me_value == NULL + Does not hold an active (key, value) pair now and never did. Unused can + transition to Active upon key insertion. This is the only case in which + me_key is NULL, and is each slot's initial state. + +2. Active. me_key != NULL and me_key != dummy and me_value != NULL + Holds an active (key, value) pair. Active can transition to Dummy upon + key deletion. This is the only case in which me_value != NULL. + +3. Dummy. me_key == dummy and me_value == NULL + Previously held an active (key, value) pair, but that was deleted and an + active pair has not yet overwritten the slot. Dummy can transition to + Active upon key insertion. Dummy slots cannot be made Unused again + (cannot have me_key set to NULL), else the probe sequence in case of + collision would have no way to know they were once active. + +Note: .popitem() abuses the me_hash field of an Unused or Dummy slot to +hold a search finger. The me_hash field of Unused or Dummy slots has no +meaning otherwise. +*/ + +/* PyDict_MINSIZE is the minimum size of a dictionary. This many slots are + * allocated directly in the dict object (in the ma_smalltable member). + * It must be a power of 2, and at least 4. 8 allows dicts with no more + * than 5 active entries to live in ma_smalltable (and so avoid an + * additional malloc); instrumentation suggested this suffices for the + * majority of dicts (consisting mostly of usually-small instance dicts and + * usually-small dicts created to pass keyword arguments). + */ +#define PyDict_MINSIZE 8 + +typedef struct { + /* Cached hash code of me_key. Note that hash codes are C longs. + * We have to use Py_ssize_t instead because dict_popitem() abuses + * me_hash to hold a search finger. + */ + Py_ssize_t me_hash; + PyObject *me_key; + PyObject *me_value; +} PyDictEntry; + +/* +To ensure the lookup algorithm terminates, there must be at least one Unused +slot (NULL key) in the table. +The value ma_fill is the number of non-NULL keys (sum of Active and Dummy); +ma_used is the number of non-NULL, non-dummy keys (== the number of non-NULL +values == the number of Active items). +To avoid slowing down lookups on a near-full table, we resize the table when +it's two-thirds full. +*/ +typedef struct _dictobject PyDictObject; +struct _dictobject { + PyObject_HEAD + Py_ssize_t ma_fill; /* # Active + # Dummy */ + Py_ssize_t ma_used; /* # Active */ + + /* The table contains ma_mask + 1 slots, and that's a power of 2. + * We store the mask instead of the size because the mask is more + * frequently needed. + */ + Py_ssize_t ma_mask; + + /* ma_table points to ma_smalltable for small tables, else to + * additional malloc'ed memory. ma_table is never NULL! This rule + * saves repeated runtime null-tests in the workhorse getitem and + * setitem calls. + */ + PyDictEntry *ma_table; + PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash); + PyDictEntry ma_smalltable[PyDict_MINSIZE]; +}; + +PyAPI_DATA(PyTypeObject) PyDict_Type; +PyAPI_DATA(PyTypeObject) PyDictIterKey_Type; +PyAPI_DATA(PyTypeObject) PyDictIterValue_Type; +PyAPI_DATA(PyTypeObject) PyDictIterItem_Type; +PyAPI_DATA(PyTypeObject) PyDictKeys_Type; +PyAPI_DATA(PyTypeObject) PyDictItems_Type; +PyAPI_DATA(PyTypeObject) PyDictValues_Type; + +#define PyDict_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) +#define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type) +#define PyDictKeys_Check(op) (Py_TYPE(op) == &PyDictKeys_Type) +#define PyDictItems_Check(op) (Py_TYPE(op) == &PyDictItems_Type) +#define PyDictValues_Check(op) (Py_TYPE(op) == &PyDictValues_Type) +/* This excludes Values, since they are not sets. */ +# define PyDictViewSet_Check(op) \ + (PyDictKeys_Check(op) || PyDictItems_Check(op)) + +PyAPI_FUNC(PyObject *) PyDict_New(void); +PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); +PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item); +PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key); +PyAPI_FUNC(void) PyDict_Clear(PyObject *mp); +PyAPI_FUNC(int) PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value); +PyAPI_FUNC(int) _PyDict_Next( + PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, long *hash); +PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp); +PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp); +PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp); +PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key); +PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, long hash); +PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); +PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp); + +/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */ +PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other); + +/* PyDict_Merge updates/merges from a mapping object (an object that + supports PyMapping_Keys() and PyObject_GetItem()). If override is true, + the last occurrence of a key wins, else the first. The Python + dict.update(other) is equivalent to PyDict_Merge(dict, other, 1). +*/ +PyAPI_FUNC(int) PyDict_Merge(PyObject *mp, + PyObject *other, + int override); + +/* PyDict_MergeFromSeq2 updates/merges from an iterable object producing + iterable objects of length 2. If override is true, the last occurrence + of a key wins, else the first. The Python dict constructor dict(seq2) + is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1). +*/ +PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d, + PyObject *seq2, + int override); + +PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key); +PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item); +PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_DICTOBJECT_H */ diff --git a/python/include/dtoa.h b/python/include/dtoa.h new file mode 100644 index 000000000..9b434b77b --- /dev/null +++ b/python/include/dtoa.h @@ -0,0 +1,15 @@ +#ifndef PY_NO_SHORT_FLOAT_REPR +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr); +PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits, + int *decpt, int *sign, char **rve); +PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/python/include/enumobject.h b/python/include/enumobject.h new file mode 100644 index 000000000..c14dbfc8c --- /dev/null +++ b/python/include/enumobject.h @@ -0,0 +1,17 @@ +#ifndef Py_ENUMOBJECT_H +#define Py_ENUMOBJECT_H + +/* Enumerate Object */ + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyEnum_Type; +PyAPI_DATA(PyTypeObject) PyReversed_Type; + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_ENUMOBJECT_H */ diff --git a/python/include/errcode.h b/python/include/errcode.h new file mode 100644 index 000000000..becec80c8 --- /dev/null +++ b/python/include/errcode.h @@ -0,0 +1,36 @@ +#ifndef Py_ERRCODE_H +#define Py_ERRCODE_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Error codes passed around between file input, tokenizer, parser and + interpreter. This is necessary so we can turn them into Python + exceptions at a higher level. Note that some errors have a + slightly different meaning when passed from the tokenizer to the + parser than when passed from the parser to the interpreter; e.g. + the parser only returns E_EOF when it hits EOF immediately, and it + never returns E_OK. */ + +#define E_OK 10 /* No error */ +#define E_EOF 11 /* End Of File */ +#define E_INTR 12 /* Interrupted */ +#define E_TOKEN 13 /* Bad token */ +#define E_SYNTAX 14 /* Syntax error */ +#define E_NOMEM 15 /* Ran out of memory */ +#define E_DONE 16 /* Parsing complete */ +#define E_ERROR 17 /* Execution error */ +#define E_TABSPACE 18 /* Inconsistent mixing of tabs and spaces */ +#define E_OVERFLOW 19 /* Node had too many children */ +#define E_TOODEEP 20 /* Too many indentation levels */ +#define E_DEDENT 21 /* No matching outer block for dedent */ +#define E_DECODE 22 /* Error in decoding into Unicode */ +#define E_EOFS 23 /* EOF in triple-quoted string */ +#define E_EOLS 24 /* EOL in single-quoted string */ +#define E_LINECONT 25 /* Unexpected characters after a line continuation */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ERRCODE_H */ diff --git a/python/include/eval.h b/python/include/eval.h new file mode 100644 index 000000000..b78dfe0fa --- /dev/null +++ b/python/include/eval.h @@ -0,0 +1,25 @@ + +/* Interface to execute compiled code */ + +#ifndef Py_EVAL_H +#define Py_EVAL_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(PyObject *) PyEval_EvalCode(PyCodeObject *, PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) PyEval_EvalCodeEx(PyCodeObject *co, + PyObject *globals, + PyObject *locals, + PyObject **args, int argc, + PyObject **kwds, int kwdc, + PyObject **defs, int defc, + PyObject *closure); + +PyAPI_FUNC(PyObject *) _PyEval_CallTracing(PyObject *func, PyObject *args); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_EVAL_H */ diff --git a/python/include/fileobject.h b/python/include/fileobject.h new file mode 100644 index 000000000..1b540f902 --- /dev/null +++ b/python/include/fileobject.h @@ -0,0 +1,97 @@ + +/* File object interface */ + +#ifndef Py_FILEOBJECT_H +#define Py_FILEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + FILE *f_fp; + PyObject *f_name; + PyObject *f_mode; + int (*f_close)(FILE *); + int f_softspace; /* Flag used by 'print' command */ + int f_binary; /* Flag which indicates whether the file is + open in binary (1) or text (0) mode */ + char* f_buf; /* Allocated readahead buffer */ + char* f_bufend; /* Points after last occupied position */ + char* f_bufptr; /* Current buffer position */ + char *f_setbuf; /* Buffer for setbuf(3) and setvbuf(3) */ + int f_univ_newline; /* Handle any newline convention */ + int f_newlinetypes; /* Types of newlines seen */ + int f_skipnextlf; /* Skip next \n */ + PyObject *f_encoding; + PyObject *f_errors; + PyObject *weakreflist; /* List of weak references */ + int unlocked_count; /* Num. currently running sections of code + using f_fp with the GIL released. */ + int readable; + int writable; +} PyFileObject; + +PyAPI_DATA(PyTypeObject) PyFile_Type; + +#define PyFile_Check(op) PyObject_TypeCheck(op, &PyFile_Type) +#define PyFile_CheckExact(op) (Py_TYPE(op) == &PyFile_Type) + +PyAPI_FUNC(PyObject *) PyFile_FromString(char *, char *); +PyAPI_FUNC(void) PyFile_SetBufSize(PyObject *, int); +PyAPI_FUNC(int) PyFile_SetEncoding(PyObject *, const char *); +PyAPI_FUNC(int) PyFile_SetEncodingAndErrors(PyObject *, const char *, char *errors); +PyAPI_FUNC(PyObject *) PyFile_FromFile(FILE *, char *, char *, + int (*)(FILE *)); +PyAPI_FUNC(FILE *) PyFile_AsFile(PyObject *); +PyAPI_FUNC(void) PyFile_IncUseCount(PyFileObject *); +PyAPI_FUNC(void) PyFile_DecUseCount(PyFileObject *); +PyAPI_FUNC(PyObject *) PyFile_Name(PyObject *); +PyAPI_FUNC(PyObject *) PyFile_GetLine(PyObject *, int); +PyAPI_FUNC(int) PyFile_WriteObject(PyObject *, PyObject *, int); +PyAPI_FUNC(int) PyFile_SoftSpace(PyObject *, int); +PyAPI_FUNC(int) PyFile_WriteString(const char *, PyObject *); +PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *); + +/* The default encoding used by the platform file system APIs + If non-NULL, this is different than the default encoding for strings +*/ +PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; + +/* Routines to replace fread() and fgets() which accept any of \r, \n + or \r\n as line terminators. +*/ +#define PY_STDIOTEXTMODE "b" +char *Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); +size_t Py_UniversalNewlineFread(char *, size_t, FILE *, PyObject *); + +/* A routine to do sanity checking on the file mode string. returns + non-zero on if an exception occurred +*/ +int _PyFile_SanitizeMode(char *mode); + +#if defined _MSC_VER && _MSC_VER >= 1400 +/* A routine to check if a file descriptor is valid on Windows. Returns 0 + * and sets errno to EBADF if it isn't. This is to avoid Assertions + * from various functions in the Windows CRT beginning with + * Visual Studio 2005 + */ +int _PyVerify_fd(int fd); +#elif defined _MSC_VER && _MSC_VER >= 1200 +/* fdopen doesn't set errno EBADF and crashes for large fd on debug build */ +#define _PyVerify_fd(fd) (_get_osfhandle(fd) >= 0) +#else +#define _PyVerify_fd(A) (1) /* dummy */ +#endif + +/* A routine to check if a file descriptor can be select()-ed. */ +#ifdef HAVE_SELECT + #define _PyIsSelectable_fd(FD) (((FD) >= 0) && ((FD) < FD_SETSIZE)) +#else + #define _PyIsSelectable_fd(FD) (1) +#endif /* HAVE_SELECT */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FILEOBJECT_H */ diff --git a/python/include/floatobject.h b/python/include/floatobject.h new file mode 100644 index 000000000..54e88256a --- /dev/null +++ b/python/include/floatobject.h @@ -0,0 +1,140 @@ + +/* Float object interface */ + +/* +PyFloatObject represents a (double precision) floating point number. +*/ + +#ifndef Py_FLOATOBJECT_H +#define Py_FLOATOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + double ob_fval; +} PyFloatObject; + +PyAPI_DATA(PyTypeObject) PyFloat_Type; + +#define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type) +#define PyFloat_CheckExact(op) (Py_TYPE(op) == &PyFloat_Type) + +/* The str() precision PyFloat_STR_PRECISION is chosen so that in most cases, + the rounding noise created by various operations is suppressed, while + giving plenty of precision for practical use. */ + +#define PyFloat_STR_PRECISION 12 + +#ifdef Py_NAN +#define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN) +#endif + +#define Py_RETURN_INF(sign) do \ + if (copysign(1., sign) == 1.) { \ + return PyFloat_FromDouble(Py_HUGE_VAL); \ + } else { \ + return PyFloat_FromDouble(-Py_HUGE_VAL); \ + } while(0) + +PyAPI_FUNC(double) PyFloat_GetMax(void); +PyAPI_FUNC(double) PyFloat_GetMin(void); +PyAPI_FUNC(PyObject *) PyFloat_GetInfo(void); + +/* Return Python float from string PyObject. Second argument ignored on + input, and, if non-NULL, NULL is stored into *junk (this tried to serve a + purpose once but can't be made to work as intended). */ +PyAPI_FUNC(PyObject *) PyFloat_FromString(PyObject*, char** junk); + +/* Return Python float from C double. */ +PyAPI_FUNC(PyObject *) PyFloat_FromDouble(double); + +/* Extract C double from Python float. The macro version trades safety for + speed. */ +PyAPI_FUNC(double) PyFloat_AsDouble(PyObject *); +#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) + +/* Write repr(v) into the char buffer argument, followed by null byte. The + buffer must be "big enough"; >= 100 is very safe. + PyFloat_AsReprString(buf, x) strives to print enough digits so that + PyFloat_FromString(buf) then reproduces x exactly. */ +PyAPI_FUNC(void) PyFloat_AsReprString(char*, PyFloatObject *v); + +/* Write str(v) into the char buffer argument, followed by null byte. The + buffer must be "big enough"; >= 100 is very safe. Note that it's + unusual to be able to get back the float you started with from + PyFloat_AsString's result -- use PyFloat_AsReprString() if you want to + preserve precision across conversions. */ +PyAPI_FUNC(void) PyFloat_AsString(char*, PyFloatObject *v); + +/* _PyFloat_{Pack,Unpack}{4,8} + * + * The struct and pickle (at least) modules need an efficient platform- + * independent way to store floating-point values as byte strings. + * The Pack routines produce a string from a C double, and the Unpack + * routines produce a C double from such a string. The suffix (4 or 8) + * specifies the number of bytes in the string. + * + * On platforms that appear to use (see _PyFloat_Init()) IEEE-754 formats + * these functions work by copying bits. On other platforms, the formats the + * 4- byte format is identical to the IEEE-754 single precision format, and + * the 8-byte format to the IEEE-754 double precision format, although the + * packing of INFs and NaNs (if such things exist on the platform) isn't + * handled correctly, and attempting to unpack a string containing an IEEE + * INF or NaN will raise an exception. + * + * On non-IEEE platforms with more precision, or larger dynamic range, than + * 754 supports, not all values can be packed; on non-IEEE platforms with less + * precision, or smaller dynamic range, not all values can be unpacked. What + * happens in such cases is partly accidental (alas). + */ + +/* The pack routines write 4 or 8 bytes, starting at p. le is a bool + * argument, true if you want the string in little-endian format (exponent + * last, at p+3 or p+7), false if you want big-endian format (exponent + * first, at p). + * Return value: 0 if all is OK, -1 if error (and an exception is + * set, most likely OverflowError). + * There are two problems on non-IEEE platforms: + * 1): What this does is undefined if x is a NaN or infinity. + * 2): -0.0 and +0.0 produce the same string. + */ +PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le); +PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le); + +/* Used to get the important decimal digits of a double */ +PyAPI_FUNC(int) _PyFloat_Digits(char *buf, double v, int *signum); +PyAPI_FUNC(void) _PyFloat_DigitsInit(void); + +/* The unpack routines read 4 or 8 bytes, starting at p. le is a bool + * argument, true if the string is in little-endian format (exponent + * last, at p+3 or p+7), false if big-endian (exponent first, at p). + * Return value: The unpacked double. On error, this is -1.0 and + * PyErr_Occurred() is true (and an exception is set, most likely + * OverflowError). Note that on a non-IEEE platform this will refuse + * to unpack a string that represents a NaN or infinity. + */ +PyAPI_FUNC(double) _PyFloat_Unpack4(const unsigned char *p, int le); +PyAPI_FUNC(double) _PyFloat_Unpack8(const unsigned char *p, int le); + +/* free list api */ +PyAPI_FUNC(int) PyFloat_ClearFreeList(void); + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(PyObject *) _PyFloat_FormatAdvanced(PyObject *obj, + char *format_spec, + Py_ssize_t format_spec_len); + +/* Round a C double x to the closest multiple of 10**-ndigits. Returns a + Python float on success, or NULL (with an appropriate exception set) on + failure. Used in builtin_round in bltinmodule.c. */ +PyAPI_FUNC(PyObject *) _Py_double_round(double x, int ndigits); + + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FLOATOBJECT_H */ diff --git a/python/include/frameobject.h b/python/include/frameobject.h new file mode 100644 index 000000000..17e7679ac --- /dev/null +++ b/python/include/frameobject.h @@ -0,0 +1,89 @@ + +/* Frame object interface */ + +#ifndef Py_FRAMEOBJECT_H +#define Py_FRAMEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int b_type; /* what kind of block this is */ + int b_handler; /* where to jump to find handler */ + int b_level; /* value stack level to pop to */ +} PyTryBlock; + +typedef struct _frame { + PyObject_VAR_HEAD + struct _frame *f_back; /* previous frame, or NULL */ + PyCodeObject *f_code; /* code segment */ + PyObject *f_builtins; /* builtin symbol table (PyDictObject) */ + PyObject *f_globals; /* global symbol table (PyDictObject) */ + PyObject *f_locals; /* local symbol table (any mapping) */ + PyObject **f_valuestack; /* points after the last local */ + /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. + Frame evaluation usually NULLs it, but a frame that yields sets it + to the current stack top. */ + PyObject **f_stacktop; + PyObject *f_trace; /* Trace function */ + + /* If an exception is raised in this frame, the next three are used to + * record the exception info (if any) originally in the thread state. See + * comments before set_exc_info() -- it's not obvious. + * Invariant: if _type is NULL, then so are _value and _traceback. + * Desired invariant: all three are NULL, or all three are non-NULL. That + * one isn't currently true, but "should be". + */ + PyObject *f_exc_type, *f_exc_value, *f_exc_traceback; + + PyThreadState *f_tstate; + int f_lasti; /* Last instruction if called */ + /* Call PyFrame_GetLineNumber() instead of reading this field + directly. As of 2.3 f_lineno is only valid when tracing is + active (i.e. when f_trace is set). At other times we use + PyCode_Addr2Line to calculate the line from the current + bytecode index. */ + int f_lineno; /* Current line number */ + int f_iblock; /* index in f_blockstack */ + PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ + PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */ +} PyFrameObject; + + +/* Standard object interface */ + +PyAPI_DATA(PyTypeObject) PyFrame_Type; + +#define PyFrame_Check(op) ((op)->ob_type == &PyFrame_Type) +#define PyFrame_IsRestricted(f) \ + ((f)->f_builtins != (f)->f_tstate->interp->builtins) + +PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *, + PyObject *, PyObject *); + + +/* The rest of the interface is specific for frame objects */ + +/* Block management functions */ + +PyAPI_FUNC(void) PyFrame_BlockSetup(PyFrameObject *, int, int, int); +PyAPI_FUNC(PyTryBlock *) PyFrame_BlockPop(PyFrameObject *); + +/* Extend the value stack */ + +PyAPI_FUNC(PyObject **) PyFrame_ExtendStack(PyFrameObject *, int, int); + +/* Conversions between "fast locals" and locals in dictionary */ + +PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int); +PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *); + +PyAPI_FUNC(int) PyFrame_ClearFreeList(void); + +/* Return the line of code the frame is currently executing. */ +PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FRAMEOBJECT_H */ diff --git a/python/include/funcobject.h b/python/include/funcobject.h new file mode 100644 index 000000000..eb19f4c38 --- /dev/null +++ b/python/include/funcobject.h @@ -0,0 +1,76 @@ + +/* Function object interface */ + +#ifndef Py_FUNCOBJECT_H +#define Py_FUNCOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Function objects and code objects should not be confused with each other: + * + * Function objects are created by the execution of the 'def' statement. + * They reference a code object in their func_code attribute, which is a + * purely syntactic object, i.e. nothing more than a compiled version of some + * source code lines. There is one code object per source code "fragment", + * but each code object can be referenced by zero or many function objects + * depending only on how many times the 'def' statement in the source was + * executed so far. + */ + +typedef struct { + PyObject_HEAD + PyObject *func_code; /* A code object */ + PyObject *func_globals; /* A dictionary (other mappings won't do) */ + PyObject *func_defaults; /* NULL or a tuple */ + PyObject *func_closure; /* NULL or a tuple of cell objects */ + PyObject *func_doc; /* The __doc__ attribute, can be anything */ + PyObject *func_name; /* The __name__ attribute, a string object */ + PyObject *func_dict; /* The __dict__ attribute, a dict or NULL */ + PyObject *func_weakreflist; /* List of weak references */ + PyObject *func_module; /* The __module__ attribute, can be anything */ + + /* Invariant: + * func_closure contains the bindings for func_code->co_freevars, so + * PyTuple_Size(func_closure) == PyCode_GetNumFree(func_code) + * (func_closure may be NULL if PyCode_GetNumFree(func_code) == 0). + */ +} PyFunctionObject; + +PyAPI_DATA(PyTypeObject) PyFunction_Type; + +#define PyFunction_Check(op) (Py_TYPE(op) == &PyFunction_Type) + +PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetCode(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *); +PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *); +PyAPI_FUNC(int) PyFunction_SetClosure(PyObject *, PyObject *); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyFunction_GET_CODE(func) \ + (((PyFunctionObject *)func) -> func_code) +#define PyFunction_GET_GLOBALS(func) \ + (((PyFunctionObject *)func) -> func_globals) +#define PyFunction_GET_MODULE(func) \ + (((PyFunctionObject *)func) -> func_module) +#define PyFunction_GET_DEFAULTS(func) \ + (((PyFunctionObject *)func) -> func_defaults) +#define PyFunction_GET_CLOSURE(func) \ + (((PyFunctionObject *)func) -> func_closure) + +/* The classmethod and staticmethod types lives here, too */ +PyAPI_DATA(PyTypeObject) PyClassMethod_Type; +PyAPI_DATA(PyTypeObject) PyStaticMethod_Type; + +PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *); +PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_FUNCOBJECT_H */ diff --git a/python/include/genobject.h b/python/include/genobject.h new file mode 100644 index 000000000..135561b70 --- /dev/null +++ b/python/include/genobject.h @@ -0,0 +1,40 @@ + +/* Generator object interface */ + +#ifndef Py_GENOBJECT_H +#define Py_GENOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +struct _frame; /* Avoid including frameobject.h */ + +typedef struct { + PyObject_HEAD + /* The gi_ prefix is intended to remind of generator-iterator. */ + + /* Note: gi_frame can be NULL if the generator is "finished" */ + struct _frame *gi_frame; + + /* True if generator is being executed. */ + int gi_running; + + /* The code object backing the generator */ + PyObject *gi_code; + + /* List of weak reference. */ + PyObject *gi_weakreflist; +} PyGenObject; + +PyAPI_DATA(PyTypeObject) PyGen_Type; + +#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type) +#define PyGen_CheckExact(op) (Py_TYPE(op) == &PyGen_Type) + +PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *); +PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_GENOBJECT_H */ diff --git a/python/include/graminit.h b/python/include/graminit.h new file mode 100644 index 000000000..40d531e8a --- /dev/null +++ b/python/include/graminit.h @@ -0,0 +1,87 @@ +/* Generated by Parser/pgen */ + +#define single_input 256 +#define file_input 257 +#define eval_input 258 +#define decorator 259 +#define decorators 260 +#define decorated 261 +#define funcdef 262 +#define parameters 263 +#define varargslist 264 +#define fpdef 265 +#define fplist 266 +#define stmt 267 +#define simple_stmt 268 +#define small_stmt 269 +#define expr_stmt 270 +#define augassign 271 +#define print_stmt 272 +#define del_stmt 273 +#define pass_stmt 274 +#define flow_stmt 275 +#define break_stmt 276 +#define continue_stmt 277 +#define return_stmt 278 +#define yield_stmt 279 +#define raise_stmt 280 +#define import_stmt 281 +#define import_name 282 +#define import_from 283 +#define import_as_name 284 +#define dotted_as_name 285 +#define import_as_names 286 +#define dotted_as_names 287 +#define dotted_name 288 +#define global_stmt 289 +#define exec_stmt 290 +#define assert_stmt 291 +#define compound_stmt 292 +#define if_stmt 293 +#define while_stmt 294 +#define for_stmt 295 +#define try_stmt 296 +#define with_stmt 297 +#define with_item 298 +#define except_clause 299 +#define suite 300 +#define testlist_safe 301 +#define old_test 302 +#define old_lambdef 303 +#define test 304 +#define or_test 305 +#define and_test 306 +#define not_test 307 +#define comparison 308 +#define comp_op 309 +#define expr 310 +#define xor_expr 311 +#define and_expr 312 +#define shift_expr 313 +#define arith_expr 314 +#define term 315 +#define factor 316 +#define power 317 +#define atom 318 +#define listmaker 319 +#define testlist_comp 320 +#define lambdef 321 +#define trailer 322 +#define subscriptlist 323 +#define subscript 324 +#define sliceop 325 +#define exprlist 326 +#define testlist 327 +#define dictorsetmaker 328 +#define classdef 329 +#define arglist 330 +#define argument 331 +#define list_iter 332 +#define list_for 333 +#define list_if 334 +#define comp_iter 335 +#define comp_for 336 +#define comp_if 337 +#define testlist1 338 +#define encoding_decl 339 +#define yield_expr 340 diff --git a/python/include/grammar.h b/python/include/grammar.h new file mode 100644 index 000000000..8426da30d --- /dev/null +++ b/python/include/grammar.h @@ -0,0 +1,93 @@ + +/* Grammar interface */ + +#ifndef Py_GRAMMAR_H +#define Py_GRAMMAR_H +#ifdef __cplusplus +extern "C" { +#endif + +#include "bitset.h" /* Sigh... */ + +/* A label of an arc */ + +typedef struct { + int lb_type; + char *lb_str; +} label; + +#define EMPTY 0 /* Label number 0 is by definition the empty label */ + +/* A list of labels */ + +typedef struct { + int ll_nlabels; + label *ll_label; +} labellist; + +/* An arc from one state to another */ + +typedef struct { + short a_lbl; /* Label of this arc */ + short a_arrow; /* State where this arc goes to */ +} arc; + +/* A state in a DFA */ + +typedef struct { + int s_narcs; + arc *s_arc; /* Array of arcs */ + + /* Optional accelerators */ + int s_lower; /* Lowest label index */ + int s_upper; /* Highest label index */ + int *s_accel; /* Accelerator */ + int s_accept; /* Nonzero for accepting state */ +} state; + +/* A DFA */ + +typedef struct { + int d_type; /* Non-terminal this represents */ + char *d_name; /* For printing */ + int d_initial; /* Initial state */ + int d_nstates; + state *d_state; /* Array of states */ + bitset d_first; +} dfa; + +/* A grammar */ + +typedef struct { + int g_ndfas; + dfa *g_dfa; /* Array of DFAs */ + labellist g_ll; + int g_start; /* Start symbol of the grammar */ + int g_accel; /* Set if accelerators present */ +} grammar; + +/* FUNCTIONS */ + +grammar *newgrammar(int start); +dfa *adddfa(grammar *g, int type, char *name); +int addstate(dfa *d); +void addarc(dfa *d, int from, int to, int lbl); +dfa *PyGrammar_FindDFA(grammar *g, int type); + +int addlabel(labellist *ll, int type, char *str); +int findlabel(labellist *ll, int type, char *str); +char *PyGrammar_LabelRepr(label *lb); +void translatelabels(grammar *g); + +void addfirstsets(grammar *g); + +void PyGrammar_AddAccelerators(grammar *g); +void PyGrammar_RemoveAccelerators(grammar *); + +void printgrammar(grammar *g, FILE *fp); +void printnonterminals(grammar *g, FILE *fp); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_GRAMMAR_H */ diff --git a/python/include/import.h b/python/include/import.h new file mode 100644 index 000000000..1b7fe0a73 --- /dev/null +++ b/python/include/import.h @@ -0,0 +1,71 @@ + +/* Module definition and import interface */ + +#ifndef Py_IMPORT_H +#define Py_IMPORT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(long) PyImport_GetMagicNumber(void); +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModule(char *name, PyObject *co); +PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleEx( + char *name, PyObject *co, char *pathname); +PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void); +PyAPI_FUNC(PyObject *) PyImport_AddModule(const char *name); +PyAPI_FUNC(PyObject *) PyImport_ImportModule(const char *name); +PyAPI_FUNC(PyObject *) PyImport_ImportModuleNoBlock(const char *); +PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(char *name, + PyObject *globals, PyObject *locals, PyObject *fromlist, int level); + +#define PyImport_ImportModuleEx(n, g, l, f) \ + PyImport_ImportModuleLevel(n, g, l, f, -1) + +PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path); +PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name); +PyAPI_FUNC(PyObject *) PyImport_ReloadModule(PyObject *m); +PyAPI_FUNC(void) PyImport_Cleanup(void); +PyAPI_FUNC(int) PyImport_ImportFrozenModule(char *); + +#ifdef WITH_THREAD +PyAPI_FUNC(void) _PyImport_AcquireLock(void); +PyAPI_FUNC(int) _PyImport_ReleaseLock(void); +#else +#define _PyImport_AcquireLock() +#define _PyImport_ReleaseLock() 1 +#endif + +PyAPI_FUNC(struct filedescr *) _PyImport_FindModule( + const char *, PyObject *, char *, size_t, FILE **, PyObject **); +PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr *); +PyAPI_FUNC(void) _PyImport_ReInitLock(void); + +PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, char *); +PyAPI_FUNC(PyObject *)_PyImport_FixupExtension(char *, char *); + +struct _inittab { + char *name; + void (*initfunc)(void); +}; + +PyAPI_DATA(PyTypeObject) PyNullImporter_Type; +PyAPI_DATA(struct _inittab *) PyImport_Inittab; + +PyAPI_FUNC(int) PyImport_AppendInittab(const char *name, void (*initfunc)(void)); +PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); + +struct _frozen { + char *name; + unsigned char *code; + int size; +}; + +/* Embedding apps may change this pointer to point to their favorite + collection of frozen modules: */ + +PyAPI_DATA(struct _frozen *) PyImport_FrozenModules; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_IMPORT_H */ diff --git a/python/include/intobject.h b/python/include/intobject.h new file mode 100644 index 000000000..78746a634 --- /dev/null +++ b/python/include/intobject.h @@ -0,0 +1,80 @@ + +/* Integer object interface */ + +/* +PyIntObject represents a (long) integer. This is an immutable object; +an integer cannot change its value after creation. + +There are functions to create new integer objects, to test an object +for integer-ness, and to get the integer value. The latter functions +returns -1 and sets errno to EBADF if the object is not an PyIntObject. +None of the functions should be applied to nil objects. + +The type PyIntObject is (unfortunately) exposed here so we can declare +_Py_TrueStruct and _Py_ZeroStruct in boolobject.h; don't use this. +*/ + +#ifndef Py_INTOBJECT_H +#define Py_INTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_HEAD + long ob_ival; +} PyIntObject; + +PyAPI_DATA(PyTypeObject) PyInt_Type; + +#define PyInt_Check(op) \ + PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_INT_SUBCLASS) +#define PyInt_CheckExact(op) ((op)->ob_type == &PyInt_Type) + +PyAPI_FUNC(PyObject *) PyInt_FromString(char*, char**, int); +#ifdef Py_USING_UNICODE +PyAPI_FUNC(PyObject *) PyInt_FromUnicode(Py_UNICODE*, Py_ssize_t, int); +#endif +PyAPI_FUNC(PyObject *) PyInt_FromLong(long); +PyAPI_FUNC(PyObject *) PyInt_FromSize_t(size_t); +PyAPI_FUNC(PyObject *) PyInt_FromSsize_t(Py_ssize_t); +PyAPI_FUNC(long) PyInt_AsLong(PyObject *); +PyAPI_FUNC(Py_ssize_t) PyInt_AsSsize_t(PyObject *); +PyAPI_FUNC(unsigned long) PyInt_AsUnsignedLongMask(PyObject *); +#ifdef HAVE_LONG_LONG +PyAPI_FUNC(unsigned PY_LONG_LONG) PyInt_AsUnsignedLongLongMask(PyObject *); +#endif + +PyAPI_FUNC(long) PyInt_GetMax(void); + +/* Macro, trading safety for speed */ +#define PyInt_AS_LONG(op) (((PyIntObject *)(op))->ob_ival) + +/* These aren't really part of the Int object, but they're handy; the protos + * are necessary for systems that need the magic of PyAPI_FUNC and that want + * to have stropmodule as a dynamically loaded module instead of building it + * into the main Python shared library/DLL. Guido thinks I'm weird for + * building it this way. :-) [cjh] + */ +PyAPI_FUNC(unsigned long) PyOS_strtoul(char *, char **, int); +PyAPI_FUNC(long) PyOS_strtol(char *, char **, int); + +/* free list api */ +PyAPI_FUNC(int) PyInt_ClearFreeList(void); + +/* Convert an integer to the given base. Returns a string. + If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'. + If newstyle is zero, then use the pre-2.6 behavior of octal having + a leading "0" */ +PyAPI_FUNC(PyObject*) _PyInt_Format(PyIntObject* v, int base, int newstyle); + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(PyObject *) _PyInt_FormatAdvanced(PyObject *obj, + char *format_spec, + Py_ssize_t format_spec_len); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTOBJECT_H */ diff --git a/python/include/intrcheck.h b/python/include/intrcheck.h new file mode 100644 index 000000000..3b67ed0d5 --- /dev/null +++ b/python/include/intrcheck.h @@ -0,0 +1,15 @@ + +#ifndef Py_INTRCHECK_H +#define Py_INTRCHECK_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(int) PyOS_InterruptOccurred(void); +PyAPI_FUNC(void) PyOS_InitInterrupts(void); +PyAPI_FUNC(void) PyOS_AfterFork(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTRCHECK_H */ diff --git a/python/include/iterobject.h b/python/include/iterobject.h new file mode 100644 index 000000000..4bd19c290 --- /dev/null +++ b/python/include/iterobject.h @@ -0,0 +1,23 @@ +#ifndef Py_ITEROBJECT_H +#define Py_ITEROBJECT_H +/* Iterators (the basic kind, over a sequence) */ +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PySeqIter_Type; + +#define PySeqIter_Check(op) (Py_TYPE(op) == &PySeqIter_Type) + +PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *); + +PyAPI_DATA(PyTypeObject) PyCallIter_Type; + +#define PyCallIter_Check(op) (Py_TYPE(op) == &PyCallIter_Type) + +PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *); +#ifdef __cplusplus +} +#endif +#endif /* !Py_ITEROBJECT_H */ + diff --git a/python/include/listobject.h b/python/include/listobject.h new file mode 100644 index 000000000..c4458733b --- /dev/null +++ b/python/include/listobject.h @@ -0,0 +1,68 @@ + +/* List object interface */ + +/* +Another generally useful object type is an list of object pointers. +This is a mutable type: the list items can be changed, and items can be +added or removed. Out-of-range indices or non-list objects are ignored. + +*** WARNING *** PyList_SetItem does not increment the new item's reference +count, but does decrement the reference count of the item it replaces, +if not nil. It does *decrement* the reference count if it is *not* +inserted in the list. Similarly, PyList_GetItem does not increment the +returned item's reference count. +*/ + +#ifndef Py_LISTOBJECT_H +#define Py_LISTOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + PyObject_VAR_HEAD + /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ + PyObject **ob_item; + + /* ob_item contains space for 'allocated' elements. The number + * currently in use is ob_size. + * Invariants: + * 0 <= ob_size <= allocated + * len(list) == ob_size + * ob_item == NULL implies ob_size == allocated == 0 + * list.sort() temporarily sets allocated to -1 to detect mutations. + * + * Items must normally not be NULL, except during construction when + * the list is not yet visible outside the function that builds it. + */ + Py_ssize_t allocated; +} PyListObject; + +PyAPI_DATA(PyTypeObject) PyList_Type; + +#define PyList_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) +#define PyList_CheckExact(op) (Py_TYPE(op) == &PyList_Type) + +PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); +PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *); +PyAPI_FUNC(PyObject *) PyList_GetItem(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyList_SetItem(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Insert(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Append(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyList_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); +PyAPI_FUNC(int) PyList_SetSlice(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); +PyAPI_FUNC(int) PyList_Sort(PyObject *); +PyAPI_FUNC(int) PyList_Reverse(PyObject *); +PyAPI_FUNC(PyObject *) PyList_AsTuple(PyObject *); +PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *); + +/* Macro, trading safety for speed */ +#define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i]) +#define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v)) +#define PyList_GET_SIZE(op) Py_SIZE(op) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LISTOBJECT_H */ diff --git a/python/include/longintrepr.h b/python/include/longintrepr.h new file mode 100644 index 000000000..6425c30f3 --- /dev/null +++ b/python/include/longintrepr.h @@ -0,0 +1,103 @@ +#ifndef Py_LONGINTREPR_H +#define Py_LONGINTREPR_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* This is published for the benefit of "friend" marshal.c only. */ + +/* Parameters of the long integer representation. There are two different + sets of parameters: one set for 30-bit digits, stored in an unsigned 32-bit + integer type, and one set for 15-bit digits with each digit stored in an + unsigned short. The value of PYLONG_BITS_IN_DIGIT, defined either at + configure time or in pyport.h, is used to decide which digit size to use. + + Type 'digit' should be able to hold 2*PyLong_BASE-1, and type 'twodigits' + should be an unsigned integer type able to hold all integers up to + PyLong_BASE*PyLong_BASE-1. x_sub assumes that 'digit' is an unsigned type, + and that overflow is handled by taking the result modulo 2**N for some N > + PyLong_SHIFT. The majority of the code doesn't care about the precise + value of PyLong_SHIFT, but there are some notable exceptions: + + - long_pow() requires that PyLong_SHIFT be divisible by 5 + + - PyLong_{As,From}ByteArray require that PyLong_SHIFT be at least 8 + + - long_hash() requires that PyLong_SHIFT is *strictly* less than the number + of bits in an unsigned long, as do the PyLong <-> long (or unsigned long) + conversion functions + + - the long <-> size_t/Py_ssize_t conversion functions expect that + PyLong_SHIFT is strictly less than the number of bits in a size_t + + - the marshal code currently expects that PyLong_SHIFT is a multiple of 15 + + The values 15 and 30 should fit all of the above requirements, on any + platform. +*/ + +#if PYLONG_BITS_IN_DIGIT == 30 +#if !(defined HAVE_UINT64_T && defined HAVE_UINT32_T && \ + defined HAVE_INT64_T && defined HAVE_INT32_T) +#error "30-bit long digits requested, but the necessary types are not available on this platform" +#endif +typedef PY_UINT32_T digit; +typedef PY_INT32_T sdigit; /* signed variant of digit */ +typedef PY_UINT64_T twodigits; +typedef PY_INT64_T stwodigits; /* signed variant of twodigits */ +#define PyLong_SHIFT 30 +#define _PyLong_DECIMAL_SHIFT 9 /* max(e such that 10**e fits in a digit) */ +#define _PyLong_DECIMAL_BASE ((digit)1000000000) /* 10 ** DECIMAL_SHIFT */ +#elif PYLONG_BITS_IN_DIGIT == 15 +typedef unsigned short digit; +typedef short sdigit; /* signed variant of digit */ +typedef unsigned long twodigits; +typedef long stwodigits; /* signed variant of twodigits */ +#define PyLong_SHIFT 15 +#define _PyLong_DECIMAL_SHIFT 4 /* max(e such that 10**e fits in a digit) */ +#define _PyLong_DECIMAL_BASE ((digit)10000) /* 10 ** DECIMAL_SHIFT */ +#else +#error "PYLONG_BITS_IN_DIGIT should be 15 or 30" +#endif +#define PyLong_BASE ((digit)1 << PyLong_SHIFT) +#define PyLong_MASK ((digit)(PyLong_BASE - 1)) + +/* b/w compatibility with Python 2.5 */ +#define SHIFT PyLong_SHIFT +#define BASE PyLong_BASE +#define MASK PyLong_MASK + +#if PyLong_SHIFT % 5 != 0 +#error "longobject.c requires that PyLong_SHIFT be divisible by 5" +#endif + +/* Long integer representation. + The absolute value of a number is equal to + SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) + Negative numbers are represented with ob_size < 0; + zero is represented by ob_size == 0. + In a normalized number, ob_digit[abs(ob_size)-1] (the most significant + digit) is never zero. Also, in all cases, for all valid i, + 0 <= ob_digit[i] <= MASK. + The allocation function takes care of allocating extra memory + so that ob_digit[0] ... ob_digit[abs(ob_size)-1] are actually available. + + CAUTION: Generic code manipulating subtypes of PyVarObject has to + aware that longs abuse ob_size's sign bit. +*/ + +struct _longobject { + PyObject_VAR_HEAD + digit ob_digit[1]; +}; + +PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t); + +/* Return a copy of src. */ +PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LONGINTREPR_H */ diff --git a/python/include/longobject.h b/python/include/longobject.h new file mode 100644 index 000000000..2b4046128 --- /dev/null +++ b/python/include/longobject.h @@ -0,0 +1,134 @@ +#ifndef Py_LONGOBJECT_H +#define Py_LONGOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Long (arbitrary precision) integer object interface */ + +typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */ + +PyAPI_DATA(PyTypeObject) PyLong_Type; + +#define PyLong_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) +#define PyLong_CheckExact(op) (Py_TYPE(op) == &PyLong_Type) + +PyAPI_FUNC(PyObject *) PyLong_FromLong(long); +PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); +PyAPI_FUNC(PyObject *) PyLong_FromDouble(double); +PyAPI_FUNC(PyObject *) PyLong_FromSize_t(size_t); +PyAPI_FUNC(PyObject *) PyLong_FromSsize_t(Py_ssize_t); +PyAPI_FUNC(long) PyLong_AsLong(PyObject *); +PyAPI_FUNC(long) PyLong_AsLongAndOverflow(PyObject *, int *); +PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *); +PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *); +PyAPI_FUNC(Py_ssize_t) PyLong_AsSsize_t(PyObject *); +PyAPI_FUNC(PyObject *) PyLong_GetInfo(void); + +/* For use by intobject.c only */ +#define _PyLong_AsSsize_t PyLong_AsSsize_t +#define _PyLong_FromSize_t PyLong_FromSize_t +#define _PyLong_FromSsize_t PyLong_FromSsize_t +PyAPI_DATA(int) _PyLong_DigitValue[256]; + +/* _PyLong_Frexp returns a double x and an exponent e such that the + true value is approximately equal to x * 2**e. e is >= 0. x is + 0.0 if and only if the input is 0 (in which case, e and x are both + zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is + possible if the number of bits doesn't fit into a Py_ssize_t, sets + OverflowError and returns -1.0 for x, 0 for e. */ +PyAPI_FUNC(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e); + +PyAPI_FUNC(double) PyLong_AsDouble(PyObject *); +PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *); +PyAPI_FUNC(void *) PyLong_AsVoidPtr(PyObject *); + +#ifdef HAVE_LONG_LONG +PyAPI_FUNC(PyObject *) PyLong_FromLongLong(PY_LONG_LONG); +PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG); +PyAPI_FUNC(PY_LONG_LONG) PyLong_AsLongLong(PyObject *); +PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(PyObject *); +PyAPI_FUNC(unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLongMask(PyObject *); +PyAPI_FUNC(PY_LONG_LONG) PyLong_AsLongLongAndOverflow(PyObject *, int *); +#endif /* HAVE_LONG_LONG */ + +PyAPI_FUNC(PyObject *) PyLong_FromString(char *, char **, int); +#ifdef Py_USING_UNICODE +PyAPI_FUNC(PyObject *) PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int); +#endif + +/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0. + v must not be NULL, and must be a normalized long. + There are no error cases. +*/ +PyAPI_FUNC(int) _PyLong_Sign(PyObject *v); + + +/* _PyLong_NumBits. Return the number of bits needed to represent the + absolute value of a long. For example, this returns 1 for 1 and -1, 2 + for 2 and -2, and 2 for 3 and -3. It returns 0 for 0. + v must not be NULL, and must be a normalized long. + (size_t)-1 is returned and OverflowError set if the true result doesn't + fit in a size_t. +*/ +PyAPI_FUNC(size_t) _PyLong_NumBits(PyObject *v); + +/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in + base 256, and return a Python long with the same numeric value. + If n is 0, the integer is 0. Else: + If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB; + else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the + LSB. + If is_signed is 0/false, view the bytes as a non-negative integer. + If is_signed is 1/true, view the bytes as a 2's-complement integer, + non-negative if bit 0x80 of the MSB is clear, negative if set. + Error returns: + + Return NULL with the appropriate exception set if there's not + enough memory to create the Python long. +*/ +PyAPI_FUNC(PyObject *) _PyLong_FromByteArray( + const unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long + v to a base-256 integer, stored in array bytes. Normally return 0, + return -1 on error. + If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at + bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and + the LSB at bytes[n-1]. + If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes + are filled and there's nothing special about bit 0x80 of the MSB. + If is_signed is 1/true, bytes is filled with the 2's-complement + representation of v's value. Bit 0x80 of the MSB is the sign bit. + Error returns (-1): + + is_signed is 0 and v < 0. TypeError is set in this case, and bytes + isn't altered. + + n isn't big enough to hold the full mathematical value of v. For + example, if is_signed is 0 and there are more digits in the v than + fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of + being large enough to hold a sign bit. OverflowError is set in this + case, but bytes holds the least-signficant n bytes of the true value. +*/ +PyAPI_FUNC(int) _PyLong_AsByteArray(PyLongObject* v, + unsigned char* bytes, size_t n, + int little_endian, int is_signed); + +/* _PyLong_Format: Convert the long to a string object with given base, + appending a base prefix of 0[box] if base is 2, 8 or 16. + Add a trailing "L" if addL is non-zero. + If newstyle is zero, then use the pre-2.6 behavior of octal having + a leading "0", instead of the prefix "0o" */ +PyAPI_FUNC(PyObject *) _PyLong_Format(PyObject *aa, int base, int addL, int newstyle); + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(PyObject *) _PyLong_FormatAdvanced(PyObject *obj, + char *format_spec, + Py_ssize_t format_spec_len); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_LONGOBJECT_H */ diff --git a/python/include/marshal.h b/python/include/marshal.h new file mode 100644 index 000000000..411fdca36 --- /dev/null +++ b/python/include/marshal.h @@ -0,0 +1,25 @@ + +/* Interface for marshal.c */ + +#ifndef Py_MARSHAL_H +#define Py_MARSHAL_H +#ifdef __cplusplus +extern "C" { +#endif + +#define Py_MARSHAL_VERSION 2 + +PyAPI_FUNC(void) PyMarshal_WriteLongToFile(long, FILE *, int); +PyAPI_FUNC(void) PyMarshal_WriteObjectToFile(PyObject *, FILE *, int); +PyAPI_FUNC(PyObject *) PyMarshal_WriteObjectToString(PyObject *, int); + +PyAPI_FUNC(long) PyMarshal_ReadLongFromFile(FILE *); +PyAPI_FUNC(int) PyMarshal_ReadShortFromFile(FILE *); +PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromFile(FILE *); +PyAPI_FUNC(PyObject *) PyMarshal_ReadLastObjectFromFile(FILE *); +PyAPI_FUNC(PyObject *) PyMarshal_ReadObjectFromString(char *, Py_ssize_t); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MARSHAL_H */ diff --git a/python/include/memoryobject.h b/python/include/memoryobject.h new file mode 100644 index 000000000..bf0b621ab --- /dev/null +++ b/python/include/memoryobject.h @@ -0,0 +1,74 @@ +/* Memory view object. In Python this is available as "memoryview". */ + +#ifndef Py_MEMORYOBJECT_H +#define Py_MEMORYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyMemoryView_Type; + +#define PyMemoryView_Check(op) (Py_TYPE(op) == &PyMemoryView_Type) + +/* Get a pointer to the underlying Py_buffer of a memoryview object. */ +#define PyMemoryView_GET_BUFFER(op) (&((PyMemoryViewObject *)(op))->view) +/* Get a pointer to the PyObject from which originates a memoryview object. */ +#define PyMemoryView_GET_BASE(op) (((PyMemoryViewObject *)(op))->view.obj) + + +PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base, + int buffertype, + char fort); + + /* Return a contiguous chunk of memory representing the buffer + from an object in a memory view object. If a copy is made then the + base object for the memory view will be a *new* bytes object. + + Otherwise, the base-object will be the object itself and no + data-copying will be done. + + The buffertype argument can be PyBUF_READ, PyBUF_WRITE, + PyBUF_SHADOW to determine whether the returned buffer + should be READONLY, WRITABLE, or set to update the + original buffer if a copy must be made. If buffertype is + PyBUF_WRITE and the buffer is not contiguous an error will + be raised. In this circumstance, the user can use + PyBUF_SHADOW to ensure that a a writable temporary + contiguous buffer is returned. The contents of this + contiguous buffer will be copied back into the original + object after the memoryview object is deleted as long as + the original object is writable and allows setting an + exclusive write lock. If this is not allowed by the + original object, then a BufferError is raised. + + If the object is multi-dimensional and if fortran is 'F', + the first dimension of the underlying array will vary the + fastest in the buffer. If fortran is 'C', then the last + dimension will vary the fastest (C-style contiguous). If + fortran is 'A', then it does not matter and you will get + whatever the object decides is more efficient. + + A new reference is returned that must be DECREF'd when finished. + */ + +PyAPI_FUNC(PyObject *) PyMemoryView_FromObject(PyObject *base); + +PyAPI_FUNC(PyObject *) PyMemoryView_FromBuffer(Py_buffer *info); + /* create new if bufptr is NULL + will be a new bytesobject in base */ + + +/* The struct is declared here so that macros can work, but it shouldn't + be considered public. Don't access those fields directly, use the macros + and functions instead! */ +typedef struct { + PyObject_HEAD + PyObject *base; + Py_buffer view; +} PyMemoryViewObject; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MEMORYOBJECT_H */ diff --git a/python/include/metagrammar.h b/python/include/metagrammar.h new file mode 100644 index 000000000..15c8ef8f3 --- /dev/null +++ b/python/include/metagrammar.h @@ -0,0 +1,18 @@ +#ifndef Py_METAGRAMMAR_H +#define Py_METAGRAMMAR_H +#ifdef __cplusplus +extern "C" { +#endif + + +#define MSTART 256 +#define RULE 257 +#define RHS 258 +#define ALT 259 +#define ITEM 260 +#define ATOM 261 + +#ifdef __cplusplus +} +#endif +#endif /* !Py_METAGRAMMAR_H */ diff --git a/python/include/methodobject.h b/python/include/methodobject.h new file mode 100644 index 000000000..6e160b639 --- /dev/null +++ b/python/include/methodobject.h @@ -0,0 +1,93 @@ + +/* Method object interface */ + +#ifndef Py_METHODOBJECT_H +#define Py_METHODOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* This is about the type 'builtin_function_or_method', + not Python methods in user-defined classes. See classobject.h + for the latter. */ + +PyAPI_DATA(PyTypeObject) PyCFunction_Type; + +#define PyCFunction_Check(op) (Py_TYPE(op) == &PyCFunction_Type) + +typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); +typedef PyObject *(*PyCFunctionWithKeywords)(PyObject *, PyObject *, + PyObject *); +typedef PyObject *(*PyNoArgsFunction)(PyObject *); + +PyAPI_FUNC(PyCFunction) PyCFunction_GetFunction(PyObject *); +PyAPI_FUNC(PyObject *) PyCFunction_GetSelf(PyObject *); +PyAPI_FUNC(int) PyCFunction_GetFlags(PyObject *); + +/* Macros for direct access to these values. Type checks are *not* + done, so use with care. */ +#define PyCFunction_GET_FUNCTION(func) \ + (((PyCFunctionObject *)func) -> m_ml -> ml_meth) +#define PyCFunction_GET_SELF(func) \ + (((PyCFunctionObject *)func) -> m_self) +#define PyCFunction_GET_FLAGS(func) \ + (((PyCFunctionObject *)func) -> m_ml -> ml_flags) +PyAPI_FUNC(PyObject *) PyCFunction_Call(PyObject *, PyObject *, PyObject *); + +struct PyMethodDef { + const char *ml_name; /* The name of the built-in function/method */ + PyCFunction ml_meth; /* The C function that implements it */ + int ml_flags; /* Combination of METH_xxx flags, which mostly + describe the args expected by the C func */ + const char *ml_doc; /* The __doc__ attribute, or NULL */ +}; +typedef struct PyMethodDef PyMethodDef; + +PyAPI_FUNC(PyObject *) Py_FindMethod(PyMethodDef[], PyObject *, const char *); + +#define PyCFunction_New(ML, SELF) PyCFunction_NewEx((ML), (SELF), NULL) +PyAPI_FUNC(PyObject *) PyCFunction_NewEx(PyMethodDef *, PyObject *, + PyObject *); + +/* Flag passed to newmethodobject */ +#define METH_OLDARGS 0x0000 +#define METH_VARARGS 0x0001 +#define METH_KEYWORDS 0x0002 +/* METH_NOARGS and METH_O must not be combined with the flags above. */ +#define METH_NOARGS 0x0004 +#define METH_O 0x0008 + +/* METH_CLASS and METH_STATIC are a little different; these control + the construction of methods for a class. These cannot be used for + functions in modules. */ +#define METH_CLASS 0x0010 +#define METH_STATIC 0x0020 + +/* METH_COEXIST allows a method to be entered eventhough a slot has + already filled the entry. When defined, the flag allows a separate + method, "__contains__" for example, to coexist with a defined + slot like sq_contains. */ + +#define METH_COEXIST 0x0040 + +typedef struct PyMethodChain { + PyMethodDef *methods; /* Methods of this type */ + struct PyMethodChain *link; /* NULL or base type */ +} PyMethodChain; + +PyAPI_FUNC(PyObject *) Py_FindMethodInChain(PyMethodChain *, PyObject *, + const char *); + +typedef struct { + PyObject_HEAD + PyMethodDef *m_ml; /* Description of the C function to call */ + PyObject *m_self; /* Passed as 'self' arg to the C func, can be NULL */ + PyObject *m_module; /* The __module__ attribute, can be anything */ +} PyCFunctionObject; + +PyAPI_FUNC(int) PyCFunction_ClearFreeList(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_METHODOBJECT_H */ diff --git a/python/include/modsupport.h b/python/include/modsupport.h new file mode 100644 index 000000000..d4dddef0b --- /dev/null +++ b/python/include/modsupport.h @@ -0,0 +1,134 @@ + +#ifndef Py_MODSUPPORT_H +#define Py_MODSUPPORT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Module support interface */ + +#include + +/* If PY_SSIZE_T_CLEAN is defined, each functions treats #-specifier + to mean Py_ssize_t */ +#ifdef PY_SSIZE_T_CLEAN +#define PyArg_Parse _PyArg_Parse_SizeT +#define PyArg_ParseTuple _PyArg_ParseTuple_SizeT +#define PyArg_ParseTupleAndKeywords _PyArg_ParseTupleAndKeywords_SizeT +#define PyArg_VaParse _PyArg_VaParse_SizeT +#define PyArg_VaParseTupleAndKeywords _PyArg_VaParseTupleAndKeywords_SizeT +#define Py_BuildValue _Py_BuildValue_SizeT +#define Py_VaBuildValue _Py_VaBuildValue_SizeT +#else +PyAPI_FUNC(PyObject *) _Py_VaBuildValue_SizeT(const char *, va_list); +#endif + +PyAPI_FUNC(int) PyArg_Parse(PyObject *, const char *, ...); +PyAPI_FUNC(int) PyArg_ParseTuple(PyObject *, const char *, ...) Py_FORMAT_PARSETUPLE(PyArg_ParseTuple, 2, 3); +PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, ...); +PyAPI_FUNC(int) PyArg_UnpackTuple(PyObject *, const char *, Py_ssize_t, Py_ssize_t, ...); +PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); +PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); +PyAPI_FUNC(int) _PyArg_NoKeywords(const char *funcname, PyObject *kw); + +PyAPI_FUNC(int) PyArg_VaParse(PyObject *, const char *, va_list); +PyAPI_FUNC(int) PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, va_list); +PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list); + +PyAPI_FUNC(int) PyModule_AddObject(PyObject *, const char *, PyObject *); +PyAPI_FUNC(int) PyModule_AddIntConstant(PyObject *, const char *, long); +PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char *); +#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, #c, c) +#define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c) + +#define PYTHON_API_VERSION 1013 +#define PYTHON_API_STRING "1013" +/* The API version is maintained (independently from the Python version) + so we can detect mismatches between the interpreter and dynamically + loaded modules. These are diagnosed by an error message but + the module is still loaded (because the mismatch can only be tested + after loading the module). The error message is intended to + explain the core dump a few seconds later. + + The symbol PYTHON_API_STRING defines the same value as a string + literal. *** PLEASE MAKE SURE THE DEFINITIONS MATCH. *** + + Please add a line or two to the top of this log for each API + version change: + + 22-Feb-2006 MvL 1013 PEP 353 - long indices for sequence lengths + + 19-Aug-2002 GvR 1012 Changes to string object struct for + interning changes, saving 3 bytes. + + 17-Jul-2001 GvR 1011 Descr-branch, just to be on the safe side + + 25-Jan-2001 FLD 1010 Parameters added to PyCode_New() and + PyFrame_New(); Python 2.1a2 + + 14-Mar-2000 GvR 1009 Unicode API added + + 3-Jan-1999 GvR 1007 Decided to change back! (Don't reuse 1008!) + + 3-Dec-1998 GvR 1008 Python 1.5.2b1 + + 18-Jan-1997 GvR 1007 string interning and other speedups + + 11-Oct-1996 GvR renamed Py_Ellipses to Py_Ellipsis :-( + + 30-Jul-1996 GvR Slice and ellipses syntax added + + 23-Jul-1996 GvR For 1.4 -- better safe than sorry this time :-) + + 7-Nov-1995 GvR Keyword arguments (should've been done at 1.3 :-( ) + + 10-Jan-1995 GvR Renamed globals to new naming scheme + + 9-Jan-1995 GvR Initial version (incompatible with older API) +*/ + +#ifdef MS_WINDOWS +/* Special defines for Windows versions used to live here. Things + have changed, and the "Version" is now in a global string variable. + Reason for this is that this for easier branding of a "custom DLL" + without actually needing a recompile. */ +#endif /* MS_WINDOWS */ + +#if SIZEOF_SIZE_T != SIZEOF_INT +/* On a 64-bit system, rename the Py_InitModule4 so that 2.4 + modules cannot get loaded into a 2.5 interpreter */ +#define Py_InitModule4 Py_InitModule4_64 +#endif + +#ifdef Py_TRACE_REFS + /* When we are tracing reference counts, rename Py_InitModule4 so + modules compiled with incompatible settings will generate a + link-time error. */ + #if SIZEOF_SIZE_T != SIZEOF_INT + #undef Py_InitModule4 + #define Py_InitModule4 Py_InitModule4TraceRefs_64 + #else + #define Py_InitModule4 Py_InitModule4TraceRefs + #endif +#endif + +PyAPI_FUNC(PyObject *) Py_InitModule4(const char *name, PyMethodDef *methods, + const char *doc, PyObject *self, + int apiver); + +#define Py_InitModule(name, methods) \ + Py_InitModule4(name, methods, (char *)NULL, (PyObject *)NULL, \ + PYTHON_API_VERSION) + +#define Py_InitModule3(name, methods, doc) \ + Py_InitModule4(name, methods, doc, (PyObject *)NULL, \ + PYTHON_API_VERSION) + +PyAPI_DATA(char *) _Py_PackageContext; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MODSUPPORT_H */ diff --git a/python/include/moduleobject.h b/python/include/moduleobject.h new file mode 100644 index 000000000..b387f5bfd --- /dev/null +++ b/python/include/moduleobject.h @@ -0,0 +1,24 @@ + +/* Module object interface */ + +#ifndef Py_MODULEOBJECT_H +#define Py_MODULEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyModule_Type; + +#define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type) +#define PyModule_CheckExact(op) (Py_TYPE(op) == &PyModule_Type) + +PyAPI_FUNC(PyObject *) PyModule_New(const char *); +PyAPI_FUNC(PyObject *) PyModule_GetDict(PyObject *); +PyAPI_FUNC(char *) PyModule_GetName(PyObject *); +PyAPI_FUNC(char *) PyModule_GetFilename(PyObject *); +PyAPI_FUNC(void) _PyModule_Clear(PyObject *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_MODULEOBJECT_H */ diff --git a/python/include/node.h b/python/include/node.h new file mode 100644 index 000000000..e23e709ff --- /dev/null +++ b/python/include/node.h @@ -0,0 +1,40 @@ + +/* Parse tree node interface */ + +#ifndef Py_NODE_H +#define Py_NODE_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _node { + short n_type; + char *n_str; + int n_lineno; + int n_col_offset; + int n_nchildren; + struct _node *n_child; +} node; + +PyAPI_FUNC(node *) PyNode_New(int type); +PyAPI_FUNC(int) PyNode_AddChild(node *n, int type, + char *str, int lineno, int col_offset); +PyAPI_FUNC(void) PyNode_Free(node *n); + +/* Node access functions */ +#define NCH(n) ((n)->n_nchildren) + +#define CHILD(n, i) (&(n)->n_child[i]) +#define RCHILD(n, i) (CHILD(n, NCH(n) + i)) +#define TYPE(n) ((n)->n_type) +#define STR(n) ((n)->n_str) + +/* Assert that the type of a node is what we expect */ +#define REQ(n, type) assert(TYPE(n) == (type)) + +PyAPI_FUNC(void) PyNode_ListTree(node *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_NODE_H */ diff --git a/python/include/object.h b/python/include/object.h new file mode 100644 index 000000000..edcd3fc22 --- /dev/null +++ b/python/include/object.h @@ -0,0 +1,996 @@ +#ifndef Py_OBJECT_H +#define Py_OBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Object and type object interface */ + +/* +Objects are structures allocated on the heap. Special rules apply to +the use of objects to ensure they are properly garbage-collected. +Objects are never allocated statically or on the stack; they must be +accessed through special macros and functions only. (Type objects are +exceptions to the first rule; the standard types are represented by +statically initialized type objects, although work on type/class unification +for Python 2.2 made it possible to have heap-allocated type objects too). + +An object has a 'reference count' that is increased or decreased when a +pointer to the object is copied or deleted; when the reference count +reaches zero there are no references to the object left and it can be +removed from the heap. + +An object has a 'type' that determines what it represents and what kind +of data it contains. An object's type is fixed when it is created. +Types themselves are represented as objects; an object contains a +pointer to the corresponding type object. The type itself has a type +pointer pointing to the object representing the type 'type', which +contains a pointer to itself!). + +Objects do not float around in memory; once allocated an object keeps +the same size and address. Objects that must hold variable-size data +can contain pointers to variable-size parts of the object. Not all +objects of the same type have the same size; but the size cannot change +after allocation. (These restrictions are made so a reference to an +object can be simply a pointer -- moving an object would require +updating all the pointers, and changing an object's size would require +moving it if there was another object right next to it.) + +Objects are always accessed through pointers of the type 'PyObject *'. +The type 'PyObject' is a structure that only contains the reference count +and the type pointer. The actual memory allocated for an object +contains other data that can only be accessed after casting the pointer +to a pointer to a longer structure type. This longer type must start +with the reference count and type fields; the macro PyObject_HEAD should be +used for this (to accommodate for future changes). The implementation +of a particular object type can cast the object pointer to the proper +type and back. + +A standard interface exists for objects that contain an array of items +whose size is determined when the object is allocated. +*/ + +/* Py_DEBUG implies Py_TRACE_REFS. */ +#if defined(Py_DEBUG) && !defined(Py_TRACE_REFS) +#define Py_TRACE_REFS +#endif + +/* Py_TRACE_REFS implies Py_REF_DEBUG. */ +#if defined(Py_TRACE_REFS) && !defined(Py_REF_DEBUG) +#define Py_REF_DEBUG +#endif + +#ifdef Py_TRACE_REFS +/* Define pointers to support a doubly-linked list of all live heap objects. */ +#define _PyObject_HEAD_EXTRA \ + struct _object *_ob_next; \ + struct _object *_ob_prev; + +#define _PyObject_EXTRA_INIT 0, 0, + +#else +#define _PyObject_HEAD_EXTRA +#define _PyObject_EXTRA_INIT +#endif + +/* PyObject_HEAD defines the initial segment of every PyObject. */ +#define PyObject_HEAD \ + _PyObject_HEAD_EXTRA \ + Py_ssize_t ob_refcnt; \ + struct _typeobject *ob_type; + +#define PyObject_HEAD_INIT(type) \ + _PyObject_EXTRA_INIT \ + 1, type, + +#define PyVarObject_HEAD_INIT(type, size) \ + PyObject_HEAD_INIT(type) size, + +/* PyObject_VAR_HEAD defines the initial segment of all variable-size + * container objects. These end with a declaration of an array with 1 + * element, but enough space is malloc'ed so that the array actually + * has room for ob_size elements. Note that ob_size is an element count, + * not necessarily a byte count. + */ +#define PyObject_VAR_HEAD \ + PyObject_HEAD \ + Py_ssize_t ob_size; /* Number of items in variable part */ +#define Py_INVALID_SIZE (Py_ssize_t)-1 + +/* Nothing is actually declared to be a PyObject, but every pointer to + * a Python object can be cast to a PyObject*. This is inheritance built + * by hand. Similarly every pointer to a variable-size Python object can, + * in addition, be cast to PyVarObject*. + */ +typedef struct _object { + PyObject_HEAD +} PyObject; + +typedef struct { + PyObject_VAR_HEAD +} PyVarObject; + +#define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt) +#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) +#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) + +/* +Type objects contain a string containing the type name (to help somewhat +in debugging), the allocation parameters (see PyObject_New() and +PyObject_NewVar()), +and methods for accessing objects of the type. Methods are optional, a +nil pointer meaning that particular kind of access is not available for +this type. The Py_DECREF() macro uses the tp_dealloc method without +checking for a nil pointer; it should always be implemented except if +the implementation can guarantee that the reference count will never +reach zero (e.g., for statically allocated type objects). + +NB: the methods for certain type groups are now contained in separate +method blocks. +*/ + +typedef PyObject * (*unaryfunc)(PyObject *); +typedef PyObject * (*binaryfunc)(PyObject *, PyObject *); +typedef PyObject * (*ternaryfunc)(PyObject *, PyObject *, PyObject *); +typedef int (*inquiry)(PyObject *); +typedef Py_ssize_t (*lenfunc)(PyObject *); +typedef int (*coercion)(PyObject **, PyObject **); +typedef PyObject *(*intargfunc)(PyObject *, int) Py_DEPRECATED(2.5); +typedef PyObject *(*intintargfunc)(PyObject *, int, int) Py_DEPRECATED(2.5); +typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t); +typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t); +typedef int(*intobjargproc)(PyObject *, int, PyObject *); +typedef int(*intintobjargproc)(PyObject *, int, int, PyObject *); +typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *); +typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *); +typedef int(*objobjargproc)(PyObject *, PyObject *, PyObject *); + + + +/* int-based buffer interface */ +typedef int (*getreadbufferproc)(PyObject *, int, void **); +typedef int (*getwritebufferproc)(PyObject *, int, void **); +typedef int (*getsegcountproc)(PyObject *, int *); +typedef int (*getcharbufferproc)(PyObject *, int, char **); +/* ssize_t-based buffer interface */ +typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **); +typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **); +typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *); +typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **); + + +/* Py3k buffer interface */ +typedef struct bufferinfo { + void *buf; + PyObject *obj; /* owned reference */ + Py_ssize_t len; + Py_ssize_t itemsize; /* This is Py_ssize_t so it can be + pointed to by strides in simple case.*/ + int readonly; + int ndim; + char *format; + Py_ssize_t *shape; + Py_ssize_t *strides; + Py_ssize_t *suboffsets; + Py_ssize_t smalltable[2]; /* static store for shape and strides of + mono-dimensional buffers. */ + void *internal; +} Py_buffer; + +typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); +typedef void (*releasebufferproc)(PyObject *, Py_buffer *); + + /* Flags for getting buffers */ +#define PyBUF_SIMPLE 0 +#define PyBUF_WRITABLE 0x0001 +/* we used to include an E, backwards compatible alias */ +#define PyBUF_WRITEABLE PyBUF_WRITABLE +#define PyBUF_FORMAT 0x0004 +#define PyBUF_ND 0x0008 +#define PyBUF_STRIDES (0x0010 | PyBUF_ND) +#define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES) +#define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES) +#define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES) +#define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES) + +#define PyBUF_CONTIG (PyBUF_ND | PyBUF_WRITABLE) +#define PyBUF_CONTIG_RO (PyBUF_ND) + +#define PyBUF_STRIDED (PyBUF_STRIDES | PyBUF_WRITABLE) +#define PyBUF_STRIDED_RO (PyBUF_STRIDES) + +#define PyBUF_RECORDS (PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT) +#define PyBUF_RECORDS_RO (PyBUF_STRIDES | PyBUF_FORMAT) + +#define PyBUF_FULL (PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT) +#define PyBUF_FULL_RO (PyBUF_INDIRECT | PyBUF_FORMAT) + + +#define PyBUF_READ 0x100 +#define PyBUF_WRITE 0x200 +#define PyBUF_SHADOW 0x400 +/* end Py3k buffer interface */ + +typedef int (*objobjproc)(PyObject *, PyObject *); +typedef int (*visitproc)(PyObject *, void *); +typedef int (*traverseproc)(PyObject *, visitproc, void *); + +typedef struct { + /* For numbers without flag bit Py_TPFLAGS_CHECKTYPES set, all + arguments are guaranteed to be of the object's type (modulo + coercion hacks -- i.e. if the type's coercion function + returns other types, then these are allowed as well). Numbers that + have the Py_TPFLAGS_CHECKTYPES flag bit set should check *both* + arguments for proper type and implement the necessary conversions + in the slot functions themselves. */ + + binaryfunc nb_add; + binaryfunc nb_subtract; + binaryfunc nb_multiply; + binaryfunc nb_divide; + binaryfunc nb_remainder; + binaryfunc nb_divmod; + ternaryfunc nb_power; + unaryfunc nb_negative; + unaryfunc nb_positive; + unaryfunc nb_absolute; + inquiry nb_nonzero; + unaryfunc nb_invert; + binaryfunc nb_lshift; + binaryfunc nb_rshift; + binaryfunc nb_and; + binaryfunc nb_xor; + binaryfunc nb_or; + coercion nb_coerce; + unaryfunc nb_int; + unaryfunc nb_long; + unaryfunc nb_float; + unaryfunc nb_oct; + unaryfunc nb_hex; + /* Added in release 2.0 */ + binaryfunc nb_inplace_add; + binaryfunc nb_inplace_subtract; + binaryfunc nb_inplace_multiply; + binaryfunc nb_inplace_divide; + binaryfunc nb_inplace_remainder; + ternaryfunc nb_inplace_power; + binaryfunc nb_inplace_lshift; + binaryfunc nb_inplace_rshift; + binaryfunc nb_inplace_and; + binaryfunc nb_inplace_xor; + binaryfunc nb_inplace_or; + + /* Added in release 2.2 */ + /* The following require the Py_TPFLAGS_HAVE_CLASS flag */ + binaryfunc nb_floor_divide; + binaryfunc nb_true_divide; + binaryfunc nb_inplace_floor_divide; + binaryfunc nb_inplace_true_divide; + + /* Added in release 2.5 */ + unaryfunc nb_index; +} PyNumberMethods; + +typedef struct { + lenfunc sq_length; + binaryfunc sq_concat; + ssizeargfunc sq_repeat; + ssizeargfunc sq_item; + ssizessizeargfunc sq_slice; + ssizeobjargproc sq_ass_item; + ssizessizeobjargproc sq_ass_slice; + objobjproc sq_contains; + /* Added in release 2.0 */ + binaryfunc sq_inplace_concat; + ssizeargfunc sq_inplace_repeat; +} PySequenceMethods; + +typedef struct { + lenfunc mp_length; + binaryfunc mp_subscript; + objobjargproc mp_ass_subscript; +} PyMappingMethods; + +typedef struct { + readbufferproc bf_getreadbuffer; + writebufferproc bf_getwritebuffer; + segcountproc bf_getsegcount; + charbufferproc bf_getcharbuffer; + getbufferproc bf_getbuffer; + releasebufferproc bf_releasebuffer; +} PyBufferProcs; + + +typedef void (*freefunc)(void *); +typedef void (*destructor)(PyObject *); +typedef int (*printfunc)(PyObject *, FILE *, int); +typedef PyObject *(*getattrfunc)(PyObject *, char *); +typedef PyObject *(*getattrofunc)(PyObject *, PyObject *); +typedef int (*setattrfunc)(PyObject *, char *, PyObject *); +typedef int (*setattrofunc)(PyObject *, PyObject *, PyObject *); +typedef int (*cmpfunc)(PyObject *, PyObject *); +typedef PyObject *(*reprfunc)(PyObject *); +typedef long (*hashfunc)(PyObject *); +typedef PyObject *(*richcmpfunc) (PyObject *, PyObject *, int); +typedef PyObject *(*getiterfunc) (PyObject *); +typedef PyObject *(*iternextfunc) (PyObject *); +typedef PyObject *(*descrgetfunc) (PyObject *, PyObject *, PyObject *); +typedef int (*descrsetfunc) (PyObject *, PyObject *, PyObject *); +typedef int (*initproc)(PyObject *, PyObject *, PyObject *); +typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *); +typedef PyObject *(*allocfunc)(struct _typeobject *, Py_ssize_t); + +typedef struct _typeobject { + PyObject_VAR_HEAD + const char *tp_name; /* For printing, in format "." */ + Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */ + + /* Methods to implement standard operations */ + + destructor tp_dealloc; + printfunc tp_print; + getattrfunc tp_getattr; + setattrfunc tp_setattr; + cmpfunc tp_compare; + reprfunc tp_repr; + + /* Method suites for standard classes */ + + PyNumberMethods *tp_as_number; + PySequenceMethods *tp_as_sequence; + PyMappingMethods *tp_as_mapping; + + /* More standard operations (here for binary compatibility) */ + + hashfunc tp_hash; + ternaryfunc tp_call; + reprfunc tp_str; + getattrofunc tp_getattro; + setattrofunc tp_setattro; + + /* Functions to access object as input/output buffer */ + PyBufferProcs *tp_as_buffer; + + /* Flags to define presence of optional/expanded features */ + long tp_flags; + + const char *tp_doc; /* Documentation string */ + + /* Assigned meaning in release 2.0 */ + /* call function for all accessible objects */ + traverseproc tp_traverse; + + /* delete references to contained objects */ + inquiry tp_clear; + + /* Assigned meaning in release 2.1 */ + /* rich comparisons */ + richcmpfunc tp_richcompare; + + /* weak reference enabler */ + Py_ssize_t tp_weaklistoffset; + + /* Added in release 2.2 */ + /* Iterators */ + getiterfunc tp_iter; + iternextfunc tp_iternext; + + /* Attribute descriptor and subclassing stuff */ + struct PyMethodDef *tp_methods; + struct PyMemberDef *tp_members; + struct PyGetSetDef *tp_getset; + struct _typeobject *tp_base; + PyObject *tp_dict; + descrgetfunc tp_descr_get; + descrsetfunc tp_descr_set; + Py_ssize_t tp_dictoffset; + initproc tp_init; + allocfunc tp_alloc; + newfunc tp_new; + freefunc tp_free; /* Low-level free-memory routine */ + inquiry tp_is_gc; /* For PyObject_IS_GC */ + PyObject *tp_bases; + PyObject *tp_mro; /* method resolution order */ + PyObject *tp_cache; + PyObject *tp_subclasses; + PyObject *tp_weaklist; + destructor tp_del; + + /* Type attribute cache version tag. Added in version 2.6 */ + unsigned int tp_version_tag; + +#ifdef COUNT_ALLOCS + /* these must be last and never explicitly initialized */ + Py_ssize_t tp_allocs; + Py_ssize_t tp_frees; + Py_ssize_t tp_maxalloc; + struct _typeobject *tp_prev; + struct _typeobject *tp_next; +#endif +} PyTypeObject; + + +/* The *real* layout of a type object when allocated on the heap */ +typedef struct _heaptypeobject { + /* Note: there's a dependency on the order of these members + in slotptr() in typeobject.c . */ + PyTypeObject ht_type; + PyNumberMethods as_number; + PyMappingMethods as_mapping; + PySequenceMethods as_sequence; /* as_sequence comes after as_mapping, + so that the mapping wins when both + the mapping and the sequence define + a given operator (e.g. __getitem__). + see add_operators() in typeobject.c . */ + PyBufferProcs as_buffer; + PyObject *ht_name, *ht_slots; + /* here are optional user slots, followed by the members. */ +} PyHeapTypeObject; + +/* access macro to the members which are floating "behind" the object */ +#define PyHeapType_GET_MEMBERS(etype) \ + ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize)) + + +/* Generic type check */ +PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); +#define PyObject_TypeCheck(ob, tp) \ + (Py_TYPE(ob) == (tp) || PyType_IsSubtype(Py_TYPE(ob), (tp))) + +PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */ +PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */ +PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */ + +#define PyType_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS) +#define PyType_CheckExact(op) (Py_TYPE(op) == &PyType_Type) + +PyAPI_FUNC(int) PyType_Ready(PyTypeObject *); +PyAPI_FUNC(PyObject *) PyType_GenericAlloc(PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *, + PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, char *, PyObject **); +PyAPI_FUNC(unsigned int) PyType_ClearCache(void); +PyAPI_FUNC(void) PyType_Modified(PyTypeObject *); + +/* Generic operations on objects */ +PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); +PyAPI_FUNC(void) _PyObject_Dump(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *); +PyAPI_FUNC(PyObject *) _PyObject_Str(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_Str(PyObject *); +#define PyObject_Bytes PyObject_Str +#ifdef Py_USING_UNICODE +PyAPI_FUNC(PyObject *) PyObject_Unicode(PyObject *); +#endif +PyAPI_FUNC(int) PyObject_Compare(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyObject_RichCompare(PyObject *, PyObject *, int); +PyAPI_FUNC(int) PyObject_RichCompareBool(PyObject *, PyObject *, int); +PyAPI_FUNC(PyObject *) PyObject_GetAttrString(PyObject *, const char *); +PyAPI_FUNC(int) PyObject_SetAttrString(PyObject *, const char *, PyObject *); +PyAPI_FUNC(int) PyObject_HasAttrString(PyObject *, const char *); +PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); +PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_SelfIter(PyObject *); +PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *); +PyAPI_FUNC(PyObject *) PyObject_GenericGetAttr(PyObject *, PyObject *); +PyAPI_FUNC(int) PyObject_GenericSetAttr(PyObject *, + PyObject *, PyObject *); +PyAPI_FUNC(long) PyObject_Hash(PyObject *); +PyAPI_FUNC(long) PyObject_HashNotImplemented(PyObject *); +PyAPI_FUNC(int) PyObject_IsTrue(PyObject *); +PyAPI_FUNC(int) PyObject_Not(PyObject *); +PyAPI_FUNC(int) PyCallable_Check(PyObject *); +PyAPI_FUNC(int) PyNumber_Coerce(PyObject **, PyObject **); +PyAPI_FUNC(int) PyNumber_CoerceEx(PyObject **, PyObject **); + +PyAPI_FUNC(void) PyObject_ClearWeakRefs(PyObject *); + +/* A slot function whose address we need to compare */ +extern int _PyObject_SlotCompare(PyObject *, PyObject *); +/* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes + dict as the last parameter. */ +PyAPI_FUNC(PyObject *) +_PyObject_GenericGetAttrWithDict(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(int) +_PyObject_GenericSetAttrWithDict(PyObject *, PyObject *, + PyObject *, PyObject *); + + +/* PyObject_Dir(obj) acts like Python __builtin__.dir(obj), returning a + list of strings. PyObject_Dir(NULL) is like __builtin__.dir(), + returning the names of the current locals. In this case, if there are + no current locals, NULL is returned, and PyErr_Occurred() is false. +*/ +PyAPI_FUNC(PyObject *) PyObject_Dir(PyObject *); + + +/* Helpers for printing recursive container types */ +PyAPI_FUNC(int) Py_ReprEnter(PyObject *); +PyAPI_FUNC(void) Py_ReprLeave(PyObject *); + +/* Helpers for hash functions */ +PyAPI_FUNC(long) _Py_HashDouble(double); +PyAPI_FUNC(long) _Py_HashPointer(void*); + +typedef struct { + long prefix; + long suffix; +} _Py_HashSecret_t; +PyAPI_DATA(_Py_HashSecret_t) _Py_HashSecret; + +#ifdef Py_DEBUG +PyAPI_DATA(int) _Py_HashSecret_Initialized; +#endif + +/* Helper for passing objects to printf and the like */ +#define PyObject_REPR(obj) PyString_AS_STRING(PyObject_Repr(obj)) + +/* Flag bits for printing: */ +#define Py_PRINT_RAW 1 /* No string quotes etc. */ + +/* +`Type flags (tp_flags) + +These flags are used to extend the type structure in a backwards-compatible +fashion. Extensions can use the flags to indicate (and test) when a given +type structure contains a new feature. The Python core will use these when +introducing new functionality between major revisions (to avoid mid-version +changes in the PYTHON_API_VERSION). + +Arbitration of the flag bit positions will need to be coordinated among +all extension writers who publically release their extensions (this will +be fewer than you might expect!).. + +Python 1.5.2 introduced the bf_getcharbuffer slot into PyBufferProcs. + +Type definitions should use Py_TPFLAGS_DEFAULT for their tp_flags value. + +Code can use PyType_HasFeature(type_ob, flag_value) to test whether the +given type object has a specified feature. + +NOTE: when building the core, Py_TPFLAGS_DEFAULT includes +Py_TPFLAGS_HAVE_VERSION_TAG; outside the core, it doesn't. This is so +that extensions that modify tp_dict of their own types directly don't +break, since this was allowed in 2.5. In 3.0 they will have to +manually remove this flag though! +*/ + +/* PyBufferProcs contains bf_getcharbuffer */ +#define Py_TPFLAGS_HAVE_GETCHARBUFFER (1L<<0) + +/* PySequenceMethods contains sq_contains */ +#define Py_TPFLAGS_HAVE_SEQUENCE_IN (1L<<1) + +/* This is here for backwards compatibility. Extensions that use the old GC + * API will still compile but the objects will not be tracked by the GC. */ +#define Py_TPFLAGS_GC 0 /* used to be (1L<<2) */ + +/* PySequenceMethods and PyNumberMethods contain in-place operators */ +#define Py_TPFLAGS_HAVE_INPLACEOPS (1L<<3) + +/* PyNumberMethods do their own coercion */ +#define Py_TPFLAGS_CHECKTYPES (1L<<4) + +/* tp_richcompare is defined */ +#define Py_TPFLAGS_HAVE_RICHCOMPARE (1L<<5) + +/* Objects which are weakly referencable if their tp_weaklistoffset is >0 */ +#define Py_TPFLAGS_HAVE_WEAKREFS (1L<<6) + +/* tp_iter is defined */ +#define Py_TPFLAGS_HAVE_ITER (1L<<7) + +/* New members introduced by Python 2.2 exist */ +#define Py_TPFLAGS_HAVE_CLASS (1L<<8) + +/* Set if the type object is dynamically allocated */ +#define Py_TPFLAGS_HEAPTYPE (1L<<9) + +/* Set if the type allows subclassing */ +#define Py_TPFLAGS_BASETYPE (1L<<10) + +/* Set if the type is 'ready' -- fully initialized */ +#define Py_TPFLAGS_READY (1L<<12) + +/* Set while the type is being 'readied', to prevent recursive ready calls */ +#define Py_TPFLAGS_READYING (1L<<13) + +/* Objects support garbage collection (see objimp.h) */ +#define Py_TPFLAGS_HAVE_GC (1L<<14) + +/* These two bits are preserved for Stackless Python, next after this is 17 */ +#ifdef STACKLESS +#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION (3L<<15) +#else +#define Py_TPFLAGS_HAVE_STACKLESS_EXTENSION 0 +#endif + +/* Objects support nb_index in PyNumberMethods */ +#define Py_TPFLAGS_HAVE_INDEX (1L<<17) + +/* Objects support type attribute cache */ +#define Py_TPFLAGS_HAVE_VERSION_TAG (1L<<18) +#define Py_TPFLAGS_VALID_VERSION_TAG (1L<<19) + +/* Type is abstract and cannot be instantiated */ +#define Py_TPFLAGS_IS_ABSTRACT (1L<<20) + +/* Has the new buffer protocol */ +#define Py_TPFLAGS_HAVE_NEWBUFFER (1L<<21) + +/* These flags are used to determine if a type is a subclass. */ +#define Py_TPFLAGS_INT_SUBCLASS (1L<<23) +#define Py_TPFLAGS_LONG_SUBCLASS (1L<<24) +#define Py_TPFLAGS_LIST_SUBCLASS (1L<<25) +#define Py_TPFLAGS_TUPLE_SUBCLASS (1L<<26) +#define Py_TPFLAGS_STRING_SUBCLASS (1L<<27) +#define Py_TPFLAGS_UNICODE_SUBCLASS (1L<<28) +#define Py_TPFLAGS_DICT_SUBCLASS (1L<<29) +#define Py_TPFLAGS_BASE_EXC_SUBCLASS (1L<<30) +#define Py_TPFLAGS_TYPE_SUBCLASS (1L<<31) + +#define Py_TPFLAGS_DEFAULT_EXTERNAL ( \ + Py_TPFLAGS_HAVE_GETCHARBUFFER | \ + Py_TPFLAGS_HAVE_SEQUENCE_IN | \ + Py_TPFLAGS_HAVE_INPLACEOPS | \ + Py_TPFLAGS_HAVE_RICHCOMPARE | \ + Py_TPFLAGS_HAVE_WEAKREFS | \ + Py_TPFLAGS_HAVE_ITER | \ + Py_TPFLAGS_HAVE_CLASS | \ + Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \ + Py_TPFLAGS_HAVE_INDEX | \ + 0) +#define Py_TPFLAGS_DEFAULT_CORE (Py_TPFLAGS_DEFAULT_EXTERNAL | \ + Py_TPFLAGS_HAVE_VERSION_TAG) + +#ifdef Py_BUILD_CORE +#define Py_TPFLAGS_DEFAULT Py_TPFLAGS_DEFAULT_CORE +#else +#define Py_TPFLAGS_DEFAULT Py_TPFLAGS_DEFAULT_EXTERNAL +#endif + +#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0) +#define PyType_FastSubclass(t,f) PyType_HasFeature(t,f) + + +/* +The macros Py_INCREF(op) and Py_DECREF(op) are used to increment or decrement +reference counts. Py_DECREF calls the object's deallocator function when +the refcount falls to 0; for +objects that don't contain references to other objects or heap memory +this can be the standard function free(). Both macros can be used +wherever a void expression is allowed. The argument must not be a +NULL pointer. If it may be NULL, use Py_XINCREF/Py_XDECREF instead. +The macro _Py_NewReference(op) initialize reference counts to 1, and +in special builds (Py_REF_DEBUG, Py_TRACE_REFS) performs additional +bookkeeping appropriate to the special build. + +We assume that the reference count field can never overflow; this can +be proven when the size of the field is the same as the pointer size, so +we ignore the possibility. Provided a C int is at least 32 bits (which +is implicitly assumed in many parts of this code), that's enough for +about 2**31 references to an object. + +XXX The following became out of date in Python 2.2, but I'm not sure +XXX what the full truth is now. Certainly, heap-allocated type objects +XXX can and should be deallocated. +Type objects should never be deallocated; the type pointer in an object +is not considered to be a reference to the type object, to save +complications in the deallocation function. (This is actually a +decision that's up to the implementer of each new type so if you want, +you can count such references to the type object.) + +*** WARNING*** The Py_DECREF macro must have a side-effect-free argument +since it may evaluate its argument multiple times. (The alternative +would be to mace it a proper function or assign it to a global temporary +variable first, both of which are slower; and in a multi-threaded +environment the global variable trick is not safe.) +*/ + +/* First define a pile of simple helper macros, one set per special + * build symbol. These either expand to the obvious things, or to + * nothing at all when the special mode isn't in effect. The main + * macros can later be defined just once then, yet expand to different + * things depending on which special build options are and aren't in effect. + * Trust me : while painful, this is 20x easier to understand than, + * e.g, defining _Py_NewReference five different times in a maze of nested + * #ifdefs (we used to do that -- it was impenetrable). + */ +#ifdef Py_REF_DEBUG +PyAPI_DATA(Py_ssize_t) _Py_RefTotal; +PyAPI_FUNC(void) _Py_NegativeRefcount(const char *fname, + int lineno, PyObject *op); +PyAPI_FUNC(PyObject *) _PyDict_Dummy(void); +PyAPI_FUNC(PyObject *) _PySet_Dummy(void); +PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); +#define _Py_INC_REFTOTAL _Py_RefTotal++ +#define _Py_DEC_REFTOTAL _Py_RefTotal-- +#define _Py_REF_DEBUG_COMMA , +#define _Py_CHECK_REFCNT(OP) \ +{ if (((PyObject*)OP)->ob_refcnt < 0) \ + _Py_NegativeRefcount(__FILE__, __LINE__, \ + (PyObject *)(OP)); \ +} +#else +#define _Py_INC_REFTOTAL +#define _Py_DEC_REFTOTAL +#define _Py_REF_DEBUG_COMMA +#define _Py_CHECK_REFCNT(OP) /* a semicolon */; +#endif /* Py_REF_DEBUG */ + +#ifdef COUNT_ALLOCS +PyAPI_FUNC(void) inc_count(PyTypeObject *); +PyAPI_FUNC(void) dec_count(PyTypeObject *); +#define _Py_INC_TPALLOCS(OP) inc_count(Py_TYPE(OP)) +#define _Py_INC_TPFREES(OP) dec_count(Py_TYPE(OP)) +#define _Py_DEC_TPFREES(OP) Py_TYPE(OP)->tp_frees-- +#define _Py_COUNT_ALLOCS_COMMA , +#else +#define _Py_INC_TPALLOCS(OP) +#define _Py_INC_TPFREES(OP) +#define _Py_DEC_TPFREES(OP) +#define _Py_COUNT_ALLOCS_COMMA +#endif /* COUNT_ALLOCS */ + +#ifdef Py_TRACE_REFS +/* Py_TRACE_REFS is such major surgery that we call external routines. */ +PyAPI_FUNC(void) _Py_NewReference(PyObject *); +PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); +PyAPI_FUNC(void) _Py_Dealloc(PyObject *); +PyAPI_FUNC(void) _Py_PrintReferences(FILE *); +PyAPI_FUNC(void) _Py_PrintReferenceAddresses(FILE *); +PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force); + +#else +/* Without Py_TRACE_REFS, there's little enough to do that we expand code + * inline. + */ +#define _Py_NewReference(op) ( \ + _Py_INC_TPALLOCS(op) _Py_COUNT_ALLOCS_COMMA \ + _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ + Py_REFCNT(op) = 1) + +#define _Py_ForgetReference(op) _Py_INC_TPFREES(op) + +#define _Py_Dealloc(op) ( \ + _Py_INC_TPFREES(op) _Py_COUNT_ALLOCS_COMMA \ + (*Py_TYPE(op)->tp_dealloc)((PyObject *)(op))) +#endif /* !Py_TRACE_REFS */ + +#define Py_INCREF(op) ( \ + _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA \ + ((PyObject*)(op))->ob_refcnt++) + +#define Py_DECREF(op) \ + do { \ + if (_Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA \ + --((PyObject*)(op))->ob_refcnt != 0) \ + _Py_CHECK_REFCNT(op) \ + else \ + _Py_Dealloc((PyObject *)(op)); \ + } while (0) + +/* Safely decref `op` and set `op` to NULL, especially useful in tp_clear + * and tp_dealloc implementatons. + * + * Note that "the obvious" code can be deadly: + * + * Py_XDECREF(op); + * op = NULL; + * + * Typically, `op` is something like self->containee, and `self` is done + * using its `containee` member. In the code sequence above, suppose + * `containee` is non-NULL with a refcount of 1. Its refcount falls to + * 0 on the first line, which can trigger an arbitrary amount of code, + * possibly including finalizers (like __del__ methods or weakref callbacks) + * coded in Python, which in turn can release the GIL and allow other threads + * to run, etc. Such code may even invoke methods of `self` again, or cause + * cyclic gc to trigger, but-- oops! --self->containee still points to the + * object being torn down, and it may be in an insane state while being torn + * down. This has in fact been a rich historic source of miserable (rare & + * hard-to-diagnose) segfaulting (and other) bugs. + * + * The safe way is: + * + * Py_CLEAR(op); + * + * That arranges to set `op` to NULL _before_ decref'ing, so that any code + * triggered as a side-effect of `op` getting torn down no longer believes + * `op` points to a valid object. + * + * There are cases where it's safe to use the naive code, but they're brittle. + * For example, if `op` points to a Python integer, you know that destroying + * one of those can't cause problems -- but in part that relies on that + * Python integers aren't currently weakly referencable. Best practice is + * to use Py_CLEAR() even if you can't think of a reason for why you need to. + */ +#define Py_CLEAR(op) \ + do { \ + if (op) { \ + PyObject *_py_tmp = (PyObject *)(op); \ + (op) = NULL; \ + Py_DECREF(_py_tmp); \ + } \ + } while (0) + +/* Macros to use in case the object pointer may be NULL: */ +#define Py_XINCREF(op) do { if ((op) == NULL) ; else Py_INCREF(op); } while (0) +#define Py_XDECREF(op) do { if ((op) == NULL) ; else Py_DECREF(op); } while (0) + +/* +These are provided as conveniences to Python runtime embedders, so that +they can have object code that is not dependent on Python compilation flags. +*/ +PyAPI_FUNC(void) Py_IncRef(PyObject *); +PyAPI_FUNC(void) Py_DecRef(PyObject *); + +/* +_Py_NoneStruct is an object of undefined type which can be used in contexts +where NULL (nil) is not suitable (since NULL often means 'error'). + +Don't forget to apply Py_INCREF() when returning this value!!! +*/ +PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */ +#define Py_None (&_Py_NoneStruct) + +/* Macro for returning Py_None from a function */ +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None + +/* +Py_NotImplemented is a singleton used to signal that an operation is +not implemented for a given type combination. +*/ +PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */ +#define Py_NotImplemented (&_Py_NotImplementedStruct) + +/* Rich comparison opcodes */ +#define Py_LT 0 +#define Py_LE 1 +#define Py_EQ 2 +#define Py_NE 3 +#define Py_GT 4 +#define Py_GE 5 + +/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE. + * Defined in object.c. + */ +PyAPI_DATA(int) _Py_SwappedOp[]; + +/* +Define staticforward and statichere for source compatibility with old +C extensions. + +The staticforward define was needed to support certain broken C +compilers (notably SCO ODT 3.0, perhaps early AIX as well) botched the +static keyword when it was used with a forward declaration of a static +initialized structure. Standard C allows the forward declaration with +static, and we've decided to stop catering to broken C compilers. +(In fact, we expect that the compilers are all fixed eight years later.) +*/ + +#define staticforward static +#define statichere static + + +/* +More conventions +================ + +Argument Checking +----------------- + +Functions that take objects as arguments normally don't check for nil +arguments, but they do check the type of the argument, and return an +error if the function doesn't apply to the type. + +Failure Modes +------------- + +Functions may fail for a variety of reasons, including running out of +memory. This is communicated to the caller in two ways: an error string +is set (see errors.h), and the function result differs: functions that +normally return a pointer return NULL for failure, functions returning +an integer return -1 (which could be a legal return value too!), and +other functions return 0 for success and -1 for failure. +Callers should always check for errors before using the result. If +an error was set, the caller must either explicitly clear it, or pass +the error on to its caller. + +Reference Counts +---------------- + +It takes a while to get used to the proper usage of reference counts. + +Functions that create an object set the reference count to 1; such new +objects must be stored somewhere or destroyed again with Py_DECREF(). +Some functions that 'store' objects, such as PyTuple_SetItem() and +PyList_SetItem(), +don't increment the reference count of the object, since the most +frequent use is to store a fresh object. Functions that 'retrieve' +objects, such as PyTuple_GetItem() and PyDict_GetItemString(), also +don't increment +the reference count, since most frequently the object is only looked at +quickly. Thus, to retrieve an object and store it again, the caller +must call Py_INCREF() explicitly. + +NOTE: functions that 'consume' a reference count, like +PyList_SetItem(), consume the reference even if the object wasn't +successfully stored, to simplify error handling. + +It seems attractive to make other functions that take an object as +argument consume a reference count; however, this may quickly get +confusing (even the current practice is already confusing). Consider +it carefully, it may save lots of calls to Py_INCREF() and Py_DECREF() at +times. +*/ + + +/* Trashcan mechanism, thanks to Christian Tismer. + +When deallocating a container object, it's possible to trigger an unbounded +chain of deallocations, as each Py_DECREF in turn drops the refcount on "the +next" object in the chain to 0. This can easily lead to stack faults, and +especially in threads (which typically have less stack space to work with). + +A container object that participates in cyclic gc can avoid this by +bracketing the body of its tp_dealloc function with a pair of macros: + +static void +mytype_dealloc(mytype *p) +{ + ... declarations go here ... + + PyObject_GC_UnTrack(p); // must untrack first + Py_TRASHCAN_SAFE_BEGIN(p) + ... The body of the deallocator goes here, including all calls ... + ... to Py_DECREF on contained objects. ... + Py_TRASHCAN_SAFE_END(p) +} + +CAUTION: Never return from the middle of the body! If the body needs to +"get out early", put a label immediately before the Py_TRASHCAN_SAFE_END +call, and goto it. Else the call-depth counter (see below) will stay +above 0 forever, and the trashcan will never get emptied. + +How it works: The BEGIN macro increments a call-depth counter. So long +as this counter is small, the body of the deallocator is run directly without +further ado. But if the counter gets large, it instead adds p to a list of +objects to be deallocated later, skips the body of the deallocator, and +resumes execution after the END macro. The tp_dealloc routine then returns +without deallocating anything (and so unbounded call-stack depth is avoided). + +When the call stack finishes unwinding again, code generated by the END macro +notices this, and calls another routine to deallocate all the objects that +may have been added to the list of deferred deallocations. In effect, a +chain of N deallocations is broken into N / PyTrash_UNWIND_LEVEL pieces, +with the call stack never exceeding a depth of PyTrash_UNWIND_LEVEL. +*/ + +PyAPI_FUNC(void) _PyTrash_deposit_object(PyObject*); +PyAPI_FUNC(void) _PyTrash_destroy_chain(void); +PyAPI_DATA(int) _PyTrash_delete_nesting; +PyAPI_DATA(PyObject *) _PyTrash_delete_later; + +#define PyTrash_UNWIND_LEVEL 50 + +#define Py_TRASHCAN_SAFE_BEGIN(op) \ + if (_PyTrash_delete_nesting < PyTrash_UNWIND_LEVEL) { \ + ++_PyTrash_delete_nesting; + /* The body of the deallocator is here. */ +#define Py_TRASHCAN_SAFE_END(op) \ + --_PyTrash_delete_nesting; \ + if (_PyTrash_delete_later && _PyTrash_delete_nesting <= 0) \ + _PyTrash_destroy_chain(); \ + } \ + else \ + _PyTrash_deposit_object((PyObject*)op); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OBJECT_H */ diff --git a/python/include/objimpl.h b/python/include/objimpl.h new file mode 100644 index 000000000..55e83eced --- /dev/null +++ b/python/include/objimpl.h @@ -0,0 +1,354 @@ +/* The PyObject_ memory family: high-level object memory interfaces. + See pymem.h for the low-level PyMem_ family. +*/ + +#ifndef Py_OBJIMPL_H +#define Py_OBJIMPL_H + +#include "pymem.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEWARE: + + Each interface exports both functions and macros. Extension modules should + use the functions, to ensure binary compatibility across Python versions. + Because the Python implementation is free to change internal details, and + the macros may (or may not) expose details for speed, if you do use the + macros you must recompile your extensions with each Python release. + + Never mix calls to PyObject_ memory functions with calls to the platform + malloc/realloc/ calloc/free, or with calls to PyMem_. +*/ + +/* +Functions and macros for modules that implement new object types. + + - PyObject_New(type, typeobj) allocates memory for a new object of the given + type, and initializes part of it. 'type' must be the C structure type used + to represent the object, and 'typeobj' the address of the corresponding + type object. Reference count and type pointer are filled in; the rest of + the bytes of the object are *undefined*! The resulting expression type is + 'type *'. The size of the object is determined by the tp_basicsize field + of the type object. + + - PyObject_NewVar(type, typeobj, n) is similar but allocates a variable-size + object with room for n items. In addition to the refcount and type pointer + fields, this also fills in the ob_size field. + + - PyObject_Del(op) releases the memory allocated for an object. It does not + run a destructor -- it only frees the memory. PyObject_Free is identical. + + - PyObject_Init(op, typeobj) and PyObject_InitVar(op, typeobj, n) don't + allocate memory. Instead of a 'type' parameter, they take a pointer to a + new object (allocated by an arbitrary allocator), and initialize its object + header fields. + +Note that objects created with PyObject_{New, NewVar} are allocated using the +specialized Python allocator (implemented in obmalloc.c), if WITH_PYMALLOC is +enabled. In addition, a special debugging allocator is used if PYMALLOC_DEBUG +is also #defined. + +In case a specific form of memory management is needed (for example, if you +must use the platform malloc heap(s), or shared memory, or C++ local storage or +operator new), you must first allocate the object with your custom allocator, +then pass its pointer to PyObject_{Init, InitVar} for filling in its Python- +specific fields: reference count, type pointer, possibly others. You should +be aware that Python no control over these objects because they don't +cooperate with the Python memory manager. Such objects may not be eligible +for automatic garbage collection and you have to make sure that they are +released accordingly whenever their destructor gets called (cf. the specific +form of memory management you're using). + +Unless you have specific memory management requirements, use +PyObject_{New, NewVar, Del}. +*/ + +/* + * Raw object memory interface + * =========================== + */ + +/* Functions to call the same malloc/realloc/free as used by Python's + object allocator. If WITH_PYMALLOC is enabled, these may differ from + the platform malloc/realloc/free. The Python object allocator is + designed for fast, cache-conscious allocation of many "small" objects, + and with low hidden memory overhead. + + PyObject_Malloc(0) returns a unique non-NULL pointer if possible. + + PyObject_Realloc(NULL, n) acts like PyObject_Malloc(n). + PyObject_Realloc(p != NULL, 0) does not return NULL, or free the memory + at p. + + Returned pointers must be checked for NULL explicitly; no action is + performed on failure other than to return NULL (no warning it printed, no + exception is set, etc). + + For allocating objects, use PyObject_{New, NewVar} instead whenever + possible. The PyObject_{Malloc, Realloc, Free} family is exposed + so that you can exploit Python's small-block allocator for non-object + uses. If you must use these routines to allocate object memory, make sure + the object gets initialized via PyObject_{Init, InitVar} after obtaining + the raw memory. +*/ +PyAPI_FUNC(void *) PyObject_Malloc(size_t); +PyAPI_FUNC(void *) PyObject_Realloc(void *, size_t); +PyAPI_FUNC(void) PyObject_Free(void *); + + +/* Macros */ +#ifdef WITH_PYMALLOC +#ifdef PYMALLOC_DEBUG /* WITH_PYMALLOC && PYMALLOC_DEBUG */ +PyAPI_FUNC(void *) _PyObject_DebugMalloc(size_t nbytes); +PyAPI_FUNC(void *) _PyObject_DebugRealloc(void *p, size_t nbytes); +PyAPI_FUNC(void) _PyObject_DebugFree(void *p); +PyAPI_FUNC(void) _PyObject_DebugDumpAddress(const void *p); +PyAPI_FUNC(void) _PyObject_DebugCheckAddress(const void *p); +PyAPI_FUNC(void) _PyObject_DebugMallocStats(void); +PyAPI_FUNC(void *) _PyObject_DebugMallocApi(char api, size_t nbytes); +PyAPI_FUNC(void *) _PyObject_DebugReallocApi(char api, void *p, size_t nbytes); +PyAPI_FUNC(void) _PyObject_DebugFreeApi(char api, void *p); +PyAPI_FUNC(void) _PyObject_DebugCheckAddressApi(char api, const void *p); +PyAPI_FUNC(void *) _PyMem_DebugMalloc(size_t nbytes); +PyAPI_FUNC(void *) _PyMem_DebugRealloc(void *p, size_t nbytes); +PyAPI_FUNC(void) _PyMem_DebugFree(void *p); +#define PyObject_MALLOC _PyObject_DebugMalloc +#define PyObject_Malloc _PyObject_DebugMalloc +#define PyObject_REALLOC _PyObject_DebugRealloc +#define PyObject_Realloc _PyObject_DebugRealloc +#define PyObject_FREE _PyObject_DebugFree +#define PyObject_Free _PyObject_DebugFree + +#else /* WITH_PYMALLOC && ! PYMALLOC_DEBUG */ +#define PyObject_MALLOC PyObject_Malloc +#define PyObject_REALLOC PyObject_Realloc +#define PyObject_FREE PyObject_Free +#endif + +#else /* ! WITH_PYMALLOC */ +#define PyObject_MALLOC PyMem_MALLOC +#define PyObject_REALLOC PyMem_REALLOC +#define PyObject_FREE PyMem_FREE + +#endif /* WITH_PYMALLOC */ + +#define PyObject_Del PyObject_Free +#define PyObject_DEL PyObject_FREE + +/* for source compatibility with 2.2 */ +#define _PyObject_Del PyObject_Free + +/* + * Generic object allocator interface + * ================================== + */ + +/* Functions */ +PyAPI_FUNC(PyObject *) PyObject_Init(PyObject *, PyTypeObject *); +PyAPI_FUNC(PyVarObject *) PyObject_InitVar(PyVarObject *, + PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(PyObject *) _PyObject_New(PyTypeObject *); +PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); + +#define PyObject_New(type, typeobj) \ + ( (type *) _PyObject_New(typeobj) ) +#define PyObject_NewVar(type, typeobj, n) \ + ( (type *) _PyObject_NewVar((typeobj), (n)) ) + +/* Macros trading binary compatibility for speed. See also pymem.h. + Note that these macros expect non-NULL object pointers.*/ +#define PyObject_INIT(op, typeobj) \ + ( Py_TYPE(op) = (typeobj), _Py_NewReference((PyObject *)(op)), (op) ) +#define PyObject_INIT_VAR(op, typeobj, size) \ + ( Py_SIZE(op) = (size), PyObject_INIT((op), (typeobj)) ) + +#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) + +/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a + vrbl-size object with nitems items, exclusive of gc overhead (if any). The + value is rounded up to the closest multiple of sizeof(void *), in order to + ensure that pointer fields at the end of the object are correctly aligned + for the platform (this is of special importance for subclasses of, e.g., + str or long, so that pointers can be stored after the embedded data). + + Note that there's no memory wastage in doing this, as malloc has to + return (at worst) pointer-aligned memory anyway. +*/ +#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0 +# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2" +#endif + +#define _PyObject_VAR_SIZE(typeobj, nitems) \ + (size_t) \ + ( ( (typeobj)->tp_basicsize + \ + (nitems)*(typeobj)->tp_itemsize + \ + (SIZEOF_VOID_P - 1) \ + ) & ~(SIZEOF_VOID_P - 1) \ + ) + +#define PyObject_NEW(type, typeobj) \ +( (type *) PyObject_Init( \ + (PyObject *) PyObject_MALLOC( _PyObject_SIZE(typeobj) ), (typeobj)) ) + +#define PyObject_NEW_VAR(type, typeobj, n) \ +( (type *) PyObject_InitVar( \ + (PyVarObject *) PyObject_MALLOC(_PyObject_VAR_SIZE((typeobj),(n)) ),\ + (typeobj), (n)) ) + +/* This example code implements an object constructor with a custom + allocator, where PyObject_New is inlined, and shows the important + distinction between two steps (at least): + 1) the actual allocation of the object storage; + 2) the initialization of the Python specific fields + in this storage with PyObject_{Init, InitVar}. + + PyObject * + YourObject_New(...) + { + PyObject *op; + + op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct)); + if (op == NULL) + return PyErr_NoMemory(); + + PyObject_Init(op, &YourTypeStruct); + + op->ob_field = value; + ... + return op; + } + + Note that in C++, the use of the new operator usually implies that + the 1st step is performed automatically for you, so in a C++ class + constructor you would start directly with PyObject_Init/InitVar +*/ + +/* + * Garbage Collection Support + * ========================== + */ + +/* C equivalent of gc.collect(). */ +PyAPI_FUNC(Py_ssize_t) PyGC_Collect(void); + +/* Test if a type has a GC head */ +#define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) + +/* Test if an object has a GC head */ +#define PyObject_IS_GC(o) (PyType_IS_GC(Py_TYPE(o)) && \ + (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o))) + +PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t); +#define PyObject_GC_Resize(type, op, n) \ + ( (type *) _PyObject_GC_Resize((PyVarObject *)(op), (n)) ) + +/* for source compatibility with 2.2 */ +#define _PyObject_GC_Del PyObject_GC_Del + +/* GC information is stored BEFORE the object structure. */ +typedef union _gc_head { + struct { + union _gc_head *gc_next; + union _gc_head *gc_prev; + Py_ssize_t gc_refs; + } gc; + long double dummy; /* force worst-case alignment */ +} PyGC_Head; + +extern PyGC_Head *_PyGC_generation0; + +#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1) + +#define _PyGC_REFS_UNTRACKED (-2) +#define _PyGC_REFS_REACHABLE (-3) +#define _PyGC_REFS_TENTATIVELY_UNREACHABLE (-4) + +/* Tell the GC to track this object. NB: While the object is tracked the + * collector it must be safe to call the ob_traverse method. */ +#define _PyObject_GC_TRACK(o) do { \ + PyGC_Head *g = _Py_AS_GC(o); \ + if (g->gc.gc_refs != _PyGC_REFS_UNTRACKED) \ + Py_FatalError("GC object already tracked"); \ + g->gc.gc_refs = _PyGC_REFS_REACHABLE; \ + g->gc.gc_next = _PyGC_generation0; \ + g->gc.gc_prev = _PyGC_generation0->gc.gc_prev; \ + g->gc.gc_prev->gc.gc_next = g; \ + _PyGC_generation0->gc.gc_prev = g; \ + } while (0); + +/* Tell the GC to stop tracking this object. + * gc_next doesn't need to be set to NULL, but doing so is a good + * way to provoke memory errors if calling code is confused. + */ +#define _PyObject_GC_UNTRACK(o) do { \ + PyGC_Head *g = _Py_AS_GC(o); \ + assert(g->gc.gc_refs != _PyGC_REFS_UNTRACKED); \ + g->gc.gc_refs = _PyGC_REFS_UNTRACKED; \ + g->gc.gc_prev->gc.gc_next = g->gc.gc_next; \ + g->gc.gc_next->gc.gc_prev = g->gc.gc_prev; \ + g->gc.gc_next = NULL; \ + } while (0); + +/* True if the object is currently tracked by the GC. */ +#define _PyObject_GC_IS_TRACKED(o) \ + ((_Py_AS_GC(o))->gc.gc_refs != _PyGC_REFS_UNTRACKED) + +/* True if the object may be tracked by the GC in the future, or already is. + This can be useful to implement some optimizations. */ +#define _PyObject_GC_MAY_BE_TRACKED(obj) \ + (PyObject_IS_GC(obj) && \ + (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj))) + + +PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t); +PyAPI_FUNC(PyObject *) _PyObject_GC_New(PyTypeObject *); +PyAPI_FUNC(PyVarObject *) _PyObject_GC_NewVar(PyTypeObject *, Py_ssize_t); +PyAPI_FUNC(void) PyObject_GC_Track(void *); +PyAPI_FUNC(void) PyObject_GC_UnTrack(void *); +PyAPI_FUNC(void) PyObject_GC_Del(void *); + +#define PyObject_GC_New(type, typeobj) \ + ( (type *) _PyObject_GC_New(typeobj) ) +#define PyObject_GC_NewVar(type, typeobj, n) \ + ( (type *) _PyObject_GC_NewVar((typeobj), (n)) ) + + +/* Utility macro to help write tp_traverse functions. + * To use this macro, the tp_traverse function must name its arguments + * "visit" and "arg". This is intended to keep tp_traverse functions + * looking as much alike as possible. + */ +#define Py_VISIT(op) \ + do { \ + if (op) { \ + int vret = visit((PyObject *)(op), arg); \ + if (vret) \ + return vret; \ + } \ + } while (0) + +/* This is here for the sake of backwards compatibility. Extensions that + * use the old GC API will still compile but the objects will not be + * tracked by the GC. */ +#define PyGC_HEAD_SIZE 0 +#define PyObject_GC_Init(op) +#define PyObject_GC_Fini(op) +#define PyObject_AS_GC(op) (op) +#define PyObject_FROM_GC(op) (op) + + +/* Test if a type supports weak references */ +#define PyType_SUPPORTS_WEAKREFS(t) \ + (PyType_HasFeature((t), Py_TPFLAGS_HAVE_WEAKREFS) \ + && ((t)->tp_weaklistoffset > 0)) + +#define PyObject_GET_WEAKREFS_LISTPTR(o) \ + ((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset)) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OBJIMPL_H */ diff --git a/python/include/opcode.h b/python/include/opcode.h new file mode 100644 index 000000000..9764109ad --- /dev/null +++ b/python/include/opcode.h @@ -0,0 +1,162 @@ +#ifndef Py_OPCODE_H +#define Py_OPCODE_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Instruction opcodes for compiled code */ + +#define STOP_CODE 0 +#define POP_TOP 1 +#define ROT_TWO 2 +#define ROT_THREE 3 +#define DUP_TOP 4 +#define ROT_FOUR 5 +#define NOP 9 + +#define UNARY_POSITIVE 10 +#define UNARY_NEGATIVE 11 +#define UNARY_NOT 12 +#define UNARY_CONVERT 13 + +#define UNARY_INVERT 15 + +#define BINARY_POWER 19 + +#define BINARY_MULTIPLY 20 +#define BINARY_DIVIDE 21 +#define BINARY_MODULO 22 +#define BINARY_ADD 23 +#define BINARY_SUBTRACT 24 +#define BINARY_SUBSCR 25 +#define BINARY_FLOOR_DIVIDE 26 +#define BINARY_TRUE_DIVIDE 27 +#define INPLACE_FLOOR_DIVIDE 28 +#define INPLACE_TRUE_DIVIDE 29 + +#define SLICE 30 +/* Also uses 31-33 */ + +#define STORE_SLICE 40 +/* Also uses 41-43 */ + +#define DELETE_SLICE 50 +/* Also uses 51-53 */ + +#define STORE_MAP 54 +#define INPLACE_ADD 55 +#define INPLACE_SUBTRACT 56 +#define INPLACE_MULTIPLY 57 +#define INPLACE_DIVIDE 58 +#define INPLACE_MODULO 59 +#define STORE_SUBSCR 60 +#define DELETE_SUBSCR 61 + +#define BINARY_LSHIFT 62 +#define BINARY_RSHIFT 63 +#define BINARY_AND 64 +#define BINARY_XOR 65 +#define BINARY_OR 66 +#define INPLACE_POWER 67 +#define GET_ITER 68 + +#define PRINT_EXPR 70 +#define PRINT_ITEM 71 +#define PRINT_NEWLINE 72 +#define PRINT_ITEM_TO 73 +#define PRINT_NEWLINE_TO 74 +#define INPLACE_LSHIFT 75 +#define INPLACE_RSHIFT 76 +#define INPLACE_AND 77 +#define INPLACE_XOR 78 +#define INPLACE_OR 79 +#define BREAK_LOOP 80 +#define WITH_CLEANUP 81 +#define LOAD_LOCALS 82 +#define RETURN_VALUE 83 +#define IMPORT_STAR 84 +#define EXEC_STMT 85 +#define YIELD_VALUE 86 +#define POP_BLOCK 87 +#define END_FINALLY 88 +#define BUILD_CLASS 89 + +#define HAVE_ARGUMENT 90 /* Opcodes from here have an argument: */ + +#define STORE_NAME 90 /* Index in name list */ +#define DELETE_NAME 91 /* "" */ +#define UNPACK_SEQUENCE 92 /* Number of sequence items */ +#define FOR_ITER 93 +#define LIST_APPEND 94 + +#define STORE_ATTR 95 /* Index in name list */ +#define DELETE_ATTR 96 /* "" */ +#define STORE_GLOBAL 97 /* "" */ +#define DELETE_GLOBAL 98 /* "" */ +#define DUP_TOPX 99 /* number of items to duplicate */ +#define LOAD_CONST 100 /* Index in const list */ +#define LOAD_NAME 101 /* Index in name list */ +#define BUILD_TUPLE 102 /* Number of tuple items */ +#define BUILD_LIST 103 /* Number of list items */ +#define BUILD_SET 104 /* Number of set items */ +#define BUILD_MAP 105 /* Always zero for now */ +#define LOAD_ATTR 106 /* Index in name list */ +#define COMPARE_OP 107 /* Comparison operator */ +#define IMPORT_NAME 108 /* Index in name list */ +#define IMPORT_FROM 109 /* Index in name list */ +#define JUMP_FORWARD 110 /* Number of bytes to skip */ + +#define JUMP_IF_FALSE_OR_POP 111 /* Target byte offset from beginning + of code */ +#define JUMP_IF_TRUE_OR_POP 112 /* "" */ +#define JUMP_ABSOLUTE 113 /* "" */ +#define POP_JUMP_IF_FALSE 114 /* "" */ +#define POP_JUMP_IF_TRUE 115 /* "" */ + +#define LOAD_GLOBAL 116 /* Index in name list */ + +#define CONTINUE_LOOP 119 /* Start of loop (absolute) */ +#define SETUP_LOOP 120 /* Target address (relative) */ +#define SETUP_EXCEPT 121 /* "" */ +#define SETUP_FINALLY 122 /* "" */ + +#define LOAD_FAST 124 /* Local variable number */ +#define STORE_FAST 125 /* Local variable number */ +#define DELETE_FAST 126 /* Local variable number */ + +#define RAISE_VARARGS 130 /* Number of raise arguments (1, 2 or 3) */ +/* CALL_FUNCTION_XXX opcodes defined below depend on this definition */ +#define CALL_FUNCTION 131 /* #args + (#kwargs<<8) */ +#define MAKE_FUNCTION 132 /* #defaults */ +#define BUILD_SLICE 133 /* Number of items */ + +#define MAKE_CLOSURE 134 /* #free vars */ +#define LOAD_CLOSURE 135 /* Load free variable from closure */ +#define LOAD_DEREF 136 /* Load and dereference from closure cell */ +#define STORE_DEREF 137 /* Store into cell */ + +/* The next 3 opcodes must be contiguous and satisfy + (CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1 */ +#define CALL_FUNCTION_VAR 140 /* #args + (#kwargs<<8) */ +#define CALL_FUNCTION_KW 141 /* #args + (#kwargs<<8) */ +#define CALL_FUNCTION_VAR_KW 142 /* #args + (#kwargs<<8) */ + +#define SETUP_WITH 143 + +/* Support for opargs more than 16 bits long */ +#define EXTENDED_ARG 145 + +#define SET_ADD 146 +#define MAP_ADD 147 + + +enum cmp_op {PyCmp_LT=Py_LT, PyCmp_LE=Py_LE, PyCmp_EQ=Py_EQ, PyCmp_NE=Py_NE, PyCmp_GT=Py_GT, PyCmp_GE=Py_GE, + PyCmp_IN, PyCmp_NOT_IN, PyCmp_IS, PyCmp_IS_NOT, PyCmp_EXC_MATCH, PyCmp_BAD}; + +#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OPCODE_H */ diff --git a/python/include/osdefs.h b/python/include/osdefs.h new file mode 100644 index 000000000..693765932 --- /dev/null +++ b/python/include/osdefs.h @@ -0,0 +1,55 @@ +#ifndef Py_OSDEFS_H +#define Py_OSDEFS_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Operating system dependencies */ + +/* Mod by chrish: QNX has WATCOM, but isn't DOS */ +#if !defined(__QNX__) +#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) || defined(PYOS_OS2) +#if defined(PYOS_OS2) && defined(PYCC_GCC) +#define MAXPATHLEN 260 +#define SEP '/' +#define ALTSEP '\\' +#else +#define SEP '\\' +#define ALTSEP '/' +#define MAXPATHLEN 256 +#endif +#define DELIM ';' +#endif +#endif + +#ifdef RISCOS +#define SEP '.' +#define MAXPATHLEN 256 +#define DELIM ',' +#endif + + +/* Filename separator */ +#ifndef SEP +#define SEP '/' +#endif + +/* Max pathname length */ +#ifndef MAXPATHLEN +#if defined(PATH_MAX) && PATH_MAX > 1024 +#define MAXPATHLEN PATH_MAX +#else +#define MAXPATHLEN 1024 +#endif +#endif + +/* Search path entry delimiter */ +#ifndef DELIM +#define DELIM ':' +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_OSDEFS_H */ diff --git a/python/include/parsetok.h b/python/include/parsetok.h new file mode 100644 index 000000000..ec1eb6ff7 --- /dev/null +++ b/python/include/parsetok.h @@ -0,0 +1,64 @@ + +/* Parser-tokenizer link interface */ + +#ifndef Py_PARSETOK_H +#define Py_PARSETOK_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int error; + const char *filename; + int lineno; + int offset; + char *text; + int token; + int expected; +} perrdetail; + +#if 0 +#define PyPARSE_YIELD_IS_KEYWORD 0x0001 +#endif + +#define PyPARSE_DONT_IMPLY_DEDENT 0x0002 + +#if 0 +#define PyPARSE_WITH_IS_KEYWORD 0x0003 +#endif + +#define PyPARSE_PRINT_IS_FUNCTION 0x0004 +#define PyPARSE_UNICODE_LITERALS 0x0008 + + + +PyAPI_FUNC(node *) PyParser_ParseString(const char *, grammar *, int, + perrdetail *); +PyAPI_FUNC(node *) PyParser_ParseFile (FILE *, const char *, grammar *, int, + char *, char *, perrdetail *); + +PyAPI_FUNC(node *) PyParser_ParseStringFlags(const char *, grammar *, int, + perrdetail *, int); +PyAPI_FUNC(node *) PyParser_ParseFileFlags(FILE *, const char *, grammar *, + int, char *, char *, + perrdetail *, int); +PyAPI_FUNC(node *) PyParser_ParseFileFlagsEx(FILE *, const char *, grammar *, + int, char *, char *, + perrdetail *, int *); + +PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilename(const char *, + const char *, + grammar *, int, + perrdetail *, int); +PyAPI_FUNC(node *) PyParser_ParseStringFlagsFilenameEx(const char *, + const char *, + grammar *, int, + perrdetail *, int *); + +/* Note that he following function is defined in pythonrun.c not parsetok.c. */ +PyAPI_FUNC(void) PyParser_SetError(perrdetail *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PARSETOK_H */ diff --git a/python/include/patchlevel.h b/python/include/patchlevel.h new file mode 100644 index 000000000..0a05696ca --- /dev/null +++ b/python/include/patchlevel.h @@ -0,0 +1,43 @@ + +/* Newfangled version identification scheme. + + This scheme was added in Python 1.5.2b2; before that time, only PATCHLEVEL + was available. To test for presence of the scheme, test for + defined(PY_MAJOR_VERSION). + + When the major or minor version changes, the VERSION variable in + configure.in must also be changed. + + There is also (independent) API version information in modsupport.h. +*/ + +/* Values for PY_RELEASE_LEVEL */ +#define PY_RELEASE_LEVEL_ALPHA 0xA +#define PY_RELEASE_LEVEL_BETA 0xB +#define PY_RELEASE_LEVEL_GAMMA 0xC /* For release candidates */ +#define PY_RELEASE_LEVEL_FINAL 0xF /* Serial should be 0 here */ + /* Higher for patch releases */ + +/* Version parsed out into numeric values */ +/*--start constants--*/ +#define PY_MAJOR_VERSION 2 +#define PY_MINOR_VERSION 7 +#define PY_MICRO_VERSION 3 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL +#define PY_RELEASE_SERIAL 0 + +/* Version as a string */ +#define PY_VERSION "2.7.3" +/*--end constants--*/ + +/* Subversion Revision number of this file (not of the repository). Empty + since Mercurial migration. */ +#define PY_PATCHLEVEL_REVISION "" + +/* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. + Use this for numeric comparisons, e.g. #if PY_VERSION_HEX >= ... */ +#define PY_VERSION_HEX ((PY_MAJOR_VERSION << 24) | \ + (PY_MINOR_VERSION << 16) | \ + (PY_MICRO_VERSION << 8) | \ + (PY_RELEASE_LEVEL << 4) | \ + (PY_RELEASE_SERIAL << 0)) diff --git a/python/include/pgen.h b/python/include/pgen.h new file mode 100644 index 000000000..8a325ed07 --- /dev/null +++ b/python/include/pgen.h @@ -0,0 +1,18 @@ +#ifndef Py_PGEN_H +#define Py_PGEN_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Parser generator interface */ + +extern grammar *meta_grammar(void); + +struct _node; +extern grammar *pgen(struct _node *); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PGEN_H */ diff --git a/python/include/pgenheaders.h b/python/include/pgenheaders.h new file mode 100644 index 000000000..2049ae32b --- /dev/null +++ b/python/include/pgenheaders.h @@ -0,0 +1,42 @@ +#ifndef Py_PGENHEADERS_H +#define Py_PGENHEADERS_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Include files and extern declarations used by most of the parser. */ + +#include "Python.h" + +PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); + +#define addarc _Py_addarc +#define addbit _Py_addbit +#define adddfa _Py_adddfa +#define addfirstsets _Py_addfirstsets +#define addlabel _Py_addlabel +#define addstate _Py_addstate +#define delbitset _Py_delbitset +#define dumptree _Py_dumptree +#define findlabel _Py_findlabel +#define mergebitset _Py_mergebitset +#define meta_grammar _Py_meta_grammar +#define newbitset _Py_newbitset +#define newgrammar _Py_newgrammar +#define pgen _Py_pgen +#define printgrammar _Py_printgrammar +#define printnonterminals _Py_printnonterminals +#define printtree _Py_printtree +#define samebitset _Py_samebitset +#define showtree _Py_showtree +#define tok_dump _Py_tok_dump +#define translatelabels _Py_translatelabels + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PGENHEADERS_H */ diff --git a/python/include/py_curses.h b/python/include/py_curses.h new file mode 100644 index 000000000..657816cbd --- /dev/null +++ b/python/include/py_curses.h @@ -0,0 +1,176 @@ + +#ifndef Py_CURSES_H +#define Py_CURSES_H + +#ifdef __APPLE__ +/* +** On Mac OS X 10.2 [n]curses.h and stdlib.h use different guards +** against multiple definition of wchar_t. +*/ +#ifdef _BSD_WCHAR_T_DEFINED_ +#define _WCHAR_T +#endif + +/* the following define is necessary for OS X 10.6; without it, the + Apple-supplied ncurses.h sets NCURSES_OPAQUE to 1, and then Python + can't get at the WINDOW flags field. */ +#define NCURSES_OPAQUE 0 +#endif /* __APPLE__ */ + +#ifdef __FreeBSD__ +/* +** On FreeBSD, [n]curses.h and stdlib.h/wchar.h use different guards +** against multiple definition of wchar_t and wint_t. +*/ +#ifdef _XOPEN_SOURCE_EXTENDED +#ifndef __FreeBSD_version +#include +#endif +#if __FreeBSD_version >= 500000 +#ifndef __wchar_t +#define __wchar_t +#endif +#ifndef __wint_t +#define __wint_t +#endif +#else +#ifndef _WCHAR_T +#define _WCHAR_T +#endif +#ifndef _WINT_T +#define _WINT_T +#endif +#endif +#endif +#endif + +#ifdef HAVE_NCURSES_H +#include +#else +#include +#ifdef HAVE_TERM_H +/* for tigetstr, which is not declared in SysV curses */ +#include +#endif +#endif + +#ifdef HAVE_NCURSES_H +/* configure was checking , but we will + use , which has all these features. */ +#ifndef WINDOW_HAS_FLAGS +#define WINDOW_HAS_FLAGS 1 +#endif +#ifndef MVWDELCH_IS_EXPRESSION +#define MVWDELCH_IS_EXPRESSION 1 +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define PyCurses_API_pointers 4 + +/* Type declarations */ + +typedef struct { + PyObject_HEAD + WINDOW *win; +} PyCursesWindowObject; + +#define PyCursesWindow_Check(v) (Py_TYPE(v) == &PyCursesWindow_Type) + +#define PyCurses_CAPSULE_NAME "_curses._C_API" + + +#ifdef CURSES_MODULE +/* This section is used when compiling _cursesmodule.c */ + +#else +/* This section is used in modules that use the _cursesmodule API */ + +static void **PyCurses_API; + +#define PyCursesWindow_Type (*(PyTypeObject *) PyCurses_API[0]) +#define PyCursesSetupTermCalled {if (! ((int (*)(void))PyCurses_API[1]) () ) return NULL;} +#define PyCursesInitialised {if (! ((int (*)(void))PyCurses_API[2]) () ) return NULL;} +#define PyCursesInitialisedColor {if (! ((int (*)(void))PyCurses_API[3]) () ) return NULL;} + +#define import_curses() \ + PyCurses_API = (void **)PyCapsule_Import(PyCurses_CAPSULE_NAME, 1); + +#endif + +/* general error messages */ +static char *catchall_ERR = "curses function returned ERR"; +static char *catchall_NULL = "curses function returned NULL"; + +/* Function Prototype Macros - They are ugly but very, very useful. ;-) + + X - function name + TYPE - parameter Type + ERGSTR - format string for construction of the return value + PARSESTR - format string for argument parsing + */ + +#define NoArgNoReturnFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + return PyCursesCheckERR(X(), # X); } + +#define NoArgOrFlagNoReturnFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self, PyObject *args) \ +{ \ + int flag = 0; \ + PyCursesInitialised \ + switch(PyTuple_Size(args)) { \ + case 0: \ + return PyCursesCheckERR(X(), # X); \ + case 1: \ + if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL; \ + if (flag) return PyCursesCheckERR(X(), # X); \ + else return PyCursesCheckERR(no ## X (), # X); \ + default: \ + PyErr_SetString(PyExc_TypeError, # X " requires 0 or 1 arguments"); \ + return NULL; } } + +#define NoArgReturnIntFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + return PyInt_FromLong((long) X()); } + + +#define NoArgReturnStringFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + return PyString_FromString(X()); } + +#define NoArgTrueFalseFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + if (X () == FALSE) { \ + Py_INCREF(Py_False); \ + return Py_False; \ + } \ + Py_INCREF(Py_True); \ + return Py_True; } + +#define NoArgNoReturnVoidFunction(X) \ +static PyObject *PyCurses_ ## X (PyObject *self) \ +{ \ + PyCursesInitialised \ + X(); \ + Py_INCREF(Py_None); \ + return Py_None; } + +#ifdef __cplusplus +} +#endif + +#endif /* !defined(Py_CURSES_H) */ + + diff --git a/python/include/pyarena.h b/python/include/pyarena.h new file mode 100644 index 000000000..5f193fece --- /dev/null +++ b/python/include/pyarena.h @@ -0,0 +1,62 @@ +/* An arena-like memory interface for the compiler. + */ + +#ifndef Py_PYARENA_H +#define Py_PYARENA_H + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct _arena PyArena; + + /* PyArena_New() and PyArena_Free() create a new arena and free it, + respectively. Once an arena has been created, it can be used + to allocate memory via PyArena_Malloc(). Pointers to PyObject can + also be registered with the arena via PyArena_AddPyObject(), and the + arena will ensure that the PyObjects stay alive at least until + PyArena_Free() is called. When an arena is freed, all the memory it + allocated is freed, the arena releases internal references to registered + PyObject*, and none of its pointers are valid. + XXX (tim) What does "none of its pointers are valid" mean? Does it + XXX mean that pointers previously obtained via PyArena_Malloc() are + XXX no longer valid? (That's clearly true, but not sure that's what + XXX the text is trying to say.) + + PyArena_New() returns an arena pointer. On error, it + returns a negative number and sets an exception. + XXX (tim): Not true. On error, PyArena_New() actually returns NULL, + XXX and looks like it may or may not set an exception (e.g., if the + XXX internal PyList_New(0) returns NULL, PyArena_New() passes that on + XXX and an exception is set; OTOH, if the internal + XXX block_new(DEFAULT_BLOCK_SIZE) returns NULL, that's passed on but + XXX an exception is not set in that case). + */ + PyAPI_FUNC(PyArena *) PyArena_New(void); + PyAPI_FUNC(void) PyArena_Free(PyArena *); + + /* Mostly like malloc(), return the address of a block of memory spanning + * `size` bytes, or return NULL (without setting an exception) if enough + * new memory can't be obtained. Unlike malloc(0), PyArena_Malloc() with + * size=0 does not guarantee to return a unique pointer (the pointer + * returned may equal one or more other pointers obtained from + * PyArena_Malloc()). + * Note that pointers obtained via PyArena_Malloc() must never be passed to + * the system free() or realloc(), or to any of Python's similar memory- + * management functions. PyArena_Malloc()-obtained pointers remain valid + * until PyArena_Free(ar) is called, at which point all pointers obtained + * from the arena `ar` become invalid simultaneously. + */ + PyAPI_FUNC(void *) PyArena_Malloc(PyArena *, size_t size); + + /* This routine isn't a proper arena allocation routine. It takes + * a PyObject* and records it so that it can be DECREFed when the + * arena is freed. + */ + PyAPI_FUNC(int) PyArena_AddPyObject(PyArena *, PyObject *); + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYARENA_H */ diff --git a/python/include/pycapsule.h b/python/include/pycapsule.h new file mode 100644 index 000000000..cd682fc7d --- /dev/null +++ b/python/include/pycapsule.h @@ -0,0 +1,56 @@ + +/* Capsule objects let you wrap a C "void *" pointer in a Python + object. They're a way of passing data through the Python interpreter + without creating your own custom type. + + Capsules are used for communication between extension modules. + They provide a way for an extension module to export a C interface + to other extension modules, so that extension modules can use the + Python import mechanism to link to one another. + + For more information, please see "c-api/capsule.html" in the + documentation. +*/ + +#ifndef Py_CAPSULE_H +#define Py_CAPSULE_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(PyTypeObject) PyCapsule_Type; + +typedef void (*PyCapsule_Destructor)(PyObject *); + +#define PyCapsule_CheckExact(op) (Py_TYPE(op) == &PyCapsule_Type) + + +PyAPI_FUNC(PyObject *) PyCapsule_New( + void *pointer, + const char *name, + PyCapsule_Destructor destructor); + +PyAPI_FUNC(void *) PyCapsule_GetPointer(PyObject *capsule, const char *name); + +PyAPI_FUNC(PyCapsule_Destructor) PyCapsule_GetDestructor(PyObject *capsule); + +PyAPI_FUNC(const char *) PyCapsule_GetName(PyObject *capsule); + +PyAPI_FUNC(void *) PyCapsule_GetContext(PyObject *capsule); + +PyAPI_FUNC(int) PyCapsule_IsValid(PyObject *capsule, const char *name); + +PyAPI_FUNC(int) PyCapsule_SetPointer(PyObject *capsule, void *pointer); + +PyAPI_FUNC(int) PyCapsule_SetDestructor(PyObject *capsule, PyCapsule_Destructor destructor); + +PyAPI_FUNC(int) PyCapsule_SetName(PyObject *capsule, const char *name); + +PyAPI_FUNC(int) PyCapsule_SetContext(PyObject *capsule, void *context); + +PyAPI_FUNC(void *) PyCapsule_Import(const char *name, int no_block); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_CAPSULE_H */ diff --git a/python/include/pyconfig.h b/python/include/pyconfig.h new file mode 100644 index 000000000..1cfc59b8c --- /dev/null +++ b/python/include/pyconfig.h @@ -0,0 +1,759 @@ +#ifndef Py_CONFIG_H +#define Py_CONFIG_H + +/* pyconfig.h. NOT Generated automatically by configure. + +This is a manually maintained version used for the Watcom, +Borland and Microsoft Visual C++ compilers. It is a +standard part of the Python distribution. + +WINDOWS DEFINES: +The code specific to Windows should be wrapped around one of +the following #defines + +MS_WIN64 - Code specific to the MS Win64 API +MS_WIN32 - Code specific to the MS Win32 (and Win64) API (obsolete, this covers all supported APIs) +MS_WINDOWS - Code specific to Windows, but all versions. +MS_WINCE - Code specific to Windows CE +Py_ENABLE_SHARED - Code if the Python core is built as a DLL. + +Also note that neither "_M_IX86" or "_MSC_VER" should be used for +any purpose other than "Windows Intel x86 specific" and "Microsoft +compiler specific". Therefore, these should be very rare. + + +NOTE: The following symbols are deprecated: +NT, USE_DL_EXPORT, USE_DL_IMPORT, DL_EXPORT, DL_IMPORT +MS_CORE_DLL. + +WIN32 is still required for the locale module. + +*/ + +#ifdef _WIN32_WCE +#define MS_WINCE +#endif + +/* Deprecated USE_DL_EXPORT macro - please use Py_BUILD_CORE */ +#ifdef USE_DL_EXPORT +# define Py_BUILD_CORE +#endif /* USE_DL_EXPORT */ + +/* Visual Studio 2005 introduces deprecation warnings for + "insecure" and POSIX functions. The insecure functions should + be replaced by *_s versions (according to Microsoft); the + POSIX functions by _* versions (which, according to Microsoft, + would be ISO C conforming). Neither renaming is feasible, so + we just silence the warnings. */ + +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif + +/* Windows CE does not have these */ +#ifndef MS_WINCE +#define HAVE_IO_H +#define HAVE_SYS_UTIME_H +#define HAVE_TEMPNAM +#define HAVE_TMPFILE +#define HAVE_TMPNAM +#define HAVE_CLOCK +#define HAVE_STRERROR +#endif + +#ifdef HAVE_IO_H +#include +#endif + +#define HAVE_HYPOT +#define HAVE_STRFTIME +#define DONT_HAVE_SIG_ALARM +#define DONT_HAVE_SIG_PAUSE +#define LONG_BIT 32 +#define WORD_BIT 32 +#define PREFIX "" +#define EXEC_PREFIX "" + +#define MS_WIN32 /* only support win32 and greater. */ +#define MS_WINDOWS +#ifndef PYTHONPATH +# define PYTHONPATH ".\\DLLs;.\\lib;.\\lib\\plat-win;.\\lib\\lib-tk" +#endif +#define NT_THREADS +#define WITH_THREAD +#ifndef NETSCAPE_PI +#define USE_SOCKET +#endif + +/* CE6 doesn't have strdup() but _strdup(). Assume the same for earlier versions. */ +#if defined(MS_WINCE) +# include +# define strdup _strdup +#endif + +#ifdef MS_WINCE +/* Windows CE does not support environment variables */ +#define getenv(v) (NULL) +#define environ (NULL) +#endif + +/* Compiler specific defines */ + +/* ------------------------------------------------------------------------*/ +/* Microsoft C defines _MSC_VER */ +#ifdef _MSC_VER + +/* We want COMPILER to expand to a string containing _MSC_VER's *value*. + * This is horridly tricky, because the stringization operator only works + * on macro arguments, and doesn't evaluate macros passed *as* arguments. + * Attempts simpler than the following appear doomed to produce "_MSC_VER" + * literally in the string. + */ +#define _Py_PASTE_VERSION(SUFFIX) \ + ("[MSC v." _Py_STRINGIZE(_MSC_VER) " " SUFFIX "]") +/* e.g., this produces, after compile-time string catenation, + * ("[MSC v.1200 32 bit (Intel)]") + * + * _Py_STRINGIZE(_MSC_VER) expands to + * _Py_STRINGIZE1((_MSC_VER)) expands to + * _Py_STRINGIZE2(_MSC_VER) but as this call is the result of token-pasting + * it's scanned again for macros and so further expands to (under MSVC 6) + * _Py_STRINGIZE2(1200) which then expands to + * "1200" + */ +#define _Py_STRINGIZE(X) _Py_STRINGIZE1((X)) +#define _Py_STRINGIZE1(X) _Py_STRINGIZE2 ## X +#define _Py_STRINGIZE2(X) #X + +/* MSVC defines _WINxx to differentiate the windows platform types + + Note that for compatibility reasons _WIN32 is defined on Win32 + *and* on Win64. For the same reasons, in Python, MS_WIN32 is + defined on Win32 *and* Win64. Win32 only code must therefore be + guarded as follows: + #if defined(MS_WIN32) && !defined(MS_WIN64) + Some modules are disabled on Itanium processors, therefore we + have MS_WINI64 set for those targets, otherwise MS_WINX64 +*/ +#ifdef _WIN64 +#define MS_WIN64 +#endif + +/* set the COMPILER */ +#ifdef MS_WIN64 +#if defined(_M_IA64) +#define COMPILER _Py_PASTE_VERSION("64 bit (Itanium)") +#define MS_WINI64 +#elif defined(_M_X64) || defined(_M_AMD64) +#define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") +#define MS_WINX64 +#else +#define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") +#endif +#endif /* MS_WIN64 */ + +/* set the version macros for the windows headers */ +#ifdef MS_WINX64 +/* 64 bit only runs on XP or greater */ +#define Py_WINVER _WIN32_WINNT_WINXP +#define Py_NTDDI NTDDI_WINXP +#else +/* Python 2.6+ requires Windows 2000 or greater */ +#ifdef _WIN32_WINNT_WIN2K +#define Py_WINVER _WIN32_WINNT_WIN2K +#else +#define Py_WINVER 0x0500 +#endif +#define Py_NTDDI NTDDI_WIN2KSP4 +#endif + +/* We only set these values when building Python - we don't want to force + these values on extensions, as that will affect the prototypes and + structures exposed in the Windows headers. Even when building Python, we + allow a single source file to override this - they may need access to + structures etc so it can optionally use new Windows features if it + determines at runtime they are available. +*/ +#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_MODULE) +#ifndef NTDDI_VERSION +#define NTDDI_VERSION Py_NTDDI +#endif +#ifndef WINVER +#define WINVER Py_WINVER +#endif +#ifndef _WIN32_WINNT +#define _WIN32_WINNT Py_WINVER +#endif +#endif + +/* _W64 is not defined for VC6 or eVC4 */ +#ifndef _W64 +#define _W64 +#endif + +/* Define like size_t, omitting the "unsigned" */ +#ifdef MS_WIN64 +typedef __int64 ssize_t; +#else +typedef _W64 int ssize_t; +#endif +#define HAVE_SSIZE_T 1 + +#if defined(MS_WIN32) && !defined(MS_WIN64) +#ifdef _M_IX86 +#define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") +#else +#define COMPILER _Py_PASTE_VERSION("32 bit (Unknown)") +#endif +#endif /* MS_WIN32 && !MS_WIN64 */ + +typedef int pid_t; + +#include +#define Py_IS_NAN _isnan +#define Py_IS_INFINITY(X) (!_finite(X) && !_isnan(X)) +#define Py_IS_FINITE(X) _finite(X) +#define copysign _copysign +#define hypot _hypot + +#endif /* _MSC_VER */ + +/* define some ANSI types that are not defined in earlier Win headers */ +#if defined(_MSC_VER) && _MSC_VER >= 1200 +/* This file only exists in VC 6.0 or higher */ +#include +#endif + +/* ------------------------------------------------------------------------*/ +/* The Borland compiler defines __BORLANDC__ */ +/* XXX These defines are likely incomplete, but should be easy to fix. */ +#ifdef __BORLANDC__ +#define COMPILER "[Borland]" + +#ifdef _WIN32 +/* tested with BCC 5.5 (__BORLANDC__ >= 0x0550) + */ + +typedef int pid_t; +/* BCC55 seems to understand __declspec(dllimport), it is used in its + own header files (winnt.h, ...) - so we can do nothing and get the default*/ + +#undef HAVE_SYS_UTIME_H +#define HAVE_UTIME_H +#define HAVE_DIRENT_H + +/* rename a few functions for the Borland compiler */ +#include +#define _chsize chsize +#define _setmode setmode + +#else /* !_WIN32 */ +#error "Only Win32 and later are supported" +#endif /* !_WIN32 */ + +#endif /* BORLANDC */ + +/* ------------------------------------------------------------------------*/ +/* egcs/gnu-win32 defines __GNUC__ and _WIN32 */ +#if defined(__GNUC__) && defined(_WIN32) +/* XXX These defines are likely incomplete, but should be easy to fix. + They should be complete enough to build extension modules. */ +/* Suggested by Rene Liebscher to avoid a GCC 2.91.* + bug that requires structure imports. More recent versions of the + compiler don't exhibit this bug. +*/ +#if (__GNUC__==2) && (__GNUC_MINOR__<=91) +#warning "Please use an up-to-date version of gcc! (>2.91 recommended)" +#endif + +#define COMPILER "[gcc]" +#define hypot _hypot +#define PY_LONG_LONG long long +#define PY_LLONG_MIN LLONG_MIN +#define PY_LLONG_MAX LLONG_MAX +#define PY_ULLONG_MAX ULLONG_MAX +#endif /* GNUC */ + +/* ------------------------------------------------------------------------*/ +/* lcc-win32 defines __LCC__ */ +#if defined(__LCC__) +/* XXX These defines are likely incomplete, but should be easy to fix. + They should be complete enough to build extension modules. */ + +#define COMPILER "[lcc-win32]" +typedef int pid_t; +/* __declspec() is supported here too - do nothing to get the defaults */ + +#endif /* LCC */ + +/* ------------------------------------------------------------------------*/ +/* End of compilers - finish up */ + +#ifndef NO_STDIO_H +# include +#endif + +/* 64 bit ints are usually spelt __int64 unless compiler has overridden */ +#define HAVE_LONG_LONG 1 +#ifndef PY_LONG_LONG +# define PY_LONG_LONG __int64 +# define PY_LLONG_MAX _I64_MAX +# define PY_LLONG_MIN _I64_MIN +# define PY_ULLONG_MAX _UI64_MAX +#endif + +/* For Windows the Python core is in a DLL by default. Test +Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ +#if !defined(MS_NO_COREDLL) && !defined(Py_NO_ENABLE_SHARED) +# define Py_ENABLE_SHARED 1 /* standard symbol for shared library */ +# define MS_COREDLL /* deprecated old symbol */ +#endif /* !MS_NO_COREDLL && ... */ + +/* All windows compilers that use this header support __declspec */ +#define HAVE_DECLSPEC_DLL + +/* For an MSVC DLL, we can nominate the .lib files used by extensions */ +#ifdef MS_COREDLL +# ifndef Py_BUILD_CORE /* not building the core - must be an ext */ +# if defined(_MSC_VER) + /* So MSVC users need not specify the .lib file in + their Makefile (other compilers are generally + taken care of by distutils.) */ +# ifdef _DEBUG +# pragma comment(lib,"python27_d.lib") +# else +# pragma comment(lib,"python27.lib") +# endif /* _DEBUG */ +# endif /* _MSC_VER */ +# endif /* Py_BUILD_CORE */ +#endif /* MS_COREDLL */ + +#if defined(MS_WIN64) +/* maintain "win32" sys.platform for backward compatibility of Python code, + the Win64 API should be close enough to the Win32 API to make this + preferable */ +# define PLATFORM "win32" +# define SIZEOF_VOID_P 8 +# define SIZEOF_TIME_T 8 +# define SIZEOF_OFF_T 4 +# define SIZEOF_FPOS_T 8 +# define SIZEOF_HKEY 8 +# define SIZEOF_SIZE_T 8 +/* configure.in defines HAVE_LARGEFILE_SUPPORT iff HAVE_LONG_LONG, + sizeof(off_t) > sizeof(long), and sizeof(PY_LONG_LONG) >= sizeof(off_t). + On Win64 the second condition is not true, but if fpos_t replaces off_t + then this is true. The uses of HAVE_LARGEFILE_SUPPORT imply that Win64 + should define this. */ +# define HAVE_LARGEFILE_SUPPORT +#elif defined(MS_WIN32) +# define PLATFORM "win32" +# define HAVE_LARGEFILE_SUPPORT +# define SIZEOF_VOID_P 4 +# define SIZEOF_OFF_T 4 +# define SIZEOF_FPOS_T 8 +# define SIZEOF_HKEY 4 +# define SIZEOF_SIZE_T 4 + /* MS VS2005 changes time_t to an 64-bit type on all platforms */ +# if defined(_MSC_VER) && _MSC_VER >= 1400 +# define SIZEOF_TIME_T 8 +# else +# define SIZEOF_TIME_T 4 +# endif +#endif + +#ifdef _DEBUG +# define Py_DEBUG +#endif + + +#ifdef MS_WIN32 + +#define SIZEOF_SHORT 2 +#define SIZEOF_INT 4 +#define SIZEOF_LONG 4 +#define SIZEOF_LONG_LONG 8 +#define SIZEOF_DOUBLE 8 +#define SIZEOF_FLOAT 4 + +/* VC 7.1 has them and VC 6.0 does not. VC 6.0 has a version number of 1200. + Microsoft eMbedded Visual C++ 4.0 has a version number of 1201 and doesn't + define these. + If some compiler does not provide them, modify the #if appropriately. */ +#if defined(_MSC_VER) +#if _MSC_VER > 1300 +#define HAVE_UINTPTR_T 1 +#define HAVE_INTPTR_T 1 +#else +/* VC6, VS 2002 and eVC4 don't support the C99 LL suffix for 64-bit integer literals */ +#define Py_LL(x) x##I64 +#endif /* _MSC_VER > 1200 */ +#endif /* _MSC_VER */ + +#endif + +/* define signed and unsigned exact-width 32-bit and 64-bit types, used in the + implementation of Python long integers. */ +#ifndef PY_UINT32_T +#if SIZEOF_INT == 4 +#define HAVE_UINT32_T 1 +#define PY_UINT32_T unsigned int +#elif SIZEOF_LONG == 4 +#define HAVE_UINT32_T 1 +#define PY_UINT32_T unsigned long +#endif +#endif + +#ifndef PY_UINT64_T +#if SIZEOF_LONG_LONG == 8 +#define HAVE_UINT64_T 1 +#define PY_UINT64_T unsigned PY_LONG_LONG +#endif +#endif + +#ifndef PY_INT32_T +#if SIZEOF_INT == 4 +#define HAVE_INT32_T 1 +#define PY_INT32_T int +#elif SIZEOF_LONG == 4 +#define HAVE_INT32_T 1 +#define PY_INT32_T long +#endif +#endif + +#ifndef PY_INT64_T +#if SIZEOF_LONG_LONG == 8 +#define HAVE_INT64_T 1 +#define PY_INT64_T PY_LONG_LONG +#endif +#endif + +/* Fairly standard from here! */ + +/* Define to 1 if you have the `copysign' function. */ +#define HAVE_COPYSIGN 1 + +/* Define to 1 if you have the `isinf' macro. */ +#define HAVE_DECL_ISINF 1 + +/* Define to 1 if you have the `isnan' function. */ +#define HAVE_DECL_ISNAN 1 + +/* Define if on AIX 3. + System headers sometimes define this. + We just want to avoid a redefinition error message. */ +#ifndef _ALL_SOURCE +/* #undef _ALL_SOURCE */ +#endif + +/* Define to empty if the keyword does not work. */ +/* #define const */ + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_CONIO_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_DIRECT_H 1 +#endif + +/* Define if you have dirent.h. */ +/* #define DIRENT 1 */ + +/* Define to the type of elements in the array set by `getgroups'. + Usually this is either `int' or `gid_t'. */ +/* #undef GETGROUPS_T */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define if your struct tm has tm_zone. */ +/* #undef HAVE_TM_ZONE */ + +/* Define if you don't have tm_zone but do have the external array + tzname. */ +#define HAVE_TZNAME + +/* Define to `int' if doesn't define. */ +/* #undef mode_t */ + +/* Define if you don't have dirent.h, but have ndir.h. */ +/* #undef NDIR */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `int' if doesn't define. */ +/* #undef pid_t */ + +/* Define if the system does not provide POSIX.1 features except + with this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define as the return type of signal handlers (int or void). */ +#define RETSIGTYPE void + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if you don't have dirent.h, but have sys/dir.h. */ +/* #undef SYSDIR */ + +/* Define if you don't have dirent.h, but have sys/ndir.h. */ +/* #undef SYSNDIR */ + +/* Define if you can safely include both and . */ +/* #undef TIME_WITH_SYS_TIME */ + +/* Define if your declares struct tm. */ +/* #define TM_IN_SYS_TIME 1 */ + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define if the closedir function returns void instead of int. */ +/* #undef VOID_CLOSEDIR */ + +/* Define if getpgrp() must be called as getpgrp(0) + and (consequently) setpgrp() as setpgrp(0, 0). */ +/* #undef GETPGRP_HAVE_ARGS */ + +/* Define this if your time.h defines altzone */ +/* #define HAVE_ALTZONE */ + +/* Define if you have the putenv function. */ +#ifndef MS_WINCE +#define HAVE_PUTENV +#endif + +/* Define if your compiler supports function prototypes */ +#define HAVE_PROTOTYPES + +/* Define if you can safely include both and + (which you can't on SCO ODT 3.0). */ +/* #undef SYS_SELECT_WITH_SYS_TIME */ + +/* Define if you want documentation strings in extension modules */ +#define WITH_DOC_STRINGS 1 + +/* Define if you want to compile in rudimentary thread support */ +/* #undef WITH_THREAD */ + +/* Define if you want to use the GNU readline library */ +/* #define WITH_READLINE 1 */ + +/* Define if you want to have a Unicode type. */ +#define Py_USING_UNICODE + +/* Define as the size of the unicode type. */ +/* This is enough for unicodeobject.h to do the "right thing" on Windows. */ +#define Py_UNICODE_SIZE 2 + +/* Use Python's own small-block memory-allocator. */ +#define WITH_PYMALLOC 1 + +/* Define if you have clock. */ +/* #define HAVE_CLOCK */ + +/* Define when any dynamic module loading is enabled */ +#define HAVE_DYNAMIC_LOADING + +/* Define if you have ftime. */ +#ifndef MS_WINCE +#define HAVE_FTIME +#endif + +/* Define if you have getpeername. */ +#define HAVE_GETPEERNAME + +/* Define if you have getpgrp. */ +/* #undef HAVE_GETPGRP */ + +/* Define if you have getpid. */ +#ifndef MS_WINCE +#define HAVE_GETPID +#endif + +/* Define if you have gettimeofday. */ +/* #undef HAVE_GETTIMEOFDAY */ + +/* Define if you have getwd. */ +/* #undef HAVE_GETWD */ + +/* Define if you have lstat. */ +/* #undef HAVE_LSTAT */ + +/* Define if you have the mktime function. */ +#define HAVE_MKTIME + +/* Define if you have nice. */ +/* #undef HAVE_NICE */ + +/* Define if you have readlink. */ +/* #undef HAVE_READLINK */ + +/* Define if you have select. */ +/* #undef HAVE_SELECT */ + +/* Define if you have setpgid. */ +/* #undef HAVE_SETPGID */ + +/* Define if you have setpgrp. */ +/* #undef HAVE_SETPGRP */ + +/* Define if you have setsid. */ +/* #undef HAVE_SETSID */ + +/* Define if you have setvbuf. */ +#define HAVE_SETVBUF + +/* Define if you have siginterrupt. */ +/* #undef HAVE_SIGINTERRUPT */ + +/* Define if you have symlink. */ +/* #undef HAVE_SYMLINK */ + +/* Define if you have tcgetpgrp. */ +/* #undef HAVE_TCGETPGRP */ + +/* Define if you have tcsetpgrp. */ +/* #undef HAVE_TCSETPGRP */ + +/* Define if you have times. */ +/* #undef HAVE_TIMES */ + +/* Define if you have uname. */ +/* #undef HAVE_UNAME */ + +/* Define if you have waitpid. */ +/* #undef HAVE_WAITPID */ + +/* Define to 1 if you have the `wcscoll' function. */ +#ifndef MS_WINCE +#define HAVE_WCSCOLL 1 +#endif + +/* Define if the zlib library has inflateCopy */ +#define HAVE_ZLIB_COPY 1 + +/* Define if you have the header file. */ +/* #undef HAVE_DLFCN_H */ + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_ERRNO_H 1 +#endif + +/* Define if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_FCNTL_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_PROCESS_H 1 +#endif + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_SIGNAL_H 1 +#endif + +/* Define if you have the prototypes. */ +#define HAVE_STDARG_PROTOTYPES + +/* Define if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_AUDIOIO_H */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_PARAM_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_SELECT_H 1 */ + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_SYS_STAT_H 1 +#endif + +/* Define if you have the header file. */ +/* #define HAVE_SYS_TIME_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_TIMES_H 1 */ + +/* Define to 1 if you have the header file. */ +#ifndef MS_WINCE +#define HAVE_SYS_TYPES_H 1 +#endif + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UN_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UTIME_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_SYS_UTSNAME_H 1 */ + +/* Define if you have the header file. */ +/* #undef HAVE_THREAD_H */ + +/* Define if you have the header file. */ +/* #define HAVE_UNISTD_H 1 */ + +/* Define if you have the header file. */ +/* #define HAVE_UTIME_H 1 */ + +/* Define if the compiler provides a wchar.h header file. */ +#define HAVE_WCHAR_H 1 + +/* Define if you have the dl library (-ldl). */ +/* #undef HAVE_LIBDL */ + +/* Define if you have the mpc library (-lmpc). */ +/* #undef HAVE_LIBMPC */ + +/* Define if you have the nsl library (-lnsl). */ +#define HAVE_LIBNSL 1 + +/* Define if you have the seq library (-lseq). */ +/* #undef HAVE_LIBSEQ */ + +/* Define if you have the socket library (-lsocket). */ +#define HAVE_LIBSOCKET 1 + +/* Define if you have the sun library (-lsun). */ +/* #undef HAVE_LIBSUN */ + +/* Define if you have the termcap library (-ltermcap). */ +/* #undef HAVE_LIBTERMCAP */ + +/* Define if you have the termlib library (-ltermlib). */ +/* #undef HAVE_LIBTERMLIB */ + +/* Define if you have the thread library (-lthread). */ +/* #undef HAVE_LIBTHREAD */ + +/* WinSock does not use a bitmask in select, and uses + socket handles greater than FD_SETSIZE */ +#define Py_SOCKET_FD_CAN_BE_GE_FD_SETSIZE + +/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the + least significant byte first */ +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1 + +#endif /* !Py_CONFIG_H */ diff --git a/python/include/pyctype.h b/python/include/pyctype.h new file mode 100644 index 000000000..673cf2eb0 --- /dev/null +++ b/python/include/pyctype.h @@ -0,0 +1,31 @@ +#ifndef PYCTYPE_H +#define PYCTYPE_H + +#define PY_CTF_LOWER 0x01 +#define PY_CTF_UPPER 0x02 +#define PY_CTF_ALPHA (PY_CTF_LOWER|PY_CTF_UPPER) +#define PY_CTF_DIGIT 0x04 +#define PY_CTF_ALNUM (PY_CTF_ALPHA|PY_CTF_DIGIT) +#define PY_CTF_SPACE 0x08 +#define PY_CTF_XDIGIT 0x10 + +PyAPI_DATA(const unsigned int) _Py_ctype_table[256]; + +/* Unlike their C counterparts, the following macros are not meant to + * handle an int with any of the values [EOF, 0-UCHAR_MAX]. The argument + * must be a signed/unsigned char. */ +#define Py_ISLOWER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_LOWER) +#define Py_ISUPPER(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_UPPER) +#define Py_ISALPHA(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALPHA) +#define Py_ISDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_DIGIT) +#define Py_ISXDIGIT(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_XDIGIT) +#define Py_ISALNUM(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_ALNUM) +#define Py_ISSPACE(c) (_Py_ctype_table[Py_CHARMASK(c)] & PY_CTF_SPACE) + +PyAPI_DATA(const unsigned char) _Py_ctype_tolower[256]; +PyAPI_DATA(const unsigned char) _Py_ctype_toupper[256]; + +#define Py_TOLOWER(c) (_Py_ctype_tolower[Py_CHARMASK(c)]) +#define Py_TOUPPER(c) (_Py_ctype_toupper[Py_CHARMASK(c)]) + +#endif /* !PYCTYPE_H */ diff --git a/python/include/pydebug.h b/python/include/pydebug.h new file mode 100644 index 000000000..0f45960f9 --- /dev/null +++ b/python/include/pydebug.h @@ -0,0 +1,41 @@ + +#ifndef Py_PYDEBUG_H +#define Py_PYDEBUG_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(int) Py_DebugFlag; +PyAPI_DATA(int) Py_VerboseFlag; +PyAPI_DATA(int) Py_InteractiveFlag; +PyAPI_DATA(int) Py_InspectFlag; +PyAPI_DATA(int) Py_OptimizeFlag; +PyAPI_DATA(int) Py_NoSiteFlag; +PyAPI_DATA(int) Py_BytesWarningFlag; +PyAPI_DATA(int) Py_UseClassExceptionsFlag; +PyAPI_DATA(int) Py_FrozenFlag; +PyAPI_DATA(int) Py_TabcheckFlag; +PyAPI_DATA(int) Py_UnicodeFlag; +PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; +PyAPI_DATA(int) Py_DivisionWarningFlag; +PyAPI_DATA(int) Py_DontWriteBytecodeFlag; +PyAPI_DATA(int) Py_NoUserSiteDirectory; +/* _XXX Py_QnewFlag should go away in 3.0. It's true iff -Qnew is passed, + on the command line, and is used in 2.2 by ceval.c to make all "/" divisions + true divisions (which they will be in 3.0). */ +PyAPI_DATA(int) _Py_QnewFlag; +/* Warn about 3.x issues */ +PyAPI_DATA(int) Py_Py3kWarningFlag; +PyAPI_DATA(int) Py_HashRandomizationFlag; + +/* this is a wrapper around getenv() that pays attention to + Py_IgnoreEnvironmentFlag. It should be used for getting variables like + PYTHONPATH and PYTHONHOME from the environment */ +#define Py_GETENV(s) (Py_IgnoreEnvironmentFlag ? NULL : getenv(s)) + +PyAPI_FUNC(void) Py_FatalError(const char *message); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYDEBUG_H */ diff --git a/python/include/pyerrors.h b/python/include/pyerrors.h new file mode 100644 index 000000000..dbe3bfa5f --- /dev/null +++ b/python/include/pyerrors.h @@ -0,0 +1,328 @@ +#ifndef Py_ERRORS_H +#define Py_ERRORS_H +#ifdef __cplusplus +extern "C" { +#endif + +/* Error objects */ + +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; +} PyBaseExceptionObject; + +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; + PyObject *msg; + PyObject *filename; + PyObject *lineno; + PyObject *offset; + PyObject *text; + PyObject *print_file_and_line; +} PySyntaxErrorObject; + +#ifdef Py_USING_UNICODE +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; + PyObject *encoding; + PyObject *object; + Py_ssize_t start; + Py_ssize_t end; + PyObject *reason; +} PyUnicodeErrorObject; +#endif + +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; + PyObject *code; +} PySystemExitObject; + +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; + PyObject *myerrno; + PyObject *strerror; + PyObject *filename; +} PyEnvironmentErrorObject; + +#ifdef MS_WINDOWS +typedef struct { + PyObject_HEAD + PyObject *dict; + PyObject *args; + PyObject *message; + PyObject *myerrno; + PyObject *strerror; + PyObject *filename; + PyObject *winerror; +} PyWindowsErrorObject; +#endif + +/* Error handling definitions */ + +PyAPI_FUNC(void) PyErr_SetNone(PyObject *); +PyAPI_FUNC(void) PyErr_SetObject(PyObject *, PyObject *); +PyAPI_FUNC(void) PyErr_SetString(PyObject *, const char *); +PyAPI_FUNC(PyObject *) PyErr_Occurred(void); +PyAPI_FUNC(void) PyErr_Clear(void); +PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **); +PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *); + +#ifdef Py_DEBUG +#define _PyErr_OCCURRED() PyErr_Occurred() +#else +#define _PyErr_OCCURRED() (_PyThreadState_Current->curexc_type) +#endif + +/* Error testing and normalization */ +PyAPI_FUNC(int) PyErr_GivenExceptionMatches(PyObject *, PyObject *); +PyAPI_FUNC(int) PyErr_ExceptionMatches(PyObject *); +PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**); + +/* */ + +#define PyExceptionClass_Check(x) \ + (PyClass_Check((x)) || (PyType_Check((x)) && \ + PyType_FastSubclass((PyTypeObject*)(x), Py_TPFLAGS_BASE_EXC_SUBCLASS))) + +#define PyExceptionInstance_Check(x) \ + (PyInstance_Check((x)) || \ + PyType_FastSubclass((x)->ob_type, Py_TPFLAGS_BASE_EXC_SUBCLASS)) + +#define PyExceptionClass_Name(x) \ + (PyClass_Check((x)) \ + ? PyString_AS_STRING(((PyClassObject*)(x))->cl_name) \ + : (char *)(((PyTypeObject*)(x))->tp_name)) + +#define PyExceptionInstance_Class(x) \ + ((PyInstance_Check((x)) \ + ? (PyObject*)((PyInstanceObject*)(x))->in_class \ + : (PyObject*)((x)->ob_type))) + + +/* Predefined exceptions */ + +PyAPI_DATA(PyObject *) PyExc_BaseException; +PyAPI_DATA(PyObject *) PyExc_Exception; +PyAPI_DATA(PyObject *) PyExc_StopIteration; +PyAPI_DATA(PyObject *) PyExc_GeneratorExit; +PyAPI_DATA(PyObject *) PyExc_StandardError; +PyAPI_DATA(PyObject *) PyExc_ArithmeticError; +PyAPI_DATA(PyObject *) PyExc_LookupError; + +PyAPI_DATA(PyObject *) PyExc_AssertionError; +PyAPI_DATA(PyObject *) PyExc_AttributeError; +PyAPI_DATA(PyObject *) PyExc_EOFError; +PyAPI_DATA(PyObject *) PyExc_FloatingPointError; +PyAPI_DATA(PyObject *) PyExc_EnvironmentError; +PyAPI_DATA(PyObject *) PyExc_IOError; +PyAPI_DATA(PyObject *) PyExc_OSError; +PyAPI_DATA(PyObject *) PyExc_ImportError; +PyAPI_DATA(PyObject *) PyExc_IndexError; +PyAPI_DATA(PyObject *) PyExc_KeyError; +PyAPI_DATA(PyObject *) PyExc_KeyboardInterrupt; +PyAPI_DATA(PyObject *) PyExc_MemoryError; +PyAPI_DATA(PyObject *) PyExc_NameError; +PyAPI_DATA(PyObject *) PyExc_OverflowError; +PyAPI_DATA(PyObject *) PyExc_RuntimeError; +PyAPI_DATA(PyObject *) PyExc_NotImplementedError; +PyAPI_DATA(PyObject *) PyExc_SyntaxError; +PyAPI_DATA(PyObject *) PyExc_IndentationError; +PyAPI_DATA(PyObject *) PyExc_TabError; +PyAPI_DATA(PyObject *) PyExc_ReferenceError; +PyAPI_DATA(PyObject *) PyExc_SystemError; +PyAPI_DATA(PyObject *) PyExc_SystemExit; +PyAPI_DATA(PyObject *) PyExc_TypeError; +PyAPI_DATA(PyObject *) PyExc_UnboundLocalError; +PyAPI_DATA(PyObject *) PyExc_UnicodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeEncodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeDecodeError; +PyAPI_DATA(PyObject *) PyExc_UnicodeTranslateError; +PyAPI_DATA(PyObject *) PyExc_ValueError; +PyAPI_DATA(PyObject *) PyExc_ZeroDivisionError; +#ifdef MS_WINDOWS +PyAPI_DATA(PyObject *) PyExc_WindowsError; +#endif +#ifdef __VMS +PyAPI_DATA(PyObject *) PyExc_VMSError; +#endif + +PyAPI_DATA(PyObject *) PyExc_BufferError; + +PyAPI_DATA(PyObject *) PyExc_MemoryErrorInst; +PyAPI_DATA(PyObject *) PyExc_RecursionErrorInst; + +/* Predefined warning categories */ +PyAPI_DATA(PyObject *) PyExc_Warning; +PyAPI_DATA(PyObject *) PyExc_UserWarning; +PyAPI_DATA(PyObject *) PyExc_DeprecationWarning; +PyAPI_DATA(PyObject *) PyExc_PendingDeprecationWarning; +PyAPI_DATA(PyObject *) PyExc_SyntaxWarning; +PyAPI_DATA(PyObject *) PyExc_RuntimeWarning; +PyAPI_DATA(PyObject *) PyExc_FutureWarning; +PyAPI_DATA(PyObject *) PyExc_ImportWarning; +PyAPI_DATA(PyObject *) PyExc_UnicodeWarning; +PyAPI_DATA(PyObject *) PyExc_BytesWarning; + + +/* Convenience functions */ + +PyAPI_FUNC(int) PyErr_BadArgument(void); +PyAPI_FUNC(PyObject *) PyErr_NoMemory(void); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObject( + PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename( + PyObject *, const char *); +#ifdef MS_WINDOWS +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename( + PyObject *, const Py_UNICODE *); +#endif /* MS_WINDOWS */ + +PyAPI_FUNC(PyObject *) PyErr_Format(PyObject *, const char *, ...) + Py_GCC_ATTRIBUTE((format(printf, 2, 3))); + +#ifdef MS_WINDOWS +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilenameObject( + int, const char *); +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilename( + int, const char *); +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithUnicodeFilename( + int, const Py_UNICODE *); +PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErr(int); +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilenameObject( + PyObject *,int, PyObject *); +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithFilename( + PyObject *,int, const char *); +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErrWithUnicodeFilename( + PyObject *,int, const Py_UNICODE *); +PyAPI_FUNC(PyObject *) PyErr_SetExcFromWindowsErr(PyObject *, int); +#endif /* MS_WINDOWS */ + +/* Export the old function so that the existing API remains available: */ +PyAPI_FUNC(void) PyErr_BadInternalCall(void); +PyAPI_FUNC(void) _PyErr_BadInternalCall(char *filename, int lineno); +/* Mask the old API with a call to the new API for code compiled under + Python 2.0: */ +#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) + +/* Function to create a new exception */ +PyAPI_FUNC(PyObject *) PyErr_NewException( + char *name, PyObject *base, PyObject *dict); +PyAPI_FUNC(PyObject *) PyErr_NewExceptionWithDoc( + char *name, char *doc, PyObject *base, PyObject *dict); +PyAPI_FUNC(void) PyErr_WriteUnraisable(PyObject *); + +/* In sigcheck.c or signalmodule.c */ +PyAPI_FUNC(int) PyErr_CheckSignals(void); +PyAPI_FUNC(void) PyErr_SetInterrupt(void); + +/* In signalmodule.c */ +int PySignal_SetWakeupFd(int fd); + +/* Support for adding program text to SyntaxErrors */ +PyAPI_FUNC(void) PyErr_SyntaxLocation(const char *, int); +PyAPI_FUNC(PyObject *) PyErr_ProgramText(const char *, int); + +#ifdef Py_USING_UNICODE +/* The following functions are used to create and modify unicode + exceptions from C */ + +/* create a UnicodeDecodeError object */ +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_Create( + const char *, const char *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *); + +/* create a UnicodeEncodeError object */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_Create( + const char *, const Py_UNICODE *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *); + +/* create a UnicodeTranslateError object */ +PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_Create( + const Py_UNICODE *, Py_ssize_t, Py_ssize_t, Py_ssize_t, const char *); + +/* get the encoding attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetEncoding(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetEncoding(PyObject *); + +/* get the object attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetObject(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetObject(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetObject(PyObject *); + +/* get the value of the start attribute (the int * may not be NULL) + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_GetStart(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeDecodeError_GetStart(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeTranslateError_GetStart(PyObject *, Py_ssize_t *); + +/* assign a new value to the start attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetStart(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetStart(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetStart(PyObject *, Py_ssize_t); + +/* get the value of the end attribute (the int *may not be NULL) + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_GetEnd(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeDecodeError_GetEnd(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) PyUnicodeTranslateError_GetEnd(PyObject *, Py_ssize_t *); + +/* assign a new value to the end attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetEnd(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetEnd(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetEnd(PyObject *, Py_ssize_t); + +/* get the value of the reason attribute */ +PyAPI_FUNC(PyObject *) PyUnicodeEncodeError_GetReason(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeDecodeError_GetReason(PyObject *); +PyAPI_FUNC(PyObject *) PyUnicodeTranslateError_GetReason(PyObject *); + +/* assign a new value to the reason attribute + return 0 on success, -1 on failure */ +PyAPI_FUNC(int) PyUnicodeEncodeError_SetReason( + PyObject *, const char *); +PyAPI_FUNC(int) PyUnicodeDecodeError_SetReason( + PyObject *, const char *); +PyAPI_FUNC(int) PyUnicodeTranslateError_SetReason( + PyObject *, const char *); +#endif + + +/* These APIs aren't really part of the error implementation, but + often needed to format error messages; the native C lib APIs are + not available on all platforms, which is why we provide emulations + for those platforms in Python/mysnprintf.c, + WARNING: The return value of snprintf varies across platforms; do + not rely on any particular behavior; eventually the C99 defn may + be reliable. +*/ +#if defined(MS_WIN32) && !defined(HAVE_SNPRINTF) +# define HAVE_SNPRINTF +# define snprintf _snprintf +# define vsnprintf _vsnprintf +#endif + +#include +PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 3, 4))); +PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va) + Py_GCC_ATTRIBUTE((format(printf, 3, 0))); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_ERRORS_H */ diff --git a/python/include/pyexpat.h b/python/include/pyexpat.h new file mode 100644 index 000000000..5340ef5fa --- /dev/null +++ b/python/include/pyexpat.h @@ -0,0 +1,48 @@ +/* Stuff to export relevant 'expat' entry points from pyexpat to other + * parser modules, such as cElementTree. */ + +/* note: you must import expat.h before importing this module! */ + +#define PyExpat_CAPI_MAGIC "pyexpat.expat_CAPI 1.0" +#define PyExpat_CAPSULE_NAME "pyexpat.expat_CAPI" + +struct PyExpat_CAPI +{ + char* magic; /* set to PyExpat_CAPI_MAGIC */ + int size; /* set to sizeof(struct PyExpat_CAPI) */ + int MAJOR_VERSION; + int MINOR_VERSION; + int MICRO_VERSION; + /* pointers to selected expat functions. add new functions at + the end, if needed */ + const XML_LChar * (*ErrorString)(enum XML_Error code); + enum XML_Error (*GetErrorCode)(XML_Parser parser); + XML_Size (*GetErrorColumnNumber)(XML_Parser parser); + XML_Size (*GetErrorLineNumber)(XML_Parser parser); + enum XML_Status (*Parse)( + XML_Parser parser, const char *s, int len, int isFinal); + XML_Parser (*ParserCreate_MM)( + const XML_Char *encoding, const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + void (*ParserFree)(XML_Parser parser); + void (*SetCharacterDataHandler)( + XML_Parser parser, XML_CharacterDataHandler handler); + void (*SetCommentHandler)( + XML_Parser parser, XML_CommentHandler handler); + void (*SetDefaultHandlerExpand)( + XML_Parser parser, XML_DefaultHandler handler); + void (*SetElementHandler)( + XML_Parser parser, XML_StartElementHandler start, + XML_EndElementHandler end); + void (*SetNamespaceDeclHandler)( + XML_Parser parser, XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + void (*SetProcessingInstructionHandler)( + XML_Parser parser, XML_ProcessingInstructionHandler handler); + void (*SetUnknownEncodingHandler)( + XML_Parser parser, XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + void (*SetUserData)(XML_Parser parser, void *userData); + /* always add new stuff to the end! */ +}; + diff --git a/python/include/pyfpe.h b/python/include/pyfpe.h new file mode 100644 index 000000000..19110ab05 --- /dev/null +++ b/python/include/pyfpe.h @@ -0,0 +1,176 @@ +#ifndef Py_PYFPE_H +#define Py_PYFPE_H +#ifdef __cplusplus +extern "C" { +#endif +/* + --------------------------------------------------------------------- + / Copyright (c) 1996. \ + | The Regents of the University of California. | + | All rights reserved. | + | | + | Permission to use, copy, modify, and distribute this software for | + | any purpose without fee is hereby granted, provided that this en- | + | tire notice is included in all copies of any software which is or | + | includes a copy or modification of this software and in all | + | copies of the supporting documentation for such software. | + | | + | This work was produced at the University of California, Lawrence | + | Livermore National Laboratory under contract no. W-7405-ENG-48 | + | between the U.S. Department of Energy and The Regents of the | + | University of California for the operation of UC LLNL. | + | | + | DISCLAIMER | + | | + | This software was prepared as an account of work sponsored by an | + | agency of the United States Government. Neither the United States | + | Government nor the University of California nor any of their em- | + | ployees, makes any warranty, express or implied, or assumes any | + | liability or responsibility for the accuracy, completeness, or | + | usefulness of any information, apparatus, product, or process | + | disclosed, or represents that its use would not infringe | + | privately-owned rights. Reference herein to any specific commer- | + | cial products, process, or service by trade name, trademark, | + | manufacturer, or otherwise, does not necessarily constitute or | + | imply its endorsement, recommendation, or favoring by the United | + | States Government or the University of California. The views and | + | opinions of authors expressed herein do not necessarily state or | + | reflect those of the United States Government or the University | + | of California, and shall not be used for advertising or product | + \ endorsement purposes. / + --------------------------------------------------------------------- +*/ + +/* + * Define macros for handling SIGFPE. + * Lee Busby, LLNL, November, 1996 + * busby1@llnl.gov + * + ********************************************* + * Overview of the system for handling SIGFPE: + * + * This file (Include/pyfpe.h) defines a couple of "wrapper" macros for + * insertion into your Python C code of choice. Their proper use is + * discussed below. The file Python/pyfpe.c defines a pair of global + * variables PyFPE_jbuf and PyFPE_counter which are used by the signal + * handler for SIGFPE to decide if a particular exception was protected + * by the macros. The signal handler itself, and code for enabling the + * generation of SIGFPE in the first place, is in a (new) Python module + * named fpectl. This module is standard in every respect. It can be loaded + * either statically or dynamically as you choose, and like any other + * Python module, has no effect until you import it. + * + * In the general case, there are three steps toward handling SIGFPE in any + * Python code: + * + * 1) Add the *_PROTECT macros to your C code as required to protect + * dangerous floating point sections. + * + * 2) Turn on the inclusion of the code by adding the ``--with-fpectl'' + * flag at the time you run configure. If the fpectl or other modules + * which use the *_PROTECT macros are to be dynamically loaded, be + * sure they are compiled with WANT_SIGFPE_HANDLER defined. + * + * 3) When python is built and running, import fpectl, and execute + * fpectl.turnon_sigfpe(). This sets up the signal handler and enables + * generation of SIGFPE whenever an exception occurs. From this point + * on, any properly trapped SIGFPE should result in the Python + * FloatingPointError exception. + * + * Step 1 has been done already for the Python kernel code, and should be + * done soon for the NumPy array package. Step 2 is usually done once at + * python install time. Python's behavior with respect to SIGFPE is not + * changed unless you also do step 3. Thus you can control this new + * facility at compile time, or run time, or both. + * + ******************************** + * Using the macros in your code: + * + * static PyObject *foobar(PyObject *self,PyObject *args) + * { + * .... + * PyFPE_START_PROTECT("Error in foobar", return 0) + * result = dangerous_op(somearg1, somearg2, ...); + * PyFPE_END_PROTECT(result) + * .... + * } + * + * If a floating point error occurs in dangerous_op, foobar returns 0 (NULL), + * after setting the associated value of the FloatingPointError exception to + * "Error in foobar". ``Dangerous_op'' can be a single operation, or a block + * of code, function calls, or any combination, so long as no alternate + * return is possible before the PyFPE_END_PROTECT macro is reached. + * + * The macros can only be used in a function context where an error return + * can be recognized as signaling a Python exception. (Generally, most + * functions that return a PyObject * will qualify.) + * + * Guido's original design suggestion for PyFPE_START_PROTECT and + * PyFPE_END_PROTECT had them open and close a local block, with a locally + * defined jmp_buf and jmp_buf pointer. This would allow recursive nesting + * of the macros. The Ansi C standard makes it clear that such local + * variables need to be declared with the "volatile" type qualifier to keep + * setjmp from corrupting their values. Some current implementations seem + * to be more restrictive. For example, the HPUX man page for setjmp says + * + * Upon the return from a setjmp() call caused by a longjmp(), the + * values of any non-static local variables belonging to the routine + * from which setjmp() was called are undefined. Code which depends on + * such values is not guaranteed to be portable. + * + * I therefore decided on a more limited form of nesting, using a counter + * variable (PyFPE_counter) to keep track of any recursion. If an exception + * occurs in an ``inner'' pair of macros, the return will apparently + * come from the outermost level. + * + */ + +#ifdef WANT_SIGFPE_HANDLER +#include +#include +#include +extern jmp_buf PyFPE_jbuf; +extern int PyFPE_counter; +extern double PyFPE_dummy(void *); + +#define PyFPE_START_PROTECT(err_string, leave_stmt) \ +if (!PyFPE_counter++ && setjmp(PyFPE_jbuf)) { \ + PyErr_SetString(PyExc_FloatingPointError, err_string); \ + PyFPE_counter = 0; \ + leave_stmt; \ +} + +/* + * This (following) is a heck of a way to decrement a counter. However, + * unless the macro argument is provided, code optimizers will sometimes move + * this statement so that it gets executed *before* the unsafe expression + * which we're trying to protect. That pretty well messes things up, + * of course. + * + * If the expression(s) you're trying to protect don't happen to return a + * value, you will need to manufacture a dummy result just to preserve the + * correct ordering of statements. Note that the macro passes the address + * of its argument (so you need to give it something which is addressable). + * If your expression returns multiple results, pass the last such result + * to PyFPE_END_PROTECT. + * + * Note that PyFPE_dummy returns a double, which is cast to int. + * This seeming insanity is to tickle the Floating Point Unit (FPU). + * If an exception has occurred in a preceding floating point operation, + * some architectures (notably Intel 80x86) will not deliver the interrupt + * until the *next* floating point operation. This is painful if you've + * already decremented PyFPE_counter. + */ +#define PyFPE_END_PROTECT(v) PyFPE_counter -= (int)PyFPE_dummy(&(v)); + +#else + +#define PyFPE_START_PROTECT(err_string, leave_stmt) +#define PyFPE_END_PROTECT(v) + +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYFPE_H */ diff --git a/python/include/pygetopt.h b/python/include/pygetopt.h new file mode 100644 index 000000000..9860d360e --- /dev/null +++ b/python/include/pygetopt.h @@ -0,0 +1,18 @@ + +#ifndef Py_PYGETOPT_H +#define Py_PYGETOPT_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_DATA(int) _PyOS_opterr; +PyAPI_DATA(int) _PyOS_optind; +PyAPI_DATA(char *) _PyOS_optarg; + +PyAPI_FUNC(void) _PyOS_ResetGetOpt(void); +PyAPI_FUNC(int) _PyOS_GetOpt(int argc, char **argv, char *optstring); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYGETOPT_H */ diff --git a/python/include/pymacconfig.h b/python/include/pymacconfig.h new file mode 100644 index 000000000..24e7b8dac --- /dev/null +++ b/python/include/pymacconfig.h @@ -0,0 +1,102 @@ +#ifndef PYMACCONFIG_H +#define PYMACCONFIG_H + /* + * This file moves some of the autoconf magic to compile-time + * when building on MacOSX. This is needed for building 4-way + * universal binaries and for 64-bit universal binaries because + * the values redefined below aren't configure-time constant but + * only compile-time constant in these scenarios. + */ + +#if defined(__APPLE__) + +# undef SIZEOF_LONG +# undef SIZEOF_PTHREAD_T +# undef SIZEOF_SIZE_T +# undef SIZEOF_TIME_T +# undef SIZEOF_VOID_P +# undef SIZEOF__BOOL +# undef SIZEOF_UINTPTR_T +# undef SIZEOF_PTHREAD_T +# undef WORDS_BIGENDIAN +# undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 +# undef DOUBLE_IS_BIG_ENDIAN_IEEE754 +# undef DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +# undef HAVE_GCC_ASM_FOR_X87 + +# undef VA_LIST_IS_ARRAY +# if defined(__LP64__) && defined(__x86_64__) +# define VA_LIST_IS_ARRAY 1 +# endif + +# undef HAVE_LARGEFILE_SUPPORT +# ifndef __LP64__ +# define HAVE_LARGEFILE_SUPPORT 1 +# endif + +# undef SIZEOF_LONG +# ifdef __LP64__ +# define SIZEOF__BOOL 1 +# define SIZEOF__BOOL 1 +# define SIZEOF_LONG 8 +# define SIZEOF_PTHREAD_T 8 +# define SIZEOF_SIZE_T 8 +# define SIZEOF_TIME_T 8 +# define SIZEOF_VOID_P 8 +# define SIZEOF_UINTPTR_T 8 +# define SIZEOF_PTHREAD_T 8 +# else +# ifdef __ppc__ +# define SIZEOF__BOOL 4 +# else +# define SIZEOF__BOOL 1 +# endif +# define SIZEOF_LONG 4 +# define SIZEOF_PTHREAD_T 4 +# define SIZEOF_SIZE_T 4 +# define SIZEOF_TIME_T 4 +# define SIZEOF_VOID_P 4 +# define SIZEOF_UINTPTR_T 4 +# define SIZEOF_PTHREAD_T 4 +# endif + +# if defined(__LP64__) + /* MacOSX 10.4 (the first release to support 64-bit code + * at all) only supports 64-bit in the UNIX layer. + * Therefore surpress the toolbox-glue in 64-bit mode. + */ + + /* In 64-bit mode setpgrp always has no argments, in 32-bit + * mode that depends on the compilation environment + */ +# undef SETPGRP_HAVE_ARG + +# endif + +#ifdef __BIG_ENDIAN__ +#define WORDS_BIGENDIAN 1 +#define DOUBLE_IS_BIG_ENDIAN_IEEE754 +#else +#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 +#endif /* __BIG_ENDIAN */ + +#ifdef __i386__ +# define HAVE_GCC_ASM_FOR_X87 +#endif + + /* + * The definition in pyconfig.h is only valid on the OS release + * where configure ran on and not necessarily for all systems where + * the executable can be used on. + * + * Specifically: OSX 10.4 has limited supported for '%zd', while + * 10.5 has full support for '%zd'. A binary built on 10.5 won't + * work properly on 10.4 unless we surpress the definition + * of PY_FORMAT_SIZE_T + */ +#undef PY_FORMAT_SIZE_T + + +#endif /* defined(_APPLE__) */ + +#endif /* PYMACCONFIG_H */ diff --git a/python/include/pymactoolbox.h b/python/include/pymactoolbox.h new file mode 100644 index 000000000..fd1597527 --- /dev/null +++ b/python/include/pymactoolbox.h @@ -0,0 +1,217 @@ +/* +** pymactoolbox.h - globals defined in mactoolboxglue.c +*/ +#ifndef Py_PYMACTOOLBOX_H +#define Py_PYMACTOOLBOX_H +#ifdef __cplusplus + extern "C" { +#endif + +#include + +#ifndef __LP64__ +#include +#endif /* !__LP64__ */ + +/* +** Helper routines for error codes and such. +*/ +char *PyMac_StrError(int); /* strerror with mac errors */ +extern PyObject *PyMac_OSErrException; /* Exception for OSErr */ +PyObject *PyMac_GetOSErrException(void); /* Initialize & return it */ +PyObject *PyErr_Mac(PyObject *, int); /* Exception with a mac error */ +PyObject *PyMac_Error(OSErr); /* Uses PyMac_GetOSErrException */ +#ifndef __LP64__ +extern OSErr PyMac_GetFullPathname(FSSpec *, char *, int); /* convert + fsspec->path */ +#endif /* __LP64__ */ + +/* +** These conversion routines are defined in mactoolboxglue.c itself. +*/ +int PyMac_GetOSType(PyObject *, OSType *); /* argument parser for OSType */ +PyObject *PyMac_BuildOSType(OSType); /* Convert OSType to PyObject */ + +PyObject *PyMac_BuildNumVersion(NumVersion);/* Convert NumVersion to PyObject */ + +int PyMac_GetStr255(PyObject *, Str255); /* argument parser for Str255 */ +PyObject *PyMac_BuildStr255(Str255); /* Convert Str255 to PyObject */ +PyObject *PyMac_BuildOptStr255(Str255); /* Convert Str255 to PyObject, + NULL to None */ + +int PyMac_GetRect(PyObject *, Rect *); /* argument parser for Rect */ +PyObject *PyMac_BuildRect(Rect *); /* Convert Rect to PyObject */ + +int PyMac_GetPoint(PyObject *, Point *); /* argument parser for Point */ +PyObject *PyMac_BuildPoint(Point); /* Convert Point to PyObject */ + +int PyMac_GetEventRecord(PyObject *, EventRecord *); /* argument parser for + EventRecord */ +PyObject *PyMac_BuildEventRecord(EventRecord *); /* Convert EventRecord to + PyObject */ + +int PyMac_GetFixed(PyObject *, Fixed *); /* argument parser for Fixed */ +PyObject *PyMac_BuildFixed(Fixed); /* Convert Fixed to PyObject */ +int PyMac_Getwide(PyObject *, wide *); /* argument parser for wide */ +PyObject *PyMac_Buildwide(wide *); /* Convert wide to PyObject */ + +/* +** The rest of the routines are implemented by extension modules. If they are +** dynamically loaded mactoolboxglue will contain a stub implementation of the +** routine, which imports the module, whereupon the module's init routine will +** communicate the routine pointer back to the stub. +** If USE_TOOLBOX_OBJECT_GLUE is not defined there is no glue code, and the +** extension modules simply declare the routine. This is the case for static +** builds (and could be the case for MacPython CFM builds, because CFM extension +** modules can reference each other without problems). +*/ + +#ifdef USE_TOOLBOX_OBJECT_GLUE +/* +** These macros are used in the module init code. If we use toolbox object glue +** it sets the function pointer to point to the real function. +*/ +#define PyMac_INIT_TOOLBOX_OBJECT_NEW(object, rtn) { \ + extern PyObject *(*PyMacGluePtr_##rtn)(object); \ + PyMacGluePtr_##rtn = _##rtn; \ +} +#define PyMac_INIT_TOOLBOX_OBJECT_CONVERT(object, rtn) { \ + extern int (*PyMacGluePtr_##rtn)(PyObject *, object *); \ + PyMacGluePtr_##rtn = _##rtn; \ +} +#else +/* +** If we don't use toolbox object glue the init macros are empty. Moreover, we define +** _xxx_New to be the same as xxx_New, and the code in mactoolboxglue isn't included. +*/ +#define PyMac_INIT_TOOLBOX_OBJECT_NEW(object, rtn) +#define PyMac_INIT_TOOLBOX_OBJECT_CONVERT(object, rtn) +#endif /* USE_TOOLBOX_OBJECT_GLUE */ + +/* macfs exports */ +#ifndef __LP64__ +int PyMac_GetFSSpec(PyObject *, FSSpec *); /* argument parser for FSSpec */ +PyObject *PyMac_BuildFSSpec(FSSpec *); /* Convert FSSpec to PyObject */ +#endif /* !__LP64__ */ + +int PyMac_GetFSRef(PyObject *, FSRef *); /* argument parser for FSRef */ +PyObject *PyMac_BuildFSRef(FSRef *); /* Convert FSRef to PyObject */ + +/* AE exports */ +extern PyObject *AEDesc_New(AppleEvent *); /* XXXX Why passed by address?? */ +extern PyObject *AEDesc_NewBorrowed(AppleEvent *); +extern int AEDesc_Convert(PyObject *, AppleEvent *); + +/* Cm exports */ +extern PyObject *CmpObj_New(Component); +extern int CmpObj_Convert(PyObject *, Component *); +extern PyObject *CmpInstObj_New(ComponentInstance); +extern int CmpInstObj_Convert(PyObject *, ComponentInstance *); + +/* Ctl exports */ +#ifndef __LP64__ +extern PyObject *CtlObj_New(ControlHandle); +extern int CtlObj_Convert(PyObject *, ControlHandle *); +#endif /* !__LP64__ */ + +/* Dlg exports */ +#ifndef __LP64__ +extern PyObject *DlgObj_New(DialogPtr); +extern int DlgObj_Convert(PyObject *, DialogPtr *); +extern PyObject *DlgObj_WhichDialog(DialogPtr); +#endif /* !__LP64__ */ + +/* Drag exports */ +#ifndef __LP64__ +extern PyObject *DragObj_New(DragReference); +extern int DragObj_Convert(PyObject *, DragReference *); +#endif /* !__LP64__ */ + +/* List exports */ +#ifndef __LP64__ +extern PyObject *ListObj_New(ListHandle); +extern int ListObj_Convert(PyObject *, ListHandle *); +#endif /* !__LP64__ */ + +/* Menu exports */ +#ifndef __LP64__ +extern PyObject *MenuObj_New(MenuHandle); +extern int MenuObj_Convert(PyObject *, MenuHandle *); +#endif /* !__LP64__ */ + +/* Qd exports */ +#ifndef __LP64__ +extern PyObject *GrafObj_New(GrafPtr); +extern int GrafObj_Convert(PyObject *, GrafPtr *); +extern PyObject *BMObj_New(BitMapPtr); +extern int BMObj_Convert(PyObject *, BitMapPtr *); +extern PyObject *QdRGB_New(RGBColor *); +extern int QdRGB_Convert(PyObject *, RGBColor *); +#endif /* !__LP64__ */ + +/* Qdoffs exports */ +#ifndef __LP64__ +extern PyObject *GWorldObj_New(GWorldPtr); +extern int GWorldObj_Convert(PyObject *, GWorldPtr *); +#endif /* !__LP64__ */ + +/* Qt exports */ +#ifndef __LP64__ +extern PyObject *TrackObj_New(Track); +extern int TrackObj_Convert(PyObject *, Track *); +extern PyObject *MovieObj_New(Movie); +extern int MovieObj_Convert(PyObject *, Movie *); +extern PyObject *MovieCtlObj_New(MovieController); +extern int MovieCtlObj_Convert(PyObject *, MovieController *); +extern PyObject *TimeBaseObj_New(TimeBase); +extern int TimeBaseObj_Convert(PyObject *, TimeBase *); +extern PyObject *UserDataObj_New(UserData); +extern int UserDataObj_Convert(PyObject *, UserData *); +extern PyObject *MediaObj_New(Media); +extern int MediaObj_Convert(PyObject *, Media *); +#endif /* !__LP64__ */ + +/* Res exports */ +extern PyObject *ResObj_New(Handle); +extern int ResObj_Convert(PyObject *, Handle *); +extern PyObject *OptResObj_New(Handle); +extern int OptResObj_Convert(PyObject *, Handle *); + +/* TE exports */ +#ifndef __LP64__ +extern PyObject *TEObj_New(TEHandle); +extern int TEObj_Convert(PyObject *, TEHandle *); +#endif /* !__LP64__ */ + +/* Win exports */ +#ifndef __LP64__ +extern PyObject *WinObj_New(WindowPtr); +extern int WinObj_Convert(PyObject *, WindowPtr *); +extern PyObject *WinObj_WhichWindow(WindowPtr); +#endif /* !__LP64__ */ + +/* CF exports */ +extern PyObject *CFObj_New(CFTypeRef); +extern int CFObj_Convert(PyObject *, CFTypeRef *); +extern PyObject *CFTypeRefObj_New(CFTypeRef); +extern int CFTypeRefObj_Convert(PyObject *, CFTypeRef *); +extern PyObject *CFStringRefObj_New(CFStringRef); +extern int CFStringRefObj_Convert(PyObject *, CFStringRef *); +extern PyObject *CFMutableStringRefObj_New(CFMutableStringRef); +extern int CFMutableStringRefObj_Convert(PyObject *, CFMutableStringRef *); +extern PyObject *CFArrayRefObj_New(CFArrayRef); +extern int CFArrayRefObj_Convert(PyObject *, CFArrayRef *); +extern PyObject *CFMutableArrayRefObj_New(CFMutableArrayRef); +extern int CFMutableArrayRefObj_Convert(PyObject *, CFMutableArrayRef *); +extern PyObject *CFDictionaryRefObj_New(CFDictionaryRef); +extern int CFDictionaryRefObj_Convert(PyObject *, CFDictionaryRef *); +extern PyObject *CFMutableDictionaryRefObj_New(CFMutableDictionaryRef); +extern int CFMutableDictionaryRefObj_Convert(PyObject *, CFMutableDictionaryRef *); +extern PyObject *CFURLRefObj_New(CFURLRef); +extern int CFURLRefObj_Convert(PyObject *, CFURLRef *); +extern int OptionalCFURLRefObj_Convert(PyObject *, CFURLRef *); + +#ifdef __cplusplus + } +#endif +#endif diff --git a/python/include/pymath.h b/python/include/pymath.h new file mode 100644 index 000000000..f77ce9308 --- /dev/null +++ b/python/include/pymath.h @@ -0,0 +1,192 @@ +#ifndef Py_PYMATH_H +#define Py_PYMATH_H + +#include "pyconfig.h" /* include for defines */ + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to mathematical +functions and constants +**************************************************************************/ + +/* Python provides implementations for copysign, round and hypot in + * Python/pymath.c just in case your math library doesn't provide the + * functions. + * + *Note: PC/pyconfig.h defines copysign as _copysign + */ +#ifndef HAVE_COPYSIGN +extern double copysign(double, double); +#endif + +#ifndef HAVE_ROUND +extern double round(double); +#endif + +#ifndef HAVE_HYPOT +extern double hypot(double, double); +#endif + +/* extra declarations */ +#ifndef _MSC_VER +#ifndef __STDC__ +//extern double fmod (double, double); +//extern double frexp (double, int *); +//extern double ldexp (double, int); +//extern double modf (double, double *); +//extern double pow(double, double); +#endif /* __STDC__ */ +#endif /* _MSC_VER */ + +#ifdef _OSF_SOURCE +/* OSF1 5.1 doesn't make these available with XOPEN_SOURCE_EXTENDED defined */ +extern int finite(double); +extern double copysign(double, double); +#endif + +/* High precision defintion of pi and e (Euler) + * The values are taken from libc6's math.h. + */ +#ifndef Py_MATH_PIl +#define Py_MATH_PIl 3.1415926535897932384626433832795029L +#endif +#ifndef Py_MATH_PI +#define Py_MATH_PI 3.14159265358979323846 +#endif + +#ifndef Py_MATH_El +#define Py_MATH_El 2.7182818284590452353602874713526625L +#endif + +#ifndef Py_MATH_E +#define Py_MATH_E 2.7182818284590452354 +#endif + +/* On x86, Py_FORCE_DOUBLE forces a floating-point number out of an x87 FPU + register and into a 64-bit memory location, rounding from extended + precision to double precision in the process. On other platforms it does + nothing. */ + +/* we take double rounding as evidence of x87 usage */ +#ifndef Py_FORCE_DOUBLE +# ifdef X87_DOUBLE_ROUNDING +PyAPI_FUNC(double) _Py_force_double(double); +# define Py_FORCE_DOUBLE(X) (_Py_force_double(X)) +# else +# define Py_FORCE_DOUBLE(X) (X) +# endif +#endif + +#ifdef HAVE_GCC_ASM_FOR_X87 +PyAPI_FUNC(unsigned short) _Py_get_387controlword(void); +PyAPI_FUNC(void) _Py_set_387controlword(unsigned short); +#endif + +/* Py_IS_NAN(X) + * Return 1 if float or double arg is a NaN, else 0. + * Caution: + * X is evaluated more than once. + * This may not work on all platforms. Each platform has *some* + * way to spell this, though -- override in pyconfig.h if you have + * a platform where it doesn't work. + * Note: PC/pyconfig.h defines Py_IS_NAN as _isnan + */ +#ifndef Py_IS_NAN +#if defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 1 +#define Py_IS_NAN(X) isnan(X) +#else +#define Py_IS_NAN(X) ((X) != (X)) +#endif +#endif + +/* Py_IS_INFINITY(X) + * Return 1 if float or double arg is an infinity, else 0. + * Caution: + * X is evaluated more than once. + * This implementation may set the underflow flag if |X| is very small; + * it really can't be implemented correctly (& easily) before C99. + * Override in pyconfig.h if you have a better spelling on your platform. + * Py_FORCE_DOUBLE is used to avoid getting false negatives from a + * non-infinite value v sitting in an 80-bit x87 register such that + * v becomes infinite when spilled from the register to 64-bit memory. + * Note: PC/pyconfig.h defines Py_IS_INFINITY as _isinf + */ +#ifndef Py_IS_INFINITY +# if defined HAVE_DECL_ISINF && HAVE_DECL_ISINF == 1 +# define Py_IS_INFINITY(X) isinf(X) +# else +# define Py_IS_INFINITY(X) ((X) && \ + (Py_FORCE_DOUBLE(X)*0.5 == Py_FORCE_DOUBLE(X))) +# endif +#endif + +/* Py_IS_FINITE(X) + * Return 1 if float or double arg is neither infinite nor NAN, else 0. + * Some compilers (e.g. VisualStudio) have intrisics for this, so a special + * macro for this particular test is useful + * Note: PC/pyconfig.h defines Py_IS_FINITE as _finite + */ +#ifndef Py_IS_FINITE +#if defined HAVE_DECL_ISFINITE && HAVE_DECL_ISFINITE == 1 +#define Py_IS_FINITE(X) isfinite(X) +#elif defined HAVE_FINITE +#define Py_IS_FINITE(X) finite(X) +#else +#define Py_IS_FINITE(X) (!Py_IS_INFINITY(X) && !Py_IS_NAN(X)) +#endif +#endif + +/* HUGE_VAL is supposed to expand to a positive double infinity. Python + * uses Py_HUGE_VAL instead because some platforms are broken in this + * respect. We used to embed code in pyport.h to try to worm around that, + * but different platforms are broken in conflicting ways. If you're on + * a platform where HUGE_VAL is defined incorrectly, fiddle your Python + * config to #define Py_HUGE_VAL to something that works on your platform. + */ +#ifndef Py_HUGE_VAL +#define Py_HUGE_VAL HUGE_VAL +#endif + +/* Py_NAN + * A value that evaluates to a NaN. On IEEE 754 platforms INF*0 or + * INF/INF works. Define Py_NO_NAN in pyconfig.h if your platform + * doesn't support NaNs. + */ +#if !defined(Py_NAN) && !defined(Py_NO_NAN) +#define Py_NAN (Py_HUGE_VAL * 0.) +#endif + +/* Py_OVERFLOWED(X) + * Return 1 iff a libm function overflowed. Set errno to 0 before calling + * a libm function, and invoke this macro after, passing the function + * result. + * Caution: + * This isn't reliable. C99 no longer requires libm to set errno under + * any exceptional condition, but does require +- HUGE_VAL return + * values on overflow. A 754 box *probably* maps HUGE_VAL to a + * double infinity, and we're cool if that's so, unless the input + * was an infinity and an infinity is the expected result. A C89 + * system sets errno to ERANGE, so we check for that too. We're + * out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or + * if the returned result is a NaN, or if a C89 box returns HUGE_VAL + * in non-overflow cases. + * X is evaluated more than once. + * Some platforms have better way to spell this, so expect some #ifdef'ery. + * + * OpenBSD uses 'isinf()' because a compiler bug on that platform causes + * the longer macro version to be mis-compiled. This isn't optimal, and + * should be removed once a newer compiler is available on that platform. + * The system that had the failure was running OpenBSD 3.2 on Intel, with + * gcc 2.95.3. + * + * According to Tim's checkin, the FreeBSD systems use isinf() to work + * around a FPE bug on that platform. + */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) +#define Py_OVERFLOWED(X) isinf(X) +#else +#define Py_OVERFLOWED(X) ((X) != 0.0 && (errno == ERANGE || \ + (X) == Py_HUGE_VAL || \ + (X) == -Py_HUGE_VAL)) +#endif + +#endif /* Py_PYMATH_H */ diff --git a/python/include/pymem.h b/python/include/pymem.h new file mode 100644 index 000000000..10b5bea5e --- /dev/null +++ b/python/include/pymem.h @@ -0,0 +1,122 @@ +/* The PyMem_ family: low-level memory allocation interfaces. + See objimpl.h for the PyObject_ memory family. +*/ + +#ifndef Py_PYMEM_H +#define Py_PYMEM_H + +#include "pyport.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEWARE: + + Each interface exports both functions and macros. Extension modules should + use the functions, to ensure binary compatibility across Python versions. + Because the Python implementation is free to change internal details, and + the macros may (or may not) expose details for speed, if you do use the + macros you must recompile your extensions with each Python release. + + Never mix calls to PyMem_ with calls to the platform malloc/realloc/ + calloc/free. For example, on Windows different DLLs may end up using + different heaps, and if you use PyMem_Malloc you'll get the memory from the + heap used by the Python DLL; it could be a disaster if you free()'ed that + directly in your own extension. Using PyMem_Free instead ensures Python + can return the memory to the proper heap. As another example, in + PYMALLOC_DEBUG mode, Python wraps all calls to all PyMem_ and PyObject_ + memory functions in special debugging wrappers that add additional + debugging info to dynamic memory blocks. The system routines have no idea + what to do with that stuff, and the Python wrappers have no idea what to do + with raw blocks obtained directly by the system routines then. + + The GIL must be held when using these APIs. +*/ + +/* + * Raw memory interface + * ==================== + */ + +/* Functions + + Functions supplying platform-independent semantics for malloc/realloc/ + free. These functions make sure that allocating 0 bytes returns a distinct + non-NULL pointer (whenever possible -- if we're flat out of memory, NULL + may be returned), even if the platform malloc and realloc don't. + Returned pointers must be checked for NULL explicitly. No action is + performed on failure (no exception is set, no warning is printed, etc). +*/ + +PyAPI_FUNC(void *) PyMem_Malloc(size_t); +PyAPI_FUNC(void *) PyMem_Realloc(void *, size_t); +PyAPI_FUNC(void) PyMem_Free(void *); + +/* Starting from Python 1.6, the wrappers Py_{Malloc,Realloc,Free} are + no longer supported. They used to call PyErr_NoMemory() on failure. */ + +/* Macros. */ +#ifdef PYMALLOC_DEBUG +/* Redirect all memory operations to Python's debugging allocator. */ +#define PyMem_MALLOC _PyMem_DebugMalloc +#define PyMem_REALLOC _PyMem_DebugRealloc +#define PyMem_FREE _PyMem_DebugFree + +#else /* ! PYMALLOC_DEBUG */ + +/* PyMem_MALLOC(0) means malloc(1). Some systems would return NULL + for malloc(0), which would be treated as an error. Some platforms + would return a pointer with no memory behind it, which would break + pymalloc. To solve these problems, allocate an extra byte. */ +/* Returns NULL to indicate error if a negative size or size larger than + Py_ssize_t can represent is supplied. Helps prevents security holes. */ +#define PyMem_MALLOC(n) ((size_t)(n) > (size_t)PY_SSIZE_T_MAX ? NULL \ + : malloc((n) ? (n) : 1)) +#define PyMem_REALLOC(p, n) ((size_t)(n) > (size_t)PY_SSIZE_T_MAX ? NULL \ + : realloc((p), (n) ? (n) : 1)) +#define PyMem_FREE free + +#endif /* PYMALLOC_DEBUG */ + +/* + * Type-oriented memory interface + * ============================== + * + * Allocate memory for n objects of the given type. Returns a new pointer + * or NULL if the request was too large or memory allocation failed. Use + * these macros rather than doing the multiplication yourself so that proper + * overflow checking is always done. + */ + +#define PyMem_New(type, n) \ + ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + ( (type *) PyMem_Malloc((n) * sizeof(type)) ) ) +#define PyMem_NEW(type, n) \ + ( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + ( (type *) PyMem_MALLOC((n) * sizeof(type)) ) ) + +/* + * The value of (p) is always clobbered by this macro regardless of success. + * The caller MUST check if (p) is NULL afterwards and deal with the memory + * error if so. This means the original value of (p) MUST be saved for the + * caller's memory error handler to not lose track of it. + */ +#define PyMem_Resize(p, type, n) \ + ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + (type *) PyMem_Realloc((p), (n) * sizeof(type)) ) +#define PyMem_RESIZE(p, type, n) \ + ( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \ + (type *) PyMem_REALLOC((p), (n) * sizeof(type)) ) + +/* PyMem{Del,DEL} are left over from ancient days, and shouldn't be used + * anymore. They're just confusing aliases for PyMem_{Free,FREE} now. + */ +#define PyMem_Del PyMem_Free +#define PyMem_DEL PyMem_FREE + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYMEM_H */ diff --git a/python/include/pyport.h b/python/include/pyport.h new file mode 100644 index 000000000..693d09354 --- /dev/null +++ b/python/include/pyport.h @@ -0,0 +1,904 @@ +#ifndef Py_PYPORT_H +#define Py_PYPORT_H + +#include "pyconfig.h" /* include for defines */ + +/* Some versions of HP-UX & Solaris need inttypes.h for int32_t, + INT32_MAX, etc. */ +#ifdef HAVE_INTTYPES_H +#include +#endif + +#ifdef HAVE_STDINT_H +#include +#endif + +/************************************************************************** +Symbols and macros to supply platform-independent interfaces to basic +C language & library operations whose spellings vary across platforms. + +Please try to make documentation here as clear as possible: by definition, +the stuff here is trying to illuminate C's darkest corners. + +Config #defines referenced here: + +SIGNED_RIGHT_SHIFT_ZERO_FILLS +Meaning: To be defined iff i>>j does not extend the sign bit when i is a + signed integral type and i < 0. +Used in: Py_ARITHMETIC_RIGHT_SHIFT + +Py_DEBUG +Meaning: Extra checks compiled in for debug mode. +Used in: Py_SAFE_DOWNCAST + +HAVE_UINTPTR_T +Meaning: The C9X type uintptr_t is supported by the compiler +Used in: Py_uintptr_t + +HAVE_LONG_LONG +Meaning: The compiler supports the C type "long long" +Used in: PY_LONG_LONG + +**************************************************************************/ + + +/* For backward compatibility only. Obsolete, do not use. */ +#ifdef HAVE_PROTOTYPES +#define Py_PROTO(x) x +#else +#define Py_PROTO(x) () +#endif +#ifndef Py_FPROTO +#define Py_FPROTO(x) Py_PROTO(x) +#endif + +/* typedefs for some C9X-defined synonyms for integral types. + * + * The names in Python are exactly the same as the C9X names, except with a + * Py_ prefix. Until C9X is universally implemented, this is the only way + * to ensure that Python gets reliable names that don't conflict with names + * in non-Python code that are playing their own tricks to define the C9X + * names. + * + * NOTE: don't go nuts here! Python has no use for *most* of the C9X + * integral synonyms. Only define the ones we actually need. + */ + +#ifdef HAVE_LONG_LONG +#ifndef PY_LONG_LONG +#define PY_LONG_LONG long long +#if defined(LLONG_MAX) +/* If LLONG_MAX is defined in limits.h, use that. */ +#define PY_LLONG_MIN LLONG_MIN +#define PY_LLONG_MAX LLONG_MAX +#define PY_ULLONG_MAX ULLONG_MAX +#elif defined(__LONG_LONG_MAX__) +/* Otherwise, if GCC has a builtin define, use that. */ +#define PY_LLONG_MAX __LONG_LONG_MAX__ +#define PY_LLONG_MIN (-PY_LLONG_MAX-1) +#define PY_ULLONG_MAX (__LONG_LONG_MAX__*2ULL + 1ULL) +#else +/* Otherwise, rely on two's complement. */ +#define PY_ULLONG_MAX (~0ULL) +#define PY_LLONG_MAX ((long long)(PY_ULLONG_MAX>>1)) +#define PY_LLONG_MIN (-PY_LLONG_MAX-1) +#endif /* LLONG_MAX */ +#endif +#endif /* HAVE_LONG_LONG */ + +/* a build with 30-bit digits for Python long integers needs an exact-width + * 32-bit unsigned integer type to store those digits. (We could just use + * type 'unsigned long', but that would be wasteful on a system where longs + * are 64-bits.) On Unix systems, the autoconf macro AC_TYPE_UINT32_T defines + * uint32_t to be such a type unless stdint.h or inttypes.h defines uint32_t. + * However, it doesn't set HAVE_UINT32_T, so we do that here. + */ +#if (defined UINT32_MAX || defined uint32_t) +#ifndef PY_UINT32_T +#define HAVE_UINT32_T 1 +#define PY_UINT32_T uint32_t +#endif +#endif + +/* Macros for a 64-bit unsigned integer type; used for type 'twodigits' in the + * long integer implementation, when 30-bit digits are enabled. + */ +#if (defined UINT64_MAX || defined uint64_t) +#ifndef PY_UINT64_T +#define HAVE_UINT64_T 1 +#define PY_UINT64_T uint64_t +#endif +#endif + +/* Signed variants of the above */ +#if (defined INT32_MAX || defined int32_t) +#ifndef PY_INT32_T +#define HAVE_INT32_T 1 +#define PY_INT32_T int32_t +#endif +#endif +#if (defined INT64_MAX || defined int64_t) +#ifndef PY_INT64_T +#define HAVE_INT64_T 1 +#define PY_INT64_T int64_t +#endif +#endif + +/* If PYLONG_BITS_IN_DIGIT is not defined then we'll use 30-bit digits if all + the necessary integer types are available, and we're on a 64-bit platform + (as determined by SIZEOF_VOID_P); otherwise we use 15-bit digits. */ + +#ifndef PYLONG_BITS_IN_DIGIT +#if (defined HAVE_UINT64_T && defined HAVE_INT64_T && \ + defined HAVE_UINT32_T && defined HAVE_INT32_T && SIZEOF_VOID_P >= 8) +#define PYLONG_BITS_IN_DIGIT 30 +#else +#define PYLONG_BITS_IN_DIGIT 15 +#endif +#endif + +/* uintptr_t is the C9X name for an unsigned integral type such that a + * legitimate void* can be cast to uintptr_t and then back to void* again + * without loss of information. Similarly for intptr_t, wrt a signed + * integral type. + */ +#ifdef HAVE_UINTPTR_T +typedef uintptr_t Py_uintptr_t; +typedef intptr_t Py_intptr_t; + +#elif SIZEOF_VOID_P <= SIZEOF_INT +typedef unsigned int Py_uintptr_t; +typedef int Py_intptr_t; + +#elif SIZEOF_VOID_P <= SIZEOF_LONG +typedef unsigned long Py_uintptr_t; +typedef long Py_intptr_t; + +#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P <= SIZEOF_LONG_LONG) +typedef unsigned PY_LONG_LONG Py_uintptr_t; +typedef PY_LONG_LONG Py_intptr_t; + +#else +# error "Python needs a typedef for Py_uintptr_t in pyport.h." +#endif /* HAVE_UINTPTR_T */ + +/* Py_ssize_t is a signed integral type such that sizeof(Py_ssize_t) == + * sizeof(size_t). C99 doesn't define such a thing directly (size_t is an + * unsigned integral type). See PEP 353 for details. + */ +#ifdef HAVE_SSIZE_T +typedef ssize_t Py_ssize_t; +#elif SIZEOF_VOID_P == SIZEOF_SIZE_T +typedef Py_intptr_t Py_ssize_t; +#else +# error "Python needs a typedef for Py_ssize_t in pyport.h." +#endif + +/* Largest possible value of size_t. + SIZE_MAX is part of C99, so it might be defined on some + platforms. If it is not defined, (size_t)-1 is a portable + definition for C89, due to the way signed->unsigned + conversion is defined. */ +#ifdef SIZE_MAX +#define PY_SIZE_MAX SIZE_MAX +#else +#define PY_SIZE_MAX ((size_t)-1) +#endif + +/* Largest positive value of type Py_ssize_t. */ +#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1)) +/* Smallest negative value of type Py_ssize_t. */ +#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1) + +#if SIZEOF_PID_T > SIZEOF_LONG +# error "Python doesn't support sizeof(pid_t) > sizeof(long)" +#endif + +/* PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf + * format to convert an argument with the width of a size_t or Py_ssize_t. + * C99 introduced "z" for this purpose, but not all platforms support that; + * e.g., MS compilers use "I" instead. + * + * These "high level" Python format functions interpret "z" correctly on + * all platforms (Python interprets the format string itself, and does whatever + * the platform C requires to convert a size_t/Py_ssize_t argument): + * + * PyString_FromFormat + * PyErr_Format + * PyString_FromFormatV + * + * Lower-level uses require that you interpolate the correct format modifier + * yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for + * example, + * + * Py_ssize_t index; + * fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index); + * + * That will expand to %ld, or %Id, or to something else correct for a + * Py_ssize_t on the platform. + */ +#ifndef PY_FORMAT_SIZE_T +# if SIZEOF_SIZE_T == SIZEOF_INT && !defined(__APPLE__) +# define PY_FORMAT_SIZE_T "" +# elif SIZEOF_SIZE_T == SIZEOF_LONG +# define PY_FORMAT_SIZE_T "l" +# elif defined(MS_WINDOWS) +# define PY_FORMAT_SIZE_T "I" +# else +# error "This platform's pyconfig.h needs to define PY_FORMAT_SIZE_T" +# endif +#endif + +/* PY_FORMAT_LONG_LONG is analogous to PY_FORMAT_SIZE_T above, but for + * the long long type instead of the size_t type. It's only available + * when HAVE_LONG_LONG is defined. The "high level" Python format + * functions listed above will interpret "lld" or "llu" correctly on + * all platforms. + */ +#ifdef HAVE_LONG_LONG +# ifndef PY_FORMAT_LONG_LONG +# if defined(MS_WIN64) || defined(MS_WINDOWS) +# define PY_FORMAT_LONG_LONG "I64" +# else +# error "This platform's pyconfig.h needs to define PY_FORMAT_LONG_LONG" +# endif +# endif +#endif + +/* Py_LOCAL can be used instead of static to get the fastest possible calling + * convention for functions that are local to a given module. + * + * Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining, + * for platforms that support that. + * + * If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more + * "aggressive" inlining/optimizaion is enabled for the entire module. This + * may lead to code bloat, and may slow things down for those reasons. It may + * also lead to errors, if the code relies on pointer aliasing. Use with + * care. + * + * NOTE: You can only use this for functions that are entirely local to a + * module; functions that are exported via method tables, callbacks, etc, + * should keep using static. + */ + +#undef USE_INLINE /* XXX - set via configure? */ + +#if defined(_MSC_VER) +#if defined(PY_LOCAL_AGGRESSIVE) +/* enable more aggressive optimization for visual studio */ +#pragma optimize("agtw", on) +#endif +/* ignore warnings if the compiler decides not to inline a function */ +#pragma warning(disable: 4710) +/* fastest possible local call under MSVC */ +#define Py_LOCAL(type) static type +#define Py_LOCAL_INLINE(type) static __inline type +#elif defined(USE_INLINE) +#define Py_LOCAL(type) static type +#define Py_LOCAL_INLINE(type) static inline type +#else +#define Py_LOCAL(type) static type +#define Py_LOCAL_INLINE(type) static type +#endif + +/* Py_MEMCPY can be used instead of memcpy in cases where the copied blocks + * are often very short. While most platforms have highly optimized code for + * large transfers, the setup costs for memcpy are often quite high. MEMCPY + * solves this by doing short copies "in line". + */ + +#if defined(_MSC_VER) +#define Py_MEMCPY(target, source, length) do { \ + size_t i_, n_ = (length); \ + char *t_ = (void*) (target); \ + const char *s_ = (void*) (source); \ + if (n_ >= 16) \ + memcpy(t_, s_, n_); \ + else \ + for (i_ = 0; i_ < n_; i_++) \ + t_[i_] = s_[i_]; \ + } while (0) +#else +#define Py_MEMCPY memcpy +#endif + +#include + +#ifdef HAVE_IEEEFP_H +#include /* needed for 'finite' declaration on some platforms */ +#endif + +#include /* Moved here from the math section, before extern "C" */ + +/******************************************** + * WRAPPER FOR and/or * + ********************************************/ + +#ifdef TIME_WITH_SYS_TIME +#include +#include +#else /* !TIME_WITH_SYS_TIME */ +#ifdef HAVE_SYS_TIME_H +#include +#else /* !HAVE_SYS_TIME_H */ +#include +#endif /* !HAVE_SYS_TIME_H */ +#endif /* !TIME_WITH_SYS_TIME */ + + +/****************************** + * WRAPPER FOR * + ******************************/ + +/* NB caller must include */ + +#ifdef HAVE_SYS_SELECT_H + +#include + +#endif /* !HAVE_SYS_SELECT_H */ + +/******************************* + * stat() and fstat() fiddling * + *******************************/ + +/* We expect that stat and fstat exist on most systems. + * It's confirmed on Unix, Mac and Windows. + * If you don't have them, add + * #define DONT_HAVE_STAT + * and/or + * #define DONT_HAVE_FSTAT + * to your pyconfig.h. Python code beyond this should check HAVE_STAT and + * HAVE_FSTAT instead. + * Also + * #define HAVE_SYS_STAT_H + * if exists on your platform, and + * #define HAVE_STAT_H + * if does. + */ +#ifndef DONT_HAVE_STAT +#define HAVE_STAT +#endif + +#ifndef DONT_HAVE_FSTAT +#define HAVE_FSTAT +#endif + +#ifdef RISCOS +#include +#include "unixstuff.h" +#endif + +#ifdef HAVE_SYS_STAT_H +#if defined(PYOS_OS2) && defined(PYCC_GCC) +#include +#endif +#include +#elif defined(HAVE_STAT_H) +#include +#endif + +#if defined(PYCC_VACPP) +/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */ +#define S_IFMT (S_IFDIR|S_IFCHR|S_IFREG) +#endif + +#ifndef S_ISREG +#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) +#endif + +#ifndef S_ISDIR +#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) +#endif + + +#ifdef __cplusplus +/* Move this down here since some C++ #include's don't like to be included + inside an extern "C" */ +extern "C" { +#endif + + +/* Py_ARITHMETIC_RIGHT_SHIFT + * C doesn't define whether a right-shift of a signed integer sign-extends + * or zero-fills. Here a macro to force sign extension: + * Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) + * Return I >> J, forcing sign extension. Arithmetically, return the + * floor of I/2**J. + * Requirements: + * I should have signed integer type. In the terminology of C99, this can + * be either one of the five standard signed integer types (signed char, + * short, int, long, long long) or an extended signed integer type. + * J is an integer >= 0 and strictly less than the number of bits in the + * type of I (because C doesn't define what happens for J outside that + * range either). + * TYPE used to specify the type of I, but is now ignored. It's been left + * in for backwards compatibility with versions <= 2.6 or 3.0. + * Caution: + * I may be evaluated more than once. + */ +#ifdef SIGNED_RIGHT_SHIFT_ZERO_FILLS +#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) \ + ((I) < 0 ? -1-((-1-(I)) >> (J)) : (I) >> (J)) +#else +#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) ((I) >> (J)) +#endif + +/* Py_FORCE_EXPANSION(X) + * "Simply" returns its argument. However, macro expansions within the + * argument are evaluated. This unfortunate trickery is needed to get + * token-pasting to work as desired in some cases. + */ +#define Py_FORCE_EXPANSION(X) X + +/* Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) + * Cast VALUE to type NARROW from type WIDE. In Py_DEBUG mode, this + * assert-fails if any information is lost. + * Caution: + * VALUE may be evaluated more than once. + */ +#ifdef Py_DEBUG +#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \ + (assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE)) +#else +#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE) +#endif + +/* Py_SET_ERRNO_ON_MATH_ERROR(x) + * If a libm function did not set errno, but it looks like the result + * overflowed or not-a-number, set errno to ERANGE or EDOM. Set errno + * to 0 before calling a libm function, and invoke this macro after, + * passing the function result. + * Caution: + * This isn't reliable. See Py_OVERFLOWED comments. + * X is evaluated more than once. + */ +#if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__hpux) && defined(__ia64)) +#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) errno = EDOM; +#else +#define _Py_SET_EDOM_FOR_NAN(X) ; +#endif +#define Py_SET_ERRNO_ON_MATH_ERROR(X) \ + do { \ + if (errno == 0) { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \ + errno = ERANGE; \ + else _Py_SET_EDOM_FOR_NAN(X) \ + } \ + } while(0) + +/* Py_SET_ERANGE_ON_OVERFLOW(x) + * An alias of Py_SET_ERRNO_ON_MATH_ERROR for backward-compatibility. + */ +#define Py_SET_ERANGE_IF_OVERFLOW(X) Py_SET_ERRNO_ON_MATH_ERROR(X) + +/* Py_ADJUST_ERANGE1(x) + * Py_ADJUST_ERANGE2(x, y) + * Set errno to 0 before calling a libm function, and invoke one of these + * macros after, passing the function result(s) (Py_ADJUST_ERANGE2 is useful + * for functions returning complex results). This makes two kinds of + * adjustments to errno: (A) If it looks like the platform libm set + * errno=ERANGE due to underflow, clear errno. (B) If it looks like the + * platform libm overflowed but didn't set errno, force errno to ERANGE. In + * effect, we're trying to force a useful implementation of C89 errno + * behavior. + * Caution: + * This isn't reliable. See Py_OVERFLOWED comments. + * X and Y may be evaluated more than once. + */ +#define Py_ADJUST_ERANGE1(X) \ + do { \ + if (errno == 0) { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \ + errno = ERANGE; \ + } \ + else if (errno == ERANGE && (X) == 0.0) \ + errno = 0; \ + } while(0) + +#define Py_ADJUST_ERANGE2(X, Y) \ + do { \ + if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL || \ + (Y) == Py_HUGE_VAL || (Y) == -Py_HUGE_VAL) { \ + if (errno == 0) \ + errno = ERANGE; \ + } \ + else if (errno == ERANGE) \ + errno = 0; \ + } while(0) + +/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c (which are + * required to support the short float repr introduced in Python 3.1) require + * that the floating-point unit that's being used for arithmetic operations + * on C doubles is set to use 53-bit precision. It also requires that the + * FPU rounding mode is round-half-to-even, but that's less often an issue. + * + * If your FPU isn't already set to 53-bit precision/round-half-to-even, and + * you want to make use of _Py_dg_strtod and _Py_dg_dtoa, then you should + * + * #define HAVE_PY_SET_53BIT_PRECISION 1 + * + * and also give appropriate definitions for the following three macros: + * + * _PY_SET_53BIT_PRECISION_START : store original FPU settings, and + * set FPU to 53-bit precision/round-half-to-even + * _PY_SET_53BIT_PRECISION_END : restore original FPU settings + * _PY_SET_53BIT_PRECISION_HEADER : any variable declarations needed to + * use the two macros above. + * + * The macros are designed to be used within a single C function: see + * Python/pystrtod.c for an example of their use. + */ + +/* get and set x87 control word for gcc/x86 */ +#ifdef HAVE_GCC_ASM_FOR_X87 +#define HAVE_PY_SET_53BIT_PRECISION 1 +/* _Py_get/set_387controlword functions are defined in Python/pymath.c */ +#define _Py_SET_53BIT_PRECISION_HEADER \ + unsigned short old_387controlword, new_387controlword +#define _Py_SET_53BIT_PRECISION_START \ + do { \ + old_387controlword = _Py_get_387controlword(); \ + new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(new_387controlword); \ + } while (0) +#define _Py_SET_53BIT_PRECISION_END \ + if (new_387controlword != old_387controlword) \ + _Py_set_387controlword(old_387controlword) +#endif + +/* default definitions are empty */ +#ifndef HAVE_PY_SET_53BIT_PRECISION +#define _Py_SET_53BIT_PRECISION_HEADER +#define _Py_SET_53BIT_PRECISION_START +#define _Py_SET_53BIT_PRECISION_END +#endif + +/* If we can't guarantee 53-bit precision, don't use the code + in Python/dtoa.c, but fall back to standard code. This + means that repr of a float will be long (17 sig digits). + + Realistically, there are two things that could go wrong: + + (1) doubles aren't IEEE 754 doubles, or + (2) we're on x86 with the rounding precision set to 64-bits + (extended precision), and we don't know how to change + the rounding precision. + */ + +#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \ + !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754) +#define PY_NO_SHORT_FLOAT_REPR +#endif + +/* double rounding is symptomatic of use of extended precision on x86. If + we're seeing double rounding, and we don't have any mechanism available for + changing the FPU rounding precision, then don't use Python/dtoa.c. */ +#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION) +#define PY_NO_SHORT_FLOAT_REPR +#endif + +/* Py_DEPRECATED(version) + * Declare a variable, type, or function deprecated. + * Usage: + * extern int old_var Py_DEPRECATED(2.3); + * typedef int T1 Py_DEPRECATED(2.4); + * extern int x() Py_DEPRECATED(2.5); + */ +#if defined(__GNUC__) && ((__GNUC__ >= 4) || \ + (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) +#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__)) +#else +#define Py_DEPRECATED(VERSION_UNUSED) +#endif + +/************************************************************************** +Prototypes that are missing from the standard include files on some systems +(and possibly only some versions of such systems.) + +Please be conservative with adding new ones, document them and enclose them +in platform-specific #ifdefs. +**************************************************************************/ + +#ifdef SOLARIS +/* Unchecked */ +extern int gethostname(char *, int); +#endif + +#ifdef __BEOS__ +/* Unchecked */ +/* It's in the libs, but not the headers... - [cjh] */ +int shutdown( int, int ); +#endif + +#ifdef HAVE__GETPTY +#include /* we need to import mode_t */ +extern char * _getpty(int *, int, mode_t, int); +#endif + +/* On QNX 6, struct termio must be declared by including sys/termio.h + if TCGETA, TCSETA, TCSETAW, or TCSETAF are used. sys/termio.h must + be included before termios.h or it will generate an error. */ +#ifdef HAVE_SYS_TERMIO_H +#include +#endif + +#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) +#if !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H) && !defined(HAVE_UTIL_H) +/* BSDI does not supply a prototype for the 'openpty' and 'forkpty' + functions, even though they are included in libutil. */ +#include +extern int openpty(int *, int *, char *, struct termios *, struct winsize *); +extern pid_t forkpty(int *, char *, struct termios *, struct winsize *); +#endif /* !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H) */ +#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */ + + +/* These are pulled from various places. It isn't obvious on what platforms + they are necessary, nor what the exact prototype should look like (which + is likely to vary between platforms!) If you find you need one of these + declarations, please move them to a platform-specific block and include + proper prototypes. */ +#if 0 + +/* From Modules/resource.c */ +extern int getrusage(); +extern int getpagesize(); + +/* From Python/sysmodule.c and Modules/posixmodule.c */ +extern int fclose(FILE *); + +/* From Modules/posixmodule.c */ +extern int fdatasync(int); +#endif /* 0 */ + + +/* On 4.4BSD-descendants, ctype functions serves the whole range of + * wchar_t character set rather than single byte code points only. + * This characteristic can break some operations of string object + * including str.upper() and str.split() on UTF-8 locales. This + * workaround was provided by Tim Robbins of FreeBSD project. + */ + +#ifdef __FreeBSD__ +#include +#if __FreeBSD_version > 500039 +# define _PY_PORT_CTYPE_UTF8_ISSUE +#endif +#endif + + +#if defined(__APPLE__) +# define _PY_PORT_CTYPE_UTF8_ISSUE +#endif + +#ifdef _PY_PORT_CTYPE_UTF8_ISSUE +#include +#include +#undef isalnum +#define isalnum(c) iswalnum(btowc(c)) +#undef isalpha +#define isalpha(c) iswalpha(btowc(c)) +#undef islower +#define islower(c) iswlower(btowc(c)) +#undef isspace +#define isspace(c) iswspace(btowc(c)) +#undef isupper +#define isupper(c) iswupper(btowc(c)) +#undef tolower +#define tolower(c) towlower(btowc(c)) +#undef toupper +#define toupper(c) towupper(btowc(c)) +#endif + + +/* Declarations for symbol visibility. + + PyAPI_FUNC(type): Declares a public Python API function and return type + PyAPI_DATA(type): Declares public Python data and its type + PyMODINIT_FUNC: A Python module init function. If these functions are + inside the Python core, they are private to the core. + If in an extension module, it may be declared with + external linkage depending on the platform. + + As a number of platforms support/require "__declspec(dllimport/dllexport)", + we support a HAVE_DECLSPEC_DLL macro to save duplication. +*/ + +/* + All windows ports, except cygwin, are handled in PC/pyconfig.h. + + BeOS and cygwin are the only other autoconf platform requiring special + linkage handling and both of these use __declspec(). +*/ +#if defined(__CYGWIN__) || defined(__BEOS__) +# define HAVE_DECLSPEC_DLL +#endif + +/* only get special linkage if built as shared or platform is Cygwin */ +#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__) +# if defined(HAVE_DECLSPEC_DLL) +# ifdef Py_BUILD_CORE +# define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE +# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE + /* module init functions inside the core need no external linkage */ + /* except for Cygwin to handle embedding (FIXME: BeOS too?) */ +# if defined(__CYGWIN__) +# define PyMODINIT_FUNC __declspec(dllexport) void +# else /* __CYGWIN__ */ +# define PyMODINIT_FUNC void +# endif /* __CYGWIN__ */ +# else /* Py_BUILD_CORE */ + /* Building an extension module, or an embedded situation */ + /* public Python functions and data are imported */ + /* Under Cygwin, auto-import functions to prevent compilation */ + /* failures similar to those described at the bottom of 4.1: */ + /* http://docs.python.org/extending/windows.html#a-cookbook-approach */ +# if !defined(__CYGWIN__) +# define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE +# endif /* !__CYGWIN__ */ +# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE + /* module init functions outside the core must be exported */ +# if defined(__cplusplus) +# define PyMODINIT_FUNC extern "C" __declspec(dllexport) void +# else /* __cplusplus */ +# define PyMODINIT_FUNC __declspec(dllexport) void +# endif /* __cplusplus */ +# endif /* Py_BUILD_CORE */ +# endif /* HAVE_DECLSPEC */ +#endif /* Py_ENABLE_SHARED */ + +/* If no external linkage macros defined by now, create defaults */ +#ifndef PyAPI_FUNC +# define PyAPI_FUNC(RTYPE) RTYPE +#endif +#ifndef PyAPI_DATA +# define PyAPI_DATA(RTYPE) extern RTYPE +#endif +#ifndef PyMODINIT_FUNC +# if defined(__cplusplus) +# define PyMODINIT_FUNC extern "C" void +# else /* __cplusplus */ +# define PyMODINIT_FUNC void +# endif /* __cplusplus */ +#endif + +/* Deprecated DL_IMPORT and DL_EXPORT macros */ +#if defined(Py_ENABLE_SHARED) && defined (HAVE_DECLSPEC_DLL) +# if defined(Py_BUILD_CORE) +# define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE +# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE +# else +# define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE +# define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE +# endif +#endif +#ifndef DL_EXPORT +# define DL_EXPORT(RTYPE) RTYPE +#endif +#ifndef DL_IMPORT +# define DL_IMPORT(RTYPE) RTYPE +#endif +/* End of deprecated DL_* macros */ + +/* If the fd manipulation macros aren't defined, + here is a set that should do the job */ + +#if 0 /* disabled and probably obsolete */ + +#ifndef FD_SETSIZE +#define FD_SETSIZE 256 +#endif + +#ifndef FD_SET + +typedef long fd_mask; + +#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */ +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif /* howmany */ + +typedef struct fd_set { + fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)]; +} fd_set; + +#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) +#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) +#define FD_ZERO(p) memset((char *)(p), '\0', sizeof(*(p))) + +#endif /* FD_SET */ + +#endif /* fd manipulation macros */ + + +/* limits.h constants that may be missing */ + +#ifndef INT_MAX +#define INT_MAX 2147483647 +#endif + +#ifndef LONG_MAX +#if SIZEOF_LONG == 4 +#define LONG_MAX 0X7FFFFFFFL +#elif SIZEOF_LONG == 8 +#define LONG_MAX 0X7FFFFFFFFFFFFFFFL +#else +#error "could not set LONG_MAX in pyport.h" +#endif +#endif + +#ifndef LONG_MIN +#define LONG_MIN (-LONG_MAX-1) +#endif + +#ifndef LONG_BIT +#define LONG_BIT (8 * SIZEOF_LONG) +#endif + +#if LONG_BIT != 8 * SIZEOF_LONG +/* 04-Oct-2000 LONG_BIT is apparently (mis)defined as 64 on some recent + * 32-bit platforms using gcc. We try to catch that here at compile-time + * rather than waiting for integer multiplication to trigger bogus + * overflows. + */ +#error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)." +#endif + +#ifdef __cplusplus +} +#endif + +/* + * Hide GCC attributes from compilers that don't support them. + */ +#if (!defined(__GNUC__) || __GNUC__ < 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ) && \ + !defined(RISCOS) +#define Py_GCC_ATTRIBUTE(x) +#else +#define Py_GCC_ATTRIBUTE(x) __attribute__(x) +#endif + +/* + * Add PyArg_ParseTuple format where available. + */ +#ifdef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE +#define Py_FORMAT_PARSETUPLE(func,p1,p2) __attribute__((format(func,p1,p2))) +#else +#define Py_FORMAT_PARSETUPLE(func,p1,p2) +#endif + +/* + * Specify alignment on compilers that support it. + */ +#if defined(__GNUC__) && __GNUC__ >= 3 +#define Py_ALIGNED(x) __attribute__((aligned(x))) +#else +#define Py_ALIGNED(x) +#endif + +/* Eliminate end-of-loop code not reached warnings from SunPro C + * when using do{...}while(0) macros + */ +#ifdef __SUNPRO_C +#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED) +#endif + +/* + * Older Microsoft compilers don't support the C99 long long literal suffixes, + * so these will be defined in PC/pyconfig.h for those compilers. + */ +#ifndef Py_LL +#define Py_LL(x) x##LL +#endif + +#ifndef Py_ULL +#define Py_ULL(x) Py_LL(x##U) +#endif + +#endif /* Py_PYPORT_H */ diff --git a/python/include/pystate.h b/python/include/pystate.h new file mode 100644 index 000000000..8d74940f9 --- /dev/null +++ b/python/include/pystate.h @@ -0,0 +1,197 @@ + +/* Thread and interpreter state structures and their interfaces */ + + +#ifndef Py_PYSTATE_H +#define Py_PYSTATE_H +#ifdef __cplusplus +extern "C" { +#endif + +/* State shared between threads */ + +struct _ts; /* Forward */ +struct _is; /* Forward */ + +typedef struct _is { + + struct _is *next; + struct _ts *tstate_head; + + PyObject *modules; + PyObject *sysdict; + PyObject *builtins; + PyObject *modules_reloading; + + PyObject *codec_search_path; + PyObject *codec_search_cache; + PyObject *codec_error_registry; + +#ifdef HAVE_DLOPEN + int dlopenflags; +#endif +#ifdef WITH_TSC + int tscdump; +#endif + +} PyInterpreterState; + + +/* State unique per thread */ + +struct _frame; /* Avoid including frameobject.h */ + +/* Py_tracefunc return -1 when raising an exception, or 0 for success. */ +typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *); + +/* The following values are used for 'what' for tracefunc functions: */ +#define PyTrace_CALL 0 +#define PyTrace_EXCEPTION 1 +#define PyTrace_LINE 2 +#define PyTrace_RETURN 3 +#define PyTrace_C_CALL 4 +#define PyTrace_C_EXCEPTION 5 +#define PyTrace_C_RETURN 6 + +typedef struct _ts { + /* See Python/ceval.c for comments explaining most fields */ + + struct _ts *next; + PyInterpreterState *interp; + + struct _frame *frame; + int recursion_depth; + /* 'tracing' keeps track of the execution depth when tracing/profiling. + This is to prevent the actual trace/profile code from being recorded in + the trace/profile. */ + int tracing; + int use_tracing; + + Py_tracefunc c_profilefunc; + Py_tracefunc c_tracefunc; + PyObject *c_profileobj; + PyObject *c_traceobj; + + PyObject *curexc_type; + PyObject *curexc_value; + PyObject *curexc_traceback; + + PyObject *exc_type; + PyObject *exc_value; + PyObject *exc_traceback; + + PyObject *dict; /* Stores per-thread state */ + + /* tick_counter is incremented whenever the check_interval ticker + * reaches zero. The purpose is to give a useful measure of the number + * of interpreted bytecode instructions in a given thread. This + * extremely lightweight statistic collector may be of interest to + * profilers (like psyco.jit()), although nothing in the core uses it. + */ + int tick_counter; + + int gilstate_counter; + + PyObject *async_exc; /* Asynchronous exception to raise */ + long thread_id; /* Thread id where this tstate was created */ + + /* XXX signal handlers should also be here */ + +} PyThreadState; + + +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void); +PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *); +PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *); + +PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); +PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *); +PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *); +PyAPI_FUNC(void) PyThreadState_Delete(PyThreadState *); +#ifdef WITH_THREAD +PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void); +#endif + +PyAPI_FUNC(PyThreadState *) PyThreadState_Get(void); +PyAPI_FUNC(PyThreadState *) PyThreadState_Swap(PyThreadState *); +PyAPI_FUNC(PyObject *) PyThreadState_GetDict(void); +PyAPI_FUNC(int) PyThreadState_SetAsyncExc(long, PyObject *); + + +/* Variable and macro for in-line access to current thread state */ + +PyAPI_DATA(PyThreadState *) _PyThreadState_Current; + +#ifdef Py_DEBUG +#define PyThreadState_GET() PyThreadState_Get() +#else +#define PyThreadState_GET() (_PyThreadState_Current) +#endif + +typedef + enum {PyGILState_LOCKED, PyGILState_UNLOCKED} + PyGILState_STATE; + +/* Ensure that the current thread is ready to call the Python + C API, regardless of the current state of Python, or of its + thread lock. This may be called as many times as desired + by a thread so long as each call is matched with a call to + PyGILState_Release(). In general, other thread-state APIs may + be used between _Ensure() and _Release() calls, so long as the + thread-state is restored to its previous state before the Release(). + For example, normal use of the Py_BEGIN_ALLOW_THREADS/ + Py_END_ALLOW_THREADS macros are acceptable. + + The return value is an opaque "handle" to the thread state when + PyGILState_Ensure() was called, and must be passed to + PyGILState_Release() to ensure Python is left in the same state. Even + though recursive calls are allowed, these handles can *not* be shared - + each unique call to PyGILState_Ensure must save the handle for its + call to PyGILState_Release. + + When the function returns, the current thread will hold the GIL. + + Failure is a fatal error. +*/ +PyAPI_FUNC(PyGILState_STATE) PyGILState_Ensure(void); + +/* Release any resources previously acquired. After this call, Python's + state will be the same as it was prior to the corresponding + PyGILState_Ensure() call (but generally this state will be unknown to + the caller, hence the use of the GILState API.) + + Every call to PyGILState_Ensure must be matched by a call to + PyGILState_Release on the same thread. +*/ +PyAPI_FUNC(void) PyGILState_Release(PyGILState_STATE); + +/* Helper/diagnostic function - get the current thread state for + this thread. May return NULL if no GILState API has been used + on the current thread. Note that the main thread always has such a + thread-state, even if no auto-thread-state call has been made + on the main thread. +*/ +PyAPI_FUNC(PyThreadState *) PyGILState_GetThisThreadState(void); + +/* The implementation of sys._current_frames() Returns a dict mapping + thread id to that thread's current frame. +*/ +PyAPI_FUNC(PyObject *) _PyThread_CurrentFrames(void); + +/* Routines for advanced debuggers, requested by David Beazley. + Don't use unless you know what you are doing! */ +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Head(void); +PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_Next(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) PyInterpreterState_ThreadHead(PyInterpreterState *); +PyAPI_FUNC(PyThreadState *) PyThreadState_Next(PyThreadState *); + +typedef struct _frame *(*PyThreadFrameGetter)(PyThreadState *self_); + +/* hook for PyEval_GetFrame(), requested for Psyco */ +PyAPI_DATA(PyThreadFrameGetter) _PyThreadState_GetFrame; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYSTATE_H */ diff --git a/python/include/pystrcmp.h b/python/include/pystrcmp.h new file mode 100644 index 000000000..369c7e77f --- /dev/null +++ b/python/include/pystrcmp.h @@ -0,0 +1,23 @@ +#ifndef Py_STRCMP_H +#define Py_STRCMP_H + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(int) PyOS_mystrnicmp(const char *, const char *, Py_ssize_t); +PyAPI_FUNC(int) PyOS_mystricmp(const char *, const char *); + +#if defined(MS_WINDOWS) || defined(PYOS_OS2) +#define PyOS_strnicmp strnicmp +#define PyOS_stricmp stricmp +#else +#define PyOS_strnicmp PyOS_mystrnicmp +#define PyOS_stricmp PyOS_mystricmp +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_STRCMP_H */ diff --git a/python/include/pystrtod.h b/python/include/pystrtod.h new file mode 100644 index 000000000..eec434f1b --- /dev/null +++ b/python/include/pystrtod.h @@ -0,0 +1,45 @@ +#ifndef Py_STRTOD_H +#define Py_STRTOD_H + +#ifdef __cplusplus +extern "C" { +#endif + + +PyAPI_FUNC(double) PyOS_ascii_strtod(const char *str, char **ptr); +PyAPI_FUNC(double) PyOS_ascii_atof(const char *str); + +/* Deprecated in 2.7 and 3.1. Will disappear in 2.8 (if it exists) and 3.2 */ +PyAPI_FUNC(char *) PyOS_ascii_formatd(char *buffer, size_t buf_len, + const char *format, double d); +PyAPI_FUNC(double) PyOS_string_to_double(const char *str, + char **endptr, + PyObject *overflow_exception); + +/* The caller is responsible for calling PyMem_Free to free the buffer + that's is returned. */ +PyAPI_FUNC(char *) PyOS_double_to_string(double val, + char format_code, + int precision, + int flags, + int *type); + +PyAPI_FUNC(double) _Py_parse_inf_or_nan(const char *p, char **endptr); + + +/* PyOS_double_to_string's "flags" parameter can be set to 0 or more of: */ +#define Py_DTSF_SIGN 0x01 /* always add the sign */ +#define Py_DTSF_ADD_DOT_0 0x02 /* if the result is an integer add ".0" */ +#define Py_DTSF_ALT 0x04 /* "alternate" formatting. it's format_code + specific */ + +/* PyOS_double_to_string's "type", if non-NULL, will be set to one of: */ +#define Py_DTST_FINITE 0 +#define Py_DTST_INFINITE 1 +#define Py_DTST_NAN 2 + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_STRTOD_H */ diff --git a/python/include/pythonrun.h b/python/include/pythonrun.h new file mode 100644 index 000000000..6bfc17505 --- /dev/null +++ b/python/include/pythonrun.h @@ -0,0 +1,181 @@ + +/* Interfaces to parse and execute pieces of python code */ + +#ifndef Py_PYTHONRUN_H +#define Py_PYTHONRUN_H +#ifdef __cplusplus +extern "C" { +#endif + +#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \ + CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \ + CO_FUTURE_UNICODE_LITERALS) +#define PyCF_MASK_OBSOLETE (CO_NESTED) +#define PyCF_SOURCE_IS_UTF8 0x0100 +#define PyCF_DONT_IMPLY_DEDENT 0x0200 +#define PyCF_ONLY_AST 0x0400 + +typedef struct { + int cf_flags; /* bitmask of CO_xxx flags relevant to future */ +} PyCompilerFlags; + +PyAPI_FUNC(void) Py_SetProgramName(char *); +PyAPI_FUNC(char *) Py_GetProgramName(void); + +PyAPI_FUNC(void) Py_SetPythonHome(char *); +PyAPI_FUNC(char *) Py_GetPythonHome(void); + +PyAPI_FUNC(void) Py_Initialize(void); +PyAPI_FUNC(void) Py_InitializeEx(int); +PyAPI_FUNC(void) Py_Finalize(void); +PyAPI_FUNC(int) Py_IsInitialized(void); +PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void); +PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *); + +PyAPI_FUNC(int) PyRun_AnyFileFlags(FILE *, const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_AnyFileExFlags(FILE *, const char *, int, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_SimpleStringFlags(const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_SimpleFileExFlags(FILE *, const char *, int, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_InteractiveOneFlags(FILE *, const char *, PyCompilerFlags *); +PyAPI_FUNC(int) PyRun_InteractiveLoopFlags(FILE *, const char *, PyCompilerFlags *); + +PyAPI_FUNC(struct _mod *) PyParser_ASTFromString(const char *, const char *, + int, PyCompilerFlags *flags, + PyArena *); +PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile(FILE *, const char *, int, + char *, char *, + PyCompilerFlags *, int *, + PyArena *); +#define PyParser_SimpleParseString(S, B) \ + PyParser_SimpleParseStringFlags(S, B, 0) +#define PyParser_SimpleParseFile(FP, S, B) \ + PyParser_SimpleParseFileFlags(FP, S, B, 0) +PyAPI_FUNC(struct _node *) PyParser_SimpleParseStringFlags(const char *, int, + int); +PyAPI_FUNC(struct _node *) PyParser_SimpleParseFileFlags(FILE *, const char *, + int, int); + +PyAPI_FUNC(PyObject *) PyRun_StringFlags(const char *, int, PyObject *, + PyObject *, PyCompilerFlags *); + +PyAPI_FUNC(PyObject *) PyRun_FileExFlags(FILE *, const char *, int, + PyObject *, PyObject *, int, + PyCompilerFlags *); + +#define Py_CompileString(str, p, s) Py_CompileStringFlags(str, p, s, NULL) +PyAPI_FUNC(PyObject *) Py_CompileStringFlags(const char *, const char *, int, + PyCompilerFlags *); +PyAPI_FUNC(struct symtable *) Py_SymtableString(const char *, const char *, int); + +PyAPI_FUNC(void) PyErr_Print(void); +PyAPI_FUNC(void) PyErr_PrintEx(int); +PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *); + +PyAPI_FUNC(int) Py_AtExit(void (*func)(void)); + +PyAPI_FUNC(void) Py_Exit(int); + +PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *); + +/* Bootstrap */ +PyAPI_FUNC(int) Py_Main(int argc, char **argv); + +/* Use macros for a bunch of old variants */ +#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL) +#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL) +#define PyRun_AnyFileEx(fp, name, closeit) \ + PyRun_AnyFileExFlags(fp, name, closeit, NULL) +#define PyRun_AnyFileFlags(fp, name, flags) \ + PyRun_AnyFileExFlags(fp, name, 0, flags) +#define PyRun_SimpleString(s) PyRun_SimpleStringFlags(s, NULL) +#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags(f, p, 0, NULL) +#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags(f, p, c, NULL) +#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags(f, p, NULL) +#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags(f, p, NULL) +#define PyRun_File(fp, p, s, g, l) \ + PyRun_FileExFlags(fp, p, s, g, l, 0, NULL) +#define PyRun_FileEx(fp, p, s, g, l, c) \ + PyRun_FileExFlags(fp, p, s, g, l, c, NULL) +#define PyRun_FileFlags(fp, p, s, g, l, flags) \ + PyRun_FileExFlags(fp, p, s, g, l, 0, flags) + +/* In getpath.c */ +PyAPI_FUNC(char *) Py_GetProgramFullPath(void); +PyAPI_FUNC(char *) Py_GetPrefix(void); +PyAPI_FUNC(char *) Py_GetExecPrefix(void); +PyAPI_FUNC(char *) Py_GetPath(void); + +/* In their own files */ +PyAPI_FUNC(const char *) Py_GetVersion(void); +PyAPI_FUNC(const char *) Py_GetPlatform(void); +PyAPI_FUNC(const char *) Py_GetCopyright(void); +PyAPI_FUNC(const char *) Py_GetCompiler(void); +PyAPI_FUNC(const char *) Py_GetBuildInfo(void); +PyAPI_FUNC(const char *) _Py_svnversion(void); +PyAPI_FUNC(const char *) Py_SubversionRevision(void); +PyAPI_FUNC(const char *) Py_SubversionShortBranch(void); +PyAPI_FUNC(const char *) _Py_hgidentifier(void); +PyAPI_FUNC(const char *) _Py_hgversion(void); + +/* Internal -- various one-time initializations */ +PyAPI_FUNC(PyObject *) _PyBuiltin_Init(void); +PyAPI_FUNC(PyObject *) _PySys_Init(void); +PyAPI_FUNC(void) _PyImport_Init(void); +PyAPI_FUNC(void) _PyExc_Init(void); +PyAPI_FUNC(void) _PyImportHooks_Init(void); +PyAPI_FUNC(int) _PyFrame_Init(void); +PyAPI_FUNC(int) _PyInt_Init(void); +PyAPI_FUNC(int) _PyLong_Init(void); +PyAPI_FUNC(void) _PyFloat_Init(void); +PyAPI_FUNC(int) PyByteArray_Init(void); +PyAPI_FUNC(void) _PyRandom_Init(void); + +/* Various internal finalizers */ +PyAPI_FUNC(void) _PyExc_Fini(void); +PyAPI_FUNC(void) _PyImport_Fini(void); +PyAPI_FUNC(void) PyMethod_Fini(void); +PyAPI_FUNC(void) PyFrame_Fini(void); +PyAPI_FUNC(void) PyCFunction_Fini(void); +PyAPI_FUNC(void) PyDict_Fini(void); +PyAPI_FUNC(void) PyTuple_Fini(void); +PyAPI_FUNC(void) PyList_Fini(void); +PyAPI_FUNC(void) PySet_Fini(void); +PyAPI_FUNC(void) PyString_Fini(void); +PyAPI_FUNC(void) PyInt_Fini(void); +PyAPI_FUNC(void) PyFloat_Fini(void); +PyAPI_FUNC(void) PyOS_FiniInterrupts(void); +PyAPI_FUNC(void) PyByteArray_Fini(void); + +/* Stuff with no proper home (yet) */ +PyAPI_FUNC(char *) PyOS_Readline(FILE *, FILE *, char *); +PyAPI_DATA(int) (*PyOS_InputHook)(void); +PyAPI_DATA(char) *(*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, char *); +PyAPI_DATA(PyThreadState*) _PyOS_ReadlineTState; + +/* Stack size, in "pointers" (so we get extra safety margins + on 64-bit platforms). On a 32-bit platform, this translates + to a 8k margin. */ +#define PYOS_STACK_MARGIN 2048 + +#if defined(WIN32) && !defined(MS_WIN64) && defined(_MSC_VER) && _MSC_VER >= 1300 +/* Enable stack checking under Microsoft C */ +#define USE_STACKCHECK +#endif + +#ifdef USE_STACKCHECK +/* Check that we aren't overflowing our stack */ +PyAPI_FUNC(int) PyOS_CheckStack(void); +#endif + +/* Signals */ +typedef void (*PyOS_sighandler_t)(int); +PyAPI_FUNC(PyOS_sighandler_t) PyOS_getsig(int); +PyAPI_FUNC(PyOS_sighandler_t) PyOS_setsig(int, PyOS_sighandler_t); + +/* Random */ +PyAPI_FUNC(int) _PyOS_URandom (void *buffer, Py_ssize_t size); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYTHONRUN_H */ diff --git a/python/include/pythread.h b/python/include/pythread.h new file mode 100644 index 000000000..dfd61575e --- /dev/null +++ b/python/include/pythread.h @@ -0,0 +1,41 @@ + +#ifndef Py_PYTHREAD_H +#define Py_PYTHREAD_H + +typedef void *PyThread_type_lock; +typedef void *PyThread_type_sema; + +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(void) PyThread_init_thread(void); +PyAPI_FUNC(long) PyThread_start_new_thread(void (*)(void *), void *); +PyAPI_FUNC(void) PyThread_exit_thread(void); +PyAPI_FUNC(long) PyThread_get_thread_ident(void); + +PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void); +PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock); +PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int); +#define WAIT_LOCK 1 +#define NOWAIT_LOCK 0 +PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock); + +PyAPI_FUNC(size_t) PyThread_get_stacksize(void); +PyAPI_FUNC(int) PyThread_set_stacksize(size_t); + +/* Thread Local Storage (TLS) API */ +PyAPI_FUNC(int) PyThread_create_key(void); +PyAPI_FUNC(void) PyThread_delete_key(int); +PyAPI_FUNC(int) PyThread_set_key_value(int, void *); +PyAPI_FUNC(void *) PyThread_get_key_value(int); +PyAPI_FUNC(void) PyThread_delete_key_value(int key); + +/* Cleanup after a fork */ +PyAPI_FUNC(void) PyThread_ReInitTLS(void); + +#ifdef __cplusplus +} +#endif + +#endif /* !Py_PYTHREAD_H */ diff --git a/python/include/rangeobject.h b/python/include/rangeobject.h new file mode 100644 index 000000000..36c9cee5a --- /dev/null +++ b/python/include/rangeobject.h @@ -0,0 +1,28 @@ + +/* Range object interface */ + +#ifndef Py_RANGEOBJECT_H +#define Py_RANGEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* This is about the type 'xrange', not the built-in function range(), which + returns regular lists. */ + +/* +A range object represents an integer range. This is an immutable object; +a range cannot change its value after creation. + +Range objects behave like the corresponding tuple objects except that +they are represented by a start, stop, and step datamembers. +*/ + +PyAPI_DATA(PyTypeObject) PyRange_Type; + +#define PyRange_Check(op) (Py_TYPE(op) == &PyRange_Type) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_RANGEOBJECT_H */ diff --git a/python/include/setobject.h b/python/include/setobject.h new file mode 100644 index 000000000..52b07d52d --- /dev/null +++ b/python/include/setobject.h @@ -0,0 +1,99 @@ +/* Set object interface */ + +#ifndef Py_SETOBJECT_H +#define Py_SETOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* +There are three kinds of slots in the table: + +1. Unused: key == NULL +2. Active: key != NULL and key != dummy +3. Dummy: key == dummy + +Note: .pop() abuses the hash field of an Unused or Dummy slot to +hold a search finger. The hash field of Unused or Dummy slots has +no meaning otherwise. +*/ + +#define PySet_MINSIZE 8 + +typedef struct { + long hash; /* cached hash code for the entry key */ + PyObject *key; +} setentry; + + +/* +This data structure is shared by set and frozenset objects. +*/ + +typedef struct _setobject PySetObject; +struct _setobject { + PyObject_HEAD + + Py_ssize_t fill; /* # Active + # Dummy */ + Py_ssize_t used; /* # Active */ + + /* The table contains mask + 1 slots, and that's a power of 2. + * We store the mask instead of the size because the mask is more + * frequently needed. + */ + Py_ssize_t mask; + + /* table points to smalltable for small tables, else to + * additional malloc'ed memory. table is never NULL! This rule + * saves repeated runtime null-tests. + */ + setentry *table; + setentry *(*lookup)(PySetObject *so, PyObject *key, long hash); + setentry smalltable[PySet_MINSIZE]; + + long hash; /* only used by frozenset objects */ + PyObject *weakreflist; /* List of weak references */ +}; + +PyAPI_DATA(PyTypeObject) PySet_Type; +PyAPI_DATA(PyTypeObject) PyFrozenSet_Type; + +/* Invariants for frozensets: + * data is immutable. + * hash is the hash of the frozenset or -1 if not computed yet. + * Invariants for sets: + * hash is -1 + */ + +#define PyFrozenSet_CheckExact(ob) (Py_TYPE(ob) == &PyFrozenSet_Type) +#define PyAnySet_CheckExact(ob) \ + (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type) +#define PyAnySet_Check(ob) \ + (Py_TYPE(ob) == &PySet_Type || Py_TYPE(ob) == &PyFrozenSet_Type || \ + PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \ + PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) +#define PySet_Check(ob) \ + (Py_TYPE(ob) == &PySet_Type || \ + PyType_IsSubtype(Py_TYPE(ob), &PySet_Type)) +#define PyFrozenSet_Check(ob) \ + (Py_TYPE(ob) == &PyFrozenSet_Type || \ + PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) + +PyAPI_FUNC(PyObject *) PySet_New(PyObject *); +PyAPI_FUNC(PyObject *) PyFrozenSet_New(PyObject *); +PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); +#define PySet_GET_SIZE(so) (((PySetObject *)(so))->used) +PyAPI_FUNC(int) PySet_Clear(PyObject *set); +PyAPI_FUNC(int) PySet_Contains(PyObject *anyset, PyObject *key); +PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); +PyAPI_FUNC(int) PySet_Add(PyObject *set, PyObject *key); +PyAPI_FUNC(int) _PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key); +PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash); +PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); +PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SETOBJECT_H */ diff --git a/python/include/sliceobject.h b/python/include/sliceobject.h new file mode 100644 index 000000000..8ab62dd4f --- /dev/null +++ b/python/include/sliceobject.h @@ -0,0 +1,44 @@ +#ifndef Py_SLICEOBJECT_H +#define Py_SLICEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* The unique ellipsis object "..." */ + +PyAPI_DATA(PyObject) _Py_EllipsisObject; /* Don't use this directly */ + +#define Py_Ellipsis (&_Py_EllipsisObject) + +/* Slice object interface */ + +/* + +A slice object containing start, stop, and step data members (the +names are from range). After much talk with Guido, it was decided to +let these be any arbitrary python type. Py_None stands for omitted values. +*/ + +typedef struct { + PyObject_HEAD + PyObject *start, *stop, *step; /* not NULL */ +} PySliceObject; + +PyAPI_DATA(PyTypeObject) PySlice_Type; +PyAPI_DATA(PyTypeObject) PyEllipsis_Type; + +#define PySlice_Check(op) (Py_TYPE(op) == &PySlice_Type) + +PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop, + PyObject* step); +PyAPI_FUNC(PyObject *) _PySlice_FromIndices(Py_ssize_t start, Py_ssize_t stop); +PyAPI_FUNC(int) PySlice_GetIndices(PySliceObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); +PyAPI_FUNC(int) PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length, + Py_ssize_t *start, Py_ssize_t *stop, + Py_ssize_t *step, Py_ssize_t *slicelength); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SLICEOBJECT_H */ diff --git a/python/include/stringobject.h b/python/include/stringobject.h new file mode 100644 index 000000000..18b5b411a --- /dev/null +++ b/python/include/stringobject.h @@ -0,0 +1,210 @@ + +/* String (str/bytes) object interface */ + +#ifndef Py_STRINGOBJECT_H +#define Py_STRINGOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* +Type PyStringObject represents a character string. An extra zero byte is +reserved at the end to ensure it is zero-terminated, but a size is +present so strings with null bytes in them can be represented. This +is an immutable object type. + +There are functions to create new string objects, to test +an object for string-ness, and to get the +string value. The latter function returns a null pointer +if the object is not of the proper type. +There is a variant that takes an explicit size as well as a +variant that assumes a zero-terminated string. Note that none of the +functions should be applied to nil objects. +*/ + +/* Caching the hash (ob_shash) saves recalculation of a string's hash value. + Interning strings (ob_sstate) tries to ensure that only one string + object with a given value exists, so equality tests can be one pointer + comparison. This is generally restricted to strings that "look like" + Python identifiers, although the intern() builtin can be used to force + interning of any string. + Together, these sped the interpreter by up to 20%. */ + +typedef struct { + PyObject_VAR_HEAD + long ob_shash; + int ob_sstate; + char ob_sval[1]; + + /* Invariants: + * ob_sval contains space for 'ob_size+1' elements. + * ob_sval[ob_size] == 0. + * ob_shash is the hash of the string or -1 if not computed yet. + * ob_sstate != 0 iff the string object is in stringobject.c's + * 'interned' dictionary; in this case the two references + * from 'interned' to this object are *not counted* in ob_refcnt. + */ +} PyStringObject; + +#define SSTATE_NOT_INTERNED 0 +#define SSTATE_INTERNED_MORTAL 1 +#define SSTATE_INTERNED_IMMORTAL 2 + +PyAPI_DATA(PyTypeObject) PyBaseString_Type; +PyAPI_DATA(PyTypeObject) PyString_Type; + +#define PyString_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_STRING_SUBCLASS) +#define PyString_CheckExact(op) (Py_TYPE(op) == &PyString_Type) + +PyAPI_FUNC(PyObject *) PyString_FromStringAndSize(const char *, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyString_FromString(const char *); +PyAPI_FUNC(PyObject *) PyString_FromFormatV(const char*, va_list) + Py_GCC_ATTRIBUTE((format(printf, 1, 0))); +PyAPI_FUNC(PyObject *) PyString_FromFormat(const char*, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(Py_ssize_t) PyString_Size(PyObject *); +PyAPI_FUNC(char *) PyString_AsString(PyObject *); +PyAPI_FUNC(PyObject *) PyString_Repr(PyObject *, int); +PyAPI_FUNC(void) PyString_Concat(PyObject **, PyObject *); +PyAPI_FUNC(void) PyString_ConcatAndDel(PyObject **, PyObject *); +PyAPI_FUNC(int) _PyString_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(int) _PyString_Eq(PyObject *, PyObject*); +PyAPI_FUNC(PyObject *) PyString_Format(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyString_FormatLong(PyObject*, int, int, + int, char**, int*); +PyAPI_FUNC(PyObject *) PyString_DecodeEscape(const char *, Py_ssize_t, + const char *, Py_ssize_t, + const char *); + +PyAPI_FUNC(void) PyString_InternInPlace(PyObject **); +PyAPI_FUNC(void) PyString_InternImmortal(PyObject **); +PyAPI_FUNC(PyObject *) PyString_InternFromString(const char *); +PyAPI_FUNC(void) _Py_ReleaseInternedStrings(void); + +/* Use only if you know it's a string */ +#define PyString_CHECK_INTERNED(op) (((PyStringObject *)(op))->ob_sstate) + +/* Macro, trading safety for speed */ +#define PyString_AS_STRING(op) (((PyStringObject *)(op))->ob_sval) +#define PyString_GET_SIZE(op) Py_SIZE(op) + +/* _PyString_Join(sep, x) is like sep.join(x). sep must be PyStringObject*, + x must be an iterable object. */ +PyAPI_FUNC(PyObject *) _PyString_Join(PyObject *sep, PyObject *x); + +/* --- Generic Codecs ----------------------------------------------------- */ + +/* Create an object by decoding the encoded string s of the + given size. */ + +PyAPI_FUNC(PyObject*) PyString_Decode( + const char *s, /* encoded string */ + Py_ssize_t size, /* size of buffer */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a char buffer of the given size and returns a + Python object. */ + +PyAPI_FUNC(PyObject*) PyString_Encode( + const char *s, /* string char buffer */ + Py_ssize_t size, /* number of chars to encode */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a string object and returns the result as Python + object. */ + +PyAPI_FUNC(PyObject*) PyString_AsEncodedObject( + PyObject *str, /* string object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a string object and returns the result as Python string + object. + + If the codec returns an Unicode object, the object is converted + back to a string using the default encoding. + + DEPRECATED - use PyString_AsEncodedObject() instead. */ + +PyAPI_FUNC(PyObject*) PyString_AsEncodedString( + PyObject *str, /* string object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Decodes a string object and returns the result as Python + object. */ + +PyAPI_FUNC(PyObject*) PyString_AsDecodedObject( + PyObject *str, /* string object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Decodes a string object and returns the result as Python string + object. + + If the codec returns an Unicode object, the object is converted + back to a string using the default encoding. + + DEPRECATED - use PyString_AsDecodedObject() instead. */ + +PyAPI_FUNC(PyObject*) PyString_AsDecodedString( + PyObject *str, /* string object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Provides access to the internal data buffer and size of a string + object or the default encoded version of an Unicode object. Passing + NULL as *len parameter will force the string buffer to be + 0-terminated (passing a string with embedded NULL characters will + cause an exception). */ + +PyAPI_FUNC(int) PyString_AsStringAndSize( + register PyObject *obj, /* string or Unicode object */ + register char **s, /* pointer to buffer variable */ + register Py_ssize_t *len /* pointer to length variable or NULL + (only possible for 0-terminated + strings) */ + ); + + +/* Using the current locale, insert the thousands grouping + into the string pointed to by buffer. For the argument descriptions, + see Objects/stringlib/localeutil.h */ +PyAPI_FUNC(Py_ssize_t) _PyString_InsertThousandsGroupingLocale(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width); + +/* Using explicit passed-in values, insert the thousands grouping + into the string pointed to by buffer. For the argument descriptions, + see Objects/stringlib/localeutil.h */ +PyAPI_FUNC(Py_ssize_t) _PyString_InsertThousandsGrouping(char *buffer, + Py_ssize_t n_buffer, + char *digits, + Py_ssize_t n_digits, + Py_ssize_t min_width, + const char *grouping, + const char *thousands_sep); + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(PyObject *) _PyBytes_FormatAdvanced(PyObject *obj, + char *format_spec, + Py_ssize_t format_spec_len); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_STRINGOBJECT_H */ diff --git a/python/include/structmember.h b/python/include/structmember.h new file mode 100644 index 000000000..fe5b44ea3 --- /dev/null +++ b/python/include/structmember.h @@ -0,0 +1,99 @@ +#ifndef Py_STRUCTMEMBER_H +#define Py_STRUCTMEMBER_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Interface to map C struct members to Python object attributes */ + +#include /* For offsetof */ + +/* The offsetof() macro calculates the offset of a structure member + in its structure. Unfortunately this cannot be written down + portably, hence it is provided by a Standard C header file. + For pre-Standard C compilers, here is a version that usually works + (but watch out!): */ + +#ifndef offsetof +#define offsetof(type, member) ( (int) & ((type*)0) -> member ) +#endif + +/* An array of memberlist structures defines the name, type and offset + of selected members of a C structure. These can be read by + PyMember_Get() and set by PyMember_Set() (except if their READONLY flag + is set). The array must be terminated with an entry whose name + pointer is NULL. */ + +struct memberlist { + /* Obsolete version, for binary backwards compatibility */ + char *name; + int type; + int offset; + int flags; +}; + +typedef struct PyMemberDef { + /* Current version, use this */ + char *name; + int type; + Py_ssize_t offset; + int flags; + char *doc; +} PyMemberDef; + +/* Types */ +#define T_SHORT 0 +#define T_INT 1 +#define T_LONG 2 +#define T_FLOAT 3 +#define T_DOUBLE 4 +#define T_STRING 5 +#define T_OBJECT 6 +/* XXX the ordering here is weird for binary compatibility */ +#define T_CHAR 7 /* 1-character string */ +#define T_BYTE 8 /* 8-bit signed int */ +/* unsigned variants: */ +#define T_UBYTE 9 +#define T_USHORT 10 +#define T_UINT 11 +#define T_ULONG 12 + +/* Added by Jack: strings contained in the structure */ +#define T_STRING_INPLACE 13 + +/* Added by Lillo: bools contained in the structure (assumed char) */ +#define T_BOOL 14 + +#define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError + when the value is NULL, instead of + converting to None. */ +#ifdef HAVE_LONG_LONG +#define T_LONGLONG 17 +#define T_ULONGLONG 18 +#endif /* HAVE_LONG_LONG */ + +#define T_PYSSIZET 19 /* Py_ssize_t */ + + +/* Flags */ +#define READONLY 1 +#define RO READONLY /* Shorthand */ +#define READ_RESTRICTED 2 +#define PY_WRITE_RESTRICTED 4 +#define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED) + + +/* Obsolete API, for binary backwards compatibility */ +PyAPI_FUNC(PyObject *) PyMember_Get(const char *, struct memberlist *, const char *); +PyAPI_FUNC(int) PyMember_Set(char *, struct memberlist *, const char *, PyObject *); + +/* Current API, use this */ +PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, struct PyMemberDef *); +PyAPI_FUNC(int) PyMember_SetOne(char *, struct PyMemberDef *, PyObject *); + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_STRUCTMEMBER_H */ diff --git a/python/include/structseq.h b/python/include/structseq.h new file mode 100644 index 000000000..e662916fe --- /dev/null +++ b/python/include/structseq.h @@ -0,0 +1,41 @@ + +/* Tuple object interface */ + +#ifndef Py_STRUCTSEQ_H +#define Py_STRUCTSEQ_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PyStructSequence_Field { + char *name; + char *doc; +} PyStructSequence_Field; + +typedef struct PyStructSequence_Desc { + char *name; + char *doc; + struct PyStructSequence_Field *fields; + int n_in_sequence; +} PyStructSequence_Desc; + +extern char* PyStructSequence_UnnamedField; + +PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type, + PyStructSequence_Desc *desc); + +PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type); + +typedef struct { + PyObject_VAR_HEAD + PyObject *ob_item[1]; +} PyStructSequence; + +/* Macro, *only* to be used to fill in brand new objects */ +#define PyStructSequence_SET_ITEM(op, i, v) \ + (((PyStructSequence *)(op))->ob_item[i] = v) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_STRUCTSEQ_H */ diff --git a/python/include/symtable.h b/python/include/symtable.h new file mode 100644 index 000000000..e0a0be41b --- /dev/null +++ b/python/include/symtable.h @@ -0,0 +1,98 @@ +#ifndef Py_SYMTABLE_H +#define Py_SYMTABLE_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock } + _Py_block_ty; + +struct _symtable_entry; + +struct symtable { + const char *st_filename; /* name of file being compiled */ + struct _symtable_entry *st_cur; /* current symbol table entry */ + struct _symtable_entry *st_top; /* module entry */ + PyObject *st_symbols; /* dictionary of symbol table entries */ + PyObject *st_stack; /* stack of namespace info */ + PyObject *st_global; /* borrowed ref to MODULE in st_symbols */ + int st_nblocks; /* number of blocks */ + PyObject *st_private; /* name of current class or NULL */ + PyFutureFeatures *st_future; /* module's future features */ +}; + +typedef struct _symtable_entry { + PyObject_HEAD + PyObject *ste_id; /* int: key in st_symbols */ + PyObject *ste_symbols; /* dict: name to flags */ + PyObject *ste_name; /* string: name of block */ + PyObject *ste_varnames; /* list of variable names */ + PyObject *ste_children; /* list of child ids */ + _Py_block_ty ste_type; /* module, class, or function */ + int ste_unoptimized; /* false if namespace is optimized */ + int ste_nested; /* true if block is nested */ + unsigned ste_free : 1; /* true if block has free variables */ + unsigned ste_child_free : 1; /* true if a child block has free vars, + including free refs to globals */ + unsigned ste_generator : 1; /* true if namespace is a generator */ + unsigned ste_varargs : 1; /* true if block has varargs */ + unsigned ste_varkeywords : 1; /* true if block has varkeywords */ + unsigned ste_returns_value : 1; /* true if namespace uses return with + an argument */ + int ste_lineno; /* first line of block */ + int ste_opt_lineno; /* lineno of last exec or import * */ + int ste_tmpname; /* counter for listcomp temp vars */ + struct symtable *ste_table; +} PySTEntryObject; + +PyAPI_DATA(PyTypeObject) PySTEntry_Type; + +#define PySTEntry_Check(op) (Py_TYPE(op) == &PySTEntry_Type) + +PyAPI_FUNC(int) PyST_GetScope(PySTEntryObject *, PyObject *); + +PyAPI_FUNC(struct symtable *) PySymtable_Build(mod_ty, const char *, + PyFutureFeatures *); +PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *); + +PyAPI_FUNC(void) PySymtable_Free(struct symtable *); + +/* Flags for def-use information */ + +#define DEF_GLOBAL 1 /* global stmt */ +#define DEF_LOCAL 2 /* assignment in code block */ +#define DEF_PARAM 2<<1 /* formal parameter */ +#define USE 2<<2 /* name is used */ +#define DEF_FREE 2<<3 /* name used but not defined in nested block */ +#define DEF_FREE_CLASS 2<<4 /* free variable from class's method */ +#define DEF_IMPORT 2<<5 /* assignment occurred via import */ + +#define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT) + +/* GLOBAL_EXPLICIT and GLOBAL_IMPLICIT are used internally by the symbol + table. GLOBAL is returned from PyST_GetScope() for either of them. + It is stored in ste_symbols at bits 12-14. +*/ +#define SCOPE_OFF 11 +#define SCOPE_MASK 7 + +#define LOCAL 1 +#define GLOBAL_EXPLICIT 2 +#define GLOBAL_IMPLICIT 3 +#define FREE 4 +#define CELL 5 + +/* The following three names are used for the ste_unoptimized bit field */ +#define OPT_IMPORT_STAR 1 +#define OPT_EXEC 2 +#define OPT_BARE_EXEC 4 +#define OPT_TOPLEVEL 8 /* top-level names, including eval and exec */ + +#define GENERATOR 1 +#define GENERATOR_EXPRESSION 2 + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SYMTABLE_H */ diff --git a/python/include/sysmodule.h b/python/include/sysmodule.h new file mode 100644 index 000000000..16af1196e --- /dev/null +++ b/python/include/sysmodule.h @@ -0,0 +1,32 @@ + +/* System module interface */ + +#ifndef Py_SYSMODULE_H +#define Py_SYSMODULE_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(PyObject *) PySys_GetObject(char *); +PyAPI_FUNC(int) PySys_SetObject(char *, PyObject *); +PyAPI_FUNC(FILE *) PySys_GetFile(char *, FILE *); +PyAPI_FUNC(void) PySys_SetArgv(int, char **); +PyAPI_FUNC(void) PySys_SetArgvEx(int, char **, int); +PyAPI_FUNC(void) PySys_SetPath(char *); + +PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); +PyAPI_FUNC(void) PySys_WriteStderr(const char *format, ...) + Py_GCC_ATTRIBUTE((format(printf, 1, 2))); + +PyAPI_DATA(PyObject *) _PySys_TraceFunc, *_PySys_ProfileFunc; +PyAPI_DATA(int) _PySys_CheckInterval; + +PyAPI_FUNC(void) PySys_ResetWarnOptions(void); +PyAPI_FUNC(void) PySys_AddWarnOption(char *); +PyAPI_FUNC(int) PySys_HasWarnOptions(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_SYSMODULE_H */ diff --git a/python/include/timefuncs.h b/python/include/timefuncs.h new file mode 100644 index 000000000..553142dba --- /dev/null +++ b/python/include/timefuncs.h @@ -0,0 +1,23 @@ +/* timefuncs.h + */ + +/* Utility function related to timemodule.c. */ + +#ifndef TIMEFUNCS_H +#define TIMEFUNCS_H +#ifdef __cplusplus +extern "C" { +#endif + + +/* Cast double x to time_t, but raise ValueError if x is too large + * to fit in a time_t. ValueError is set on return iff the return + * value is (time_t)-1 and PyErr_Occurred(). + */ +PyAPI_FUNC(time_t) _PyTime_DoubleToTimet(double x); + + +#ifdef __cplusplus +} +#endif +#endif /* TIMEFUNCS_H */ diff --git a/python/include/token.h b/python/include/token.h new file mode 100644 index 000000000..72659ac05 --- /dev/null +++ b/python/include/token.h @@ -0,0 +1,85 @@ + +/* Token types */ + +#ifndef Py_TOKEN_H +#define Py_TOKEN_H +#ifdef __cplusplus +extern "C" { +#endif + +#undef TILDE /* Prevent clash of our definition with system macro. Ex AIX, ioctl.h */ + +#define ENDMARKER 0 +#define NAME 1 +#define NUMBER 2 +#define STRING 3 +#define NEWLINE 4 +#define INDENT 5 +#define DEDENT 6 +#define LPAR 7 +#define RPAR 8 +#define LSQB 9 +#define RSQB 10 +#define COLON 11 +#define COMMA 12 +#define SEMI 13 +#define PLUS 14 +#define MINUS 15 +#define STAR 16 +#define SLASH 17 +#define VBAR 18 +#define AMPER 19 +#define LESS 20 +#define GREATER 21 +#define EQUAL 22 +#define DOT 23 +#define PERCENT 24 +#define BACKQUOTE 25 +#define LBRACE 26 +#define RBRACE 27 +#define EQEQUAL 28 +#define NOTEQUAL 29 +#define LESSEQUAL 30 +#define GREATEREQUAL 31 +#define TILDE 32 +#define CIRCUMFLEX 33 +#define LEFTSHIFT 34 +#define RIGHTSHIFT 35 +#define DOUBLESTAR 36 +#define PLUSEQUAL 37 +#define MINEQUAL 38 +#define STAREQUAL 39 +#define SLASHEQUAL 40 +#define PERCENTEQUAL 41 +#define AMPEREQUAL 42 +#define VBAREQUAL 43 +#define CIRCUMFLEXEQUAL 44 +#define LEFTSHIFTEQUAL 45 +#define RIGHTSHIFTEQUAL 46 +#define DOUBLESTAREQUAL 47 +#define DOUBLESLASH 48 +#define DOUBLESLASHEQUAL 49 +#define AT 50 +/* Don't forget to update the table _PyParser_TokenNames in tokenizer.c! */ +#define OP 51 +#define ERRORTOKEN 52 +#define N_TOKENS 53 + +/* Special definitions for cooperation with parser */ + +#define NT_OFFSET 256 + +#define ISTERMINAL(x) ((x) < NT_OFFSET) +#define ISNONTERMINAL(x) ((x) >= NT_OFFSET) +#define ISEOF(x) ((x) == ENDMARKER) + + +PyAPI_DATA(char *) _PyParser_TokenNames[]; /* Token names */ +PyAPI_FUNC(int) PyToken_OneChar(int); +PyAPI_FUNC(int) PyToken_TwoChars(int, int); +PyAPI_FUNC(int) PyToken_ThreeChars(int, int, int); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TOKEN_H */ diff --git a/python/include/traceback.h b/python/include/traceback.h new file mode 100644 index 000000000..e7943dae9 --- /dev/null +++ b/python/include/traceback.h @@ -0,0 +1,31 @@ + +#ifndef Py_TRACEBACK_H +#define Py_TRACEBACK_H +#ifdef __cplusplus +extern "C" { +#endif + +struct _frame; + +/* Traceback interface */ + +typedef struct _traceback { + PyObject_HEAD + struct _traceback *tb_next; + struct _frame *tb_frame; + int tb_lasti; + int tb_lineno; +} PyTracebackObject; + +PyAPI_FUNC(int) PyTraceBack_Here(struct _frame *); +PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); +PyAPI_FUNC(int) _Py_DisplaySourceLine(PyObject *, const char *, int, int); + +/* Reveal traceback type so we can typecheck traceback objects */ +PyAPI_DATA(PyTypeObject) PyTraceBack_Type; +#define PyTraceBack_Check(v) (Py_TYPE(v) == &PyTraceBack_Type) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TRACEBACK_H */ diff --git a/python/include/tupleobject.h b/python/include/tupleobject.h new file mode 100644 index 000000000..a5ab73320 --- /dev/null +++ b/python/include/tupleobject.h @@ -0,0 +1,61 @@ + +/* Tuple object interface */ + +#ifndef Py_TUPLEOBJECT_H +#define Py_TUPLEOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +/* +Another generally useful object type is a tuple of object pointers. +For Python, this is an immutable type. C code can change the tuple items +(but not their number), and even use tuples are general-purpose arrays of +object references, but in general only brand new tuples should be mutated, +not ones that might already have been exposed to Python code. + +*** WARNING *** PyTuple_SetItem does not increment the new item's reference +count, but does decrement the reference count of the item it replaces, +if not nil. It does *decrement* the reference count if it is *not* +inserted in the tuple. Similarly, PyTuple_GetItem does not increment the +returned item's reference count. +*/ + +typedef struct { + PyObject_VAR_HEAD + PyObject *ob_item[1]; + + /* ob_item contains space for 'ob_size' elements. + * Items must normally not be NULL, except during construction when + * the tuple is not yet visible outside the function that builds it. + */ +} PyTupleObject; + +PyAPI_DATA(PyTypeObject) PyTuple_Type; + +#define PyTuple_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) +#define PyTuple_CheckExact(op) (Py_TYPE(op) == &PyTuple_Type) + +PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); +PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); +PyAPI_FUNC(PyObject *) PyTuple_GetItem(PyObject *, Py_ssize_t); +PyAPI_FUNC(int) PyTuple_SetItem(PyObject *, Py_ssize_t, PyObject *); +PyAPI_FUNC(PyObject *) PyTuple_GetSlice(PyObject *, Py_ssize_t, Py_ssize_t); +PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t); +PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...); +PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *); + +/* Macro, trading safety for speed */ +#define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i]) +#define PyTuple_GET_SIZE(op) Py_SIZE(op) + +/* Macro, *only* to be used to fill in brand new tuples */ +#define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v) + +PyAPI_FUNC(int) PyTuple_ClearFreeList(void); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_TUPLEOBJECT_H */ diff --git a/python/include/ucnhash.h b/python/include/ucnhash.h new file mode 100644 index 000000000..69b7774a9 --- /dev/null +++ b/python/include/ucnhash.h @@ -0,0 +1,33 @@ +/* Unicode name database interface */ + +#ifndef Py_UCNHASH_H +#define Py_UCNHASH_H +#ifdef __cplusplus +extern "C" { +#endif + +/* revised ucnhash CAPI interface (exported through a "wrapper") */ + +#define PyUnicodeData_CAPSULE_NAME "unicodedata.ucnhash_CAPI" + +typedef struct { + + /* Size of this struct */ + int size; + + /* Get name for a given character code. Returns non-zero if + success, zero if not. Does not set Python exceptions. + If self is NULL, data come from the default version of the database. + If it is not NULL, it should be a unicodedata.ucd_X_Y_Z object */ + int (*getname)(PyObject *self, Py_UCS4 code, char* buffer, int buflen); + + /* Get character code for a given name. Same error handling + as for getname. */ + int (*getcode)(PyObject *self, const char* name, int namelen, Py_UCS4* code); + +} _PyUnicode_Name_CAPI; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_UCNHASH_H */ diff --git a/python/include/unicodeobject.h b/python/include/unicodeobject.h new file mode 100644 index 000000000..9ab724aa6 --- /dev/null +++ b/python/include/unicodeobject.h @@ -0,0 +1,1413 @@ +#ifndef Py_UNICODEOBJECT_H +#define Py_UNICODEOBJECT_H + +#include + +/* + +Unicode implementation based on original code by Fredrik Lundh, +modified by Marc-Andre Lemburg (mal@lemburg.com) according to the +Unicode Integration Proposal (see file Misc/unicode.txt). + +Copyright (c) Corporation for National Research Initiatives. + + + Original header: + -------------------------------------------------------------------- + + * Yet another Unicode string type for Python. This type supports the + * 16-bit Basic Multilingual Plane (BMP) only. + * + * Written by Fredrik Lundh, January 1999. + * + * Copyright (c) 1999 by Secret Labs AB. + * Copyright (c) 1999 by Fredrik Lundh. + * + * fredrik@pythonware.com + * http://www.pythonware.com + * + * -------------------------------------------------------------------- + * This Unicode String Type is + * + * Copyright (c) 1999 by Secret Labs AB + * Copyright (c) 1999 by Fredrik Lundh + * + * By obtaining, using, and/or copying this software and/or its + * associated documentation, you agree that you have read, understood, + * and will comply with the following terms and conditions: + * + * Permission to use, copy, modify, and distribute this software and its + * associated documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appears in all + * copies, and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of Secret Labs + * AB or the author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. + * + * SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * -------------------------------------------------------------------- */ + +#include + +/* === Internal API ======================================================= */ + +/* --- Internal Unicode Format -------------------------------------------- */ + +#ifndef Py_USING_UNICODE + +#define PyUnicode_Check(op) 0 +#define PyUnicode_CheckExact(op) 0 + +#else + +/* FIXME: MvL's new implementation assumes that Py_UNICODE_SIZE is + properly set, but the default rules below doesn't set it. I'll + sort this out some other day -- fredrik@pythonware.com */ + +#ifndef Py_UNICODE_SIZE +#error Must define Py_UNICODE_SIZE +#endif + +/* Setting Py_UNICODE_WIDE enables UCS-4 storage. Otherwise, Unicode + strings are stored as UCS-2 (with limited support for UTF-16) */ + +#if Py_UNICODE_SIZE >= 4 +#define Py_UNICODE_WIDE +#endif + +/* Set these flags if the platform has "wchar.h", "wctype.h" and the + wchar_t type is a 16-bit unsigned type */ +/* #define HAVE_WCHAR_H */ +/* #define HAVE_USABLE_WCHAR_T */ + +/* Defaults for various platforms */ +#ifndef PY_UNICODE_TYPE + +/* Windows has a usable wchar_t type (unless we're using UCS-4) */ +# if defined(MS_WIN32) && Py_UNICODE_SIZE == 2 +# define HAVE_USABLE_WCHAR_T +# define PY_UNICODE_TYPE wchar_t +# endif + +# if defined(Py_UNICODE_WIDE) +# define PY_UNICODE_TYPE Py_UCS4 +# endif + +#endif + +/* If the compiler provides a wchar_t type we try to support it + through the interface functions PyUnicode_FromWideChar() and + PyUnicode_AsWideChar(). */ + +#ifdef HAVE_USABLE_WCHAR_T +# ifndef HAVE_WCHAR_H +# define HAVE_WCHAR_H +# endif +#endif + +#ifdef HAVE_WCHAR_H +/* Work around a cosmetic bug in BSDI 4.x wchar.h; thanks to Thomas Wouters */ +# ifdef _HAVE_BSDI +# include +# endif +# include +#endif + +/* + * Use this typedef when you need to represent a UTF-16 surrogate pair + * as single unsigned integer. + */ +#if SIZEOF_INT >= 4 +typedef unsigned int Py_UCS4; +#elif SIZEOF_LONG >= 4 +typedef unsigned long Py_UCS4; +#endif + +/* Py_UNICODE is the native Unicode storage format (code unit) used by + Python and represents a single Unicode element in the Unicode + type. */ + +typedef PY_UNICODE_TYPE Py_UNICODE; + +/* --- UCS-2/UCS-4 Name Mangling ------------------------------------------ */ + +/* Unicode API names are mangled to assure that UCS-2 and UCS-4 builds + produce different external names and thus cause import errors in + case Python interpreters and extensions with mixed compiled in + Unicode width assumptions are combined. */ + +#ifndef Py_UNICODE_WIDE + +# define PyUnicode_AsASCIIString PyUnicodeUCS2_AsASCIIString +# define PyUnicode_AsCharmapString PyUnicodeUCS2_AsCharmapString +# define PyUnicode_AsEncodedObject PyUnicodeUCS2_AsEncodedObject +# define PyUnicode_AsEncodedString PyUnicodeUCS2_AsEncodedString +# define PyUnicode_AsLatin1String PyUnicodeUCS2_AsLatin1String +# define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS2_AsRawUnicodeEscapeString +# define PyUnicode_AsUTF32String PyUnicodeUCS2_AsUTF32String +# define PyUnicode_AsUTF16String PyUnicodeUCS2_AsUTF16String +# define PyUnicode_AsUTF8String PyUnicodeUCS2_AsUTF8String +# define PyUnicode_AsUnicode PyUnicodeUCS2_AsUnicode +# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS2_AsUnicodeEscapeString +# define PyUnicode_AsWideChar PyUnicodeUCS2_AsWideChar +# define PyUnicode_ClearFreeList PyUnicodeUCS2_ClearFreelist +# define PyUnicode_Compare PyUnicodeUCS2_Compare +# define PyUnicode_Concat PyUnicodeUCS2_Concat +# define PyUnicode_Contains PyUnicodeUCS2_Contains +# define PyUnicode_Count PyUnicodeUCS2_Count +# define PyUnicode_Decode PyUnicodeUCS2_Decode +# define PyUnicode_DecodeASCII PyUnicodeUCS2_DecodeASCII +# define PyUnicode_DecodeCharmap PyUnicodeUCS2_DecodeCharmap +# define PyUnicode_DecodeLatin1 PyUnicodeUCS2_DecodeLatin1 +# define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS2_DecodeRawUnicodeEscape +# define PyUnicode_DecodeUTF32 PyUnicodeUCS2_DecodeUTF32 +# define PyUnicode_DecodeUTF32Stateful PyUnicodeUCS2_DecodeUTF32Stateful +# define PyUnicode_DecodeUTF16 PyUnicodeUCS2_DecodeUTF16 +# define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS2_DecodeUTF16Stateful +# define PyUnicode_DecodeUTF8 PyUnicodeUCS2_DecodeUTF8 +# define PyUnicode_DecodeUTF8Stateful PyUnicodeUCS2_DecodeUTF8Stateful +# define PyUnicode_DecodeUnicodeEscape PyUnicodeUCS2_DecodeUnicodeEscape +# define PyUnicode_Encode PyUnicodeUCS2_Encode +# define PyUnicode_EncodeASCII PyUnicodeUCS2_EncodeASCII +# define PyUnicode_EncodeCharmap PyUnicodeUCS2_EncodeCharmap +# define PyUnicode_EncodeDecimal PyUnicodeUCS2_EncodeDecimal +# define PyUnicode_EncodeLatin1 PyUnicodeUCS2_EncodeLatin1 +# define PyUnicode_EncodeRawUnicodeEscape PyUnicodeUCS2_EncodeRawUnicodeEscape +# define PyUnicode_EncodeUTF32 PyUnicodeUCS2_EncodeUTF32 +# define PyUnicode_EncodeUTF16 PyUnicodeUCS2_EncodeUTF16 +# define PyUnicode_EncodeUTF8 PyUnicodeUCS2_EncodeUTF8 +# define PyUnicode_EncodeUnicodeEscape PyUnicodeUCS2_EncodeUnicodeEscape +# define PyUnicode_Find PyUnicodeUCS2_Find +# define PyUnicode_Format PyUnicodeUCS2_Format +# define PyUnicode_FromEncodedObject PyUnicodeUCS2_FromEncodedObject +# define PyUnicode_FromFormat PyUnicodeUCS2_FromFormat +# define PyUnicode_FromFormatV PyUnicodeUCS2_FromFormatV +# define PyUnicode_FromObject PyUnicodeUCS2_FromObject +# define PyUnicode_FromOrdinal PyUnicodeUCS2_FromOrdinal +# define PyUnicode_FromString PyUnicodeUCS2_FromString +# define PyUnicode_FromStringAndSize PyUnicodeUCS2_FromStringAndSize +# define PyUnicode_FromUnicode PyUnicodeUCS2_FromUnicode +# define PyUnicode_FromWideChar PyUnicodeUCS2_FromWideChar +# define PyUnicode_GetDefaultEncoding PyUnicodeUCS2_GetDefaultEncoding +# define PyUnicode_GetMax PyUnicodeUCS2_GetMax +# define PyUnicode_GetSize PyUnicodeUCS2_GetSize +# define PyUnicode_Join PyUnicodeUCS2_Join +# define PyUnicode_Partition PyUnicodeUCS2_Partition +# define PyUnicode_RPartition PyUnicodeUCS2_RPartition +# define PyUnicode_RSplit PyUnicodeUCS2_RSplit +# define PyUnicode_Replace PyUnicodeUCS2_Replace +# define PyUnicode_Resize PyUnicodeUCS2_Resize +# define PyUnicode_RichCompare PyUnicodeUCS2_RichCompare +# define PyUnicode_SetDefaultEncoding PyUnicodeUCS2_SetDefaultEncoding +# define PyUnicode_Split PyUnicodeUCS2_Split +# define PyUnicode_Splitlines PyUnicodeUCS2_Splitlines +# define PyUnicode_Tailmatch PyUnicodeUCS2_Tailmatch +# define PyUnicode_Translate PyUnicodeUCS2_Translate +# define PyUnicode_TranslateCharmap PyUnicodeUCS2_TranslateCharmap +# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS2_AsDefaultEncodedString +# define _PyUnicode_Fini _PyUnicodeUCS2_Fini +# define _PyUnicode_Init _PyUnicodeUCS2_Init +# define _PyUnicode_IsAlpha _PyUnicodeUCS2_IsAlpha +# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS2_IsDecimalDigit +# define _PyUnicode_IsDigit _PyUnicodeUCS2_IsDigit +# define _PyUnicode_IsLinebreak _PyUnicodeUCS2_IsLinebreak +# define _PyUnicode_IsLowercase _PyUnicodeUCS2_IsLowercase +# define _PyUnicode_IsNumeric _PyUnicodeUCS2_IsNumeric +# define _PyUnicode_IsTitlecase _PyUnicodeUCS2_IsTitlecase +# define _PyUnicode_IsUppercase _PyUnicodeUCS2_IsUppercase +# define _PyUnicode_IsWhitespace _PyUnicodeUCS2_IsWhitespace +# define _PyUnicode_ToDecimalDigit _PyUnicodeUCS2_ToDecimalDigit +# define _PyUnicode_ToDigit _PyUnicodeUCS2_ToDigit +# define _PyUnicode_ToLowercase _PyUnicodeUCS2_ToLowercase +# define _PyUnicode_ToNumeric _PyUnicodeUCS2_ToNumeric +# define _PyUnicode_ToTitlecase _PyUnicodeUCS2_ToTitlecase +# define _PyUnicode_ToUppercase _PyUnicodeUCS2_ToUppercase + +#else + +# define PyUnicode_AsASCIIString PyUnicodeUCS4_AsASCIIString +# define PyUnicode_AsCharmapString PyUnicodeUCS4_AsCharmapString +# define PyUnicode_AsEncodedObject PyUnicodeUCS4_AsEncodedObject +# define PyUnicode_AsEncodedString PyUnicodeUCS4_AsEncodedString +# define PyUnicode_AsLatin1String PyUnicodeUCS4_AsLatin1String +# define PyUnicode_AsRawUnicodeEscapeString PyUnicodeUCS4_AsRawUnicodeEscapeString +# define PyUnicode_AsUTF32String PyUnicodeUCS4_AsUTF32String +# define PyUnicode_AsUTF16String PyUnicodeUCS4_AsUTF16String +# define PyUnicode_AsUTF8String PyUnicodeUCS4_AsUTF8String +# define PyUnicode_AsUnicode PyUnicodeUCS4_AsUnicode +# define PyUnicode_AsUnicodeEscapeString PyUnicodeUCS4_AsUnicodeEscapeString +# define PyUnicode_AsWideChar PyUnicodeUCS4_AsWideChar +# define PyUnicode_ClearFreeList PyUnicodeUCS4_ClearFreelist +# define PyUnicode_Compare PyUnicodeUCS4_Compare +# define PyUnicode_Concat PyUnicodeUCS4_Concat +# define PyUnicode_Contains PyUnicodeUCS4_Contains +# define PyUnicode_Count PyUnicodeUCS4_Count +# define PyUnicode_Decode PyUnicodeUCS4_Decode +# define PyUnicode_DecodeASCII PyUnicodeUCS4_DecodeASCII +# define PyUnicode_DecodeCharmap PyUnicodeUCS4_DecodeCharmap +# define PyUnicode_DecodeLatin1 PyUnicodeUCS4_DecodeLatin1 +# define PyUnicode_DecodeRawUnicodeEscape PyUnicodeUCS4_DecodeRawUnicodeEscape +# define PyUnicode_DecodeUTF32 PyUnicodeUCS4_DecodeUTF32 +# define PyUnicode_DecodeUTF32Stateful PyUnicodeUCS4_DecodeUTF32Stateful +# define PyUnicode_DecodeUTF16 PyUnicodeUCS4_DecodeUTF16 +# define PyUnicode_DecodeUTF16Stateful PyUnicodeUCS4_DecodeUTF16Stateful +# define PyUnicode_DecodeUTF8 PyUnicodeUCS4_DecodeUTF8 +# define PyUnicode_DecodeUTF8Stateful PyUnicodeUCS4_DecodeUTF8Stateful +# define PyUnicode_DecodeUnicodeEscape PyUnicodeUCS4_DecodeUnicodeEscape +# define PyUnicode_Encode PyUnicodeUCS4_Encode +# define PyUnicode_EncodeASCII PyUnicodeUCS4_EncodeASCII +# define PyUnicode_EncodeCharmap PyUnicodeUCS4_EncodeCharmap +# define PyUnicode_EncodeDecimal PyUnicodeUCS4_EncodeDecimal +# define PyUnicode_EncodeLatin1 PyUnicodeUCS4_EncodeLatin1 +# define PyUnicode_EncodeRawUnicodeEscape PyUnicodeUCS4_EncodeRawUnicodeEscape +# define PyUnicode_EncodeUTF32 PyUnicodeUCS4_EncodeUTF32 +# define PyUnicode_EncodeUTF16 PyUnicodeUCS4_EncodeUTF16 +# define PyUnicode_EncodeUTF8 PyUnicodeUCS4_EncodeUTF8 +# define PyUnicode_EncodeUnicodeEscape PyUnicodeUCS4_EncodeUnicodeEscape +# define PyUnicode_Find PyUnicodeUCS4_Find +# define PyUnicode_Format PyUnicodeUCS4_Format +# define PyUnicode_FromEncodedObject PyUnicodeUCS4_FromEncodedObject +# define PyUnicode_FromFormat PyUnicodeUCS4_FromFormat +# define PyUnicode_FromFormatV PyUnicodeUCS4_FromFormatV +# define PyUnicode_FromObject PyUnicodeUCS4_FromObject +# define PyUnicode_FromOrdinal PyUnicodeUCS4_FromOrdinal +# define PyUnicode_FromString PyUnicodeUCS4_FromString +# define PyUnicode_FromStringAndSize PyUnicodeUCS4_FromStringAndSize +# define PyUnicode_FromUnicode PyUnicodeUCS4_FromUnicode +# define PyUnicode_FromWideChar PyUnicodeUCS4_FromWideChar +# define PyUnicode_GetDefaultEncoding PyUnicodeUCS4_GetDefaultEncoding +# define PyUnicode_GetMax PyUnicodeUCS4_GetMax +# define PyUnicode_GetSize PyUnicodeUCS4_GetSize +# define PyUnicode_Join PyUnicodeUCS4_Join +# define PyUnicode_Partition PyUnicodeUCS4_Partition +# define PyUnicode_RPartition PyUnicodeUCS4_RPartition +# define PyUnicode_RSplit PyUnicodeUCS4_RSplit +# define PyUnicode_Replace PyUnicodeUCS4_Replace +# define PyUnicode_Resize PyUnicodeUCS4_Resize +# define PyUnicode_RichCompare PyUnicodeUCS4_RichCompare +# define PyUnicode_SetDefaultEncoding PyUnicodeUCS4_SetDefaultEncoding +# define PyUnicode_Split PyUnicodeUCS4_Split +# define PyUnicode_Splitlines PyUnicodeUCS4_Splitlines +# define PyUnicode_Tailmatch PyUnicodeUCS4_Tailmatch +# define PyUnicode_Translate PyUnicodeUCS4_Translate +# define PyUnicode_TranslateCharmap PyUnicodeUCS4_TranslateCharmap +# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS4_AsDefaultEncodedString +# define _PyUnicode_Fini _PyUnicodeUCS4_Fini +# define _PyUnicode_Init _PyUnicodeUCS4_Init +# define _PyUnicode_IsAlpha _PyUnicodeUCS4_IsAlpha +# define _PyUnicode_IsDecimalDigit _PyUnicodeUCS4_IsDecimalDigit +# define _PyUnicode_IsDigit _PyUnicodeUCS4_IsDigit +# define _PyUnicode_IsLinebreak _PyUnicodeUCS4_IsLinebreak +# define _PyUnicode_IsLowercase _PyUnicodeUCS4_IsLowercase +# define _PyUnicode_IsNumeric _PyUnicodeUCS4_IsNumeric +# define _PyUnicode_IsTitlecase _PyUnicodeUCS4_IsTitlecase +# define _PyUnicode_IsUppercase _PyUnicodeUCS4_IsUppercase +# define _PyUnicode_IsWhitespace _PyUnicodeUCS4_IsWhitespace +# define _PyUnicode_ToDecimalDigit _PyUnicodeUCS4_ToDecimalDigit +# define _PyUnicode_ToDigit _PyUnicodeUCS4_ToDigit +# define _PyUnicode_ToLowercase _PyUnicodeUCS4_ToLowercase +# define _PyUnicode_ToNumeric _PyUnicodeUCS4_ToNumeric +# define _PyUnicode_ToTitlecase _PyUnicodeUCS4_ToTitlecase +# define _PyUnicode_ToUppercase _PyUnicodeUCS4_ToUppercase + + +#endif + +/* --- Internal Unicode Operations ---------------------------------------- */ + +/* If you want Python to use the compiler's wctype.h functions instead + of the ones supplied with Python, define WANT_WCTYPE_FUNCTIONS or + configure Python using --with-wctype-functions. This reduces the + interpreter's code size. */ + +#if defined(HAVE_USABLE_WCHAR_T) && defined(WANT_WCTYPE_FUNCTIONS) + +#include + +#define Py_UNICODE_ISSPACE(ch) iswspace(ch) + +#define Py_UNICODE_ISLOWER(ch) iswlower(ch) +#define Py_UNICODE_ISUPPER(ch) iswupper(ch) +#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) + +#define Py_UNICODE_TOLOWER(ch) towlower(ch) +#define Py_UNICODE_TOUPPER(ch) towupper(ch) +#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) + +#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) +#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) +#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) + +#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) +#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) +#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) + +#define Py_UNICODE_ISALPHA(ch) iswalpha(ch) + +#else + +/* Since splitting on whitespace is an important use case, and + whitespace in most situations is solely ASCII whitespace, we + optimize for the common case by using a quick look-up table + _Py_ascii_whitespace (see below) with an inlined check. + + */ +#define Py_UNICODE_ISSPACE(ch) \ + ((ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch)) + +#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) +#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) +#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) + +#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) +#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) +#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) + +#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) +#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) +#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) + +#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) +#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) +#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) + +#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) + +#endif + +#define Py_UNICODE_ISALNUM(ch) \ + (Py_UNICODE_ISALPHA(ch) || \ + Py_UNICODE_ISDECIMAL(ch) || \ + Py_UNICODE_ISDIGIT(ch) || \ + Py_UNICODE_ISNUMERIC(ch)) + +#define Py_UNICODE_COPY(target, source, length) \ + Py_MEMCPY((target), (source), (length)*sizeof(Py_UNICODE)) + +#define Py_UNICODE_FILL(target, value, length) \ + do {Py_ssize_t i_; Py_UNICODE *t_ = (target); Py_UNICODE v_ = (value);\ + for (i_ = 0; i_ < (length); i_++) t_[i_] = v_;\ + } while (0) + +/* Check if substring matches at given offset. the offset must be + valid, and the substring must not be empty */ + +#define Py_UNICODE_MATCH(string, offset, substring) \ + ((*((string)->str + (offset)) == *((substring)->str)) && \ + ((*((string)->str + (offset) + (substring)->length-1) == *((substring)->str + (substring)->length-1))) && \ + !memcmp((string)->str + (offset), (substring)->str, (substring)->length*sizeof(Py_UNICODE))) + +#ifdef __cplusplus +extern "C" { +#endif + +/* --- Unicode Type ------------------------------------------------------- */ + +typedef struct { + PyObject_HEAD + Py_ssize_t length; /* Length of raw Unicode data in buffer */ + Py_UNICODE *str; /* Raw Unicode buffer */ + long hash; /* Hash value; -1 if not set */ + PyObject *defenc; /* (Default) Encoded version as Python + string, or NULL; this is used for + implementing the buffer protocol */ +} PyUnicodeObject; + +PyAPI_DATA(PyTypeObject) PyUnicode_Type; + +#define PyUnicode_Check(op) \ + PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) +#define PyUnicode_CheckExact(op) (Py_TYPE(op) == &PyUnicode_Type) + +/* Fast access macros */ +#define PyUnicode_GET_SIZE(op) \ + (((PyUnicodeObject *)(op))->length) +#define PyUnicode_GET_DATA_SIZE(op) \ + (((PyUnicodeObject *)(op))->length * sizeof(Py_UNICODE)) +#define PyUnicode_AS_UNICODE(op) \ + (((PyUnicodeObject *)(op))->str) +#define PyUnicode_AS_DATA(op) \ + ((const char *)((PyUnicodeObject *)(op))->str) + +/* --- Constants ---------------------------------------------------------- */ + +/* This Unicode character will be used as replacement character during + decoding if the errors argument is set to "replace". Note: the + Unicode character U+FFFD is the official REPLACEMENT CHARACTER in + Unicode 3.0. */ + +#define Py_UNICODE_REPLACEMENT_CHARACTER ((Py_UNICODE) 0xFFFD) + +/* === Public API ========================================================= */ + +/* --- Plain Py_UNICODE --------------------------------------------------- */ + +/* Create a Unicode Object from the Py_UNICODE buffer u of the given + size. + + u may be NULL which causes the contents to be undefined. It is the + user's responsibility to fill in the needed data afterwards. Note + that modifying the Unicode object contents after construction is + only allowed if u was set to NULL. + + The buffer is copied into the new object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode( + const Py_UNICODE *u, /* Unicode buffer */ + Py_ssize_t size /* size of buffer */ + ); + +/* Similar to PyUnicode_FromUnicode(), but u points to Latin-1 encoded bytes */ +PyAPI_FUNC(PyObject*) PyUnicode_FromStringAndSize( + const char *u, /* char buffer */ + Py_ssize_t size /* size of buffer */ + ); + +/* Similar to PyUnicode_FromUnicode(), but u points to null-terminated + Latin-1 encoded bytes */ +PyAPI_FUNC(PyObject*) PyUnicode_FromString( + const char *u /* string */ + ); + +/* Return a read-only pointer to the Unicode object's internal + Py_UNICODE buffer. */ + +PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( + PyObject *unicode /* Unicode object */ + ); + +/* Get the length of the Unicode object. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize( + PyObject *unicode /* Unicode object */ + ); + +/* Get the maximum ordinal for a Unicode character. */ +PyAPI_FUNC(Py_UNICODE) PyUnicode_GetMax(void); + +/* Resize an already allocated Unicode object to the new size length. + + *unicode is modified to point to the new (resized) object and 0 + returned on success. + + This API may only be called by the function which also called the + Unicode constructor. The refcount on the object must be 1. Otherwise, + an error is returned. + + Error handling is implemented as follows: an exception is set, -1 + is returned and *unicode left untouched. + +*/ + +PyAPI_FUNC(int) PyUnicode_Resize( + PyObject **unicode, /* Pointer to the Unicode object */ + Py_ssize_t length /* New length */ + ); + +/* Coerce obj to an Unicode object and return a reference with + *incremented* refcount. + + Coercion is done in the following way: + + 1. String and other char buffer compatible objects are decoded + under the assumptions that they contain data using the current + default encoding. Decoding is done in "strict" mode. + + 2. All other objects (including Unicode objects) raise an + exception. + + The API returns NULL in case of an error. The caller is responsible + for decref'ing the returned objects. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromEncodedObject( + register PyObject *obj, /* Object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Coerce obj to an Unicode object and return a reference with + *incremented* refcount. + + Unicode objects are passed back as-is (subclasses are converted to + true Unicode objects), all other objects are delegated to + PyUnicode_FromEncodedObject(obj, NULL, "strict") which results in + using the default encoding as basis for decoding the object. + + The API returns NULL in case of an error. The caller is responsible + for decref'ing the returned objects. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromObject( + register PyObject *obj /* Object */ + ); + +PyAPI_FUNC(PyObject *) PyUnicode_FromFormatV(const char*, va_list); +PyAPI_FUNC(PyObject *) PyUnicode_FromFormat(const char*, ...); + +/* Format the object based on the format_spec, as defined in PEP 3101 + (Advanced String Formatting). */ +PyAPI_FUNC(PyObject *) _PyUnicode_FormatAdvanced(PyObject *obj, + Py_UNICODE *format_spec, + Py_ssize_t format_spec_len); + +/* --- wchar_t support for platforms which support it --------------------- */ + +#ifdef HAVE_WCHAR_H + +/* Create a Unicode Object from the whcar_t buffer w of the given + size. + + The buffer is copied into the new object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_FromWideChar( + register const wchar_t *w, /* wchar_t buffer */ + Py_ssize_t size /* size of buffer */ + ); + +/* Copies the Unicode Object contents into the wchar_t buffer w. At + most size wchar_t characters are copied. + + Note that the resulting wchar_t string may or may not be + 0-terminated. It is the responsibility of the caller to make sure + that the wchar_t string is 0-terminated in case this is required by + the application. + + Returns the number of wchar_t characters copied (excluding a + possibly trailing 0-termination character) or -1 in case of an + error. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_AsWideChar( + PyUnicodeObject *unicode, /* Unicode object */ + register wchar_t *w, /* wchar_t buffer */ + Py_ssize_t size /* size of buffer */ + ); + +#endif + +/* --- Unicode ordinals --------------------------------------------------- */ + +/* Create a Unicode Object from the given Unicode code point ordinal. + + The ordinal must be in range(0x10000) on narrow Python builds + (UCS2), and range(0x110000) on wide builds (UCS4). A ValueError is + raised in case it is not. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_FromOrdinal(int ordinal); + +/* --- Free-list management ----------------------------------------------- */ + +/* Clear the free list used by the Unicode implementation. + + This can be used to release memory used for objects on the free + list back to the Python memory allocator. + +*/ + +PyAPI_FUNC(int) PyUnicode_ClearFreeList(void); + +/* === Builtin Codecs ===================================================== + + Many of these APIs take two arguments encoding and errors. These + parameters encoding and errors have the same semantics as the ones + of the builtin unicode() API. + + Setting encoding to NULL causes the default encoding to be used. + + Error handling is set by errors which may also be set to NULL + meaning to use the default handling defined for the codec. Default + error handling for all builtin codecs is "strict" (ValueErrors are + raised). + + The codecs all use a similar interface. Only deviation from the + generic ones are documented. + +*/ + +/* --- Manage the default encoding ---------------------------------------- */ + +/* Return a Python string holding the default encoded value of the + Unicode object. + + The resulting string is cached in the Unicode object for subsequent + usage by this function. The cached version is needed to implement + the character buffer interface and will live (at least) as long as + the Unicode object itself. + + The refcount of the string is *not* incremented. + + *** Exported for internal use by the interpreter only !!! *** + +*/ + +PyAPI_FUNC(PyObject *) _PyUnicode_AsDefaultEncodedString( + PyObject *, const char *); + +/* Returns the currently active default encoding. + + The default encoding is currently implemented as run-time settable + process global. This may change in future versions of the + interpreter to become a parameter which is managed on a per-thread + basis. + + */ + +PyAPI_FUNC(const char*) PyUnicode_GetDefaultEncoding(void); + +/* Sets the currently active default encoding. + + Returns 0 on success, -1 in case of an error. + + */ + +PyAPI_FUNC(int) PyUnicode_SetDefaultEncoding( + const char *encoding /* Encoding name in standard form */ + ); + +/* --- Generic Codecs ----------------------------------------------------- */ + +/* Create a Unicode object by decoding the encoded string s of the + given size. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Decode( + const char *s, /* encoded string */ + Py_ssize_t size, /* size of buffer */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a Py_UNICODE buffer of the given size and returns a + Python string object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Encode( + const Py_UNICODE *s, /* Unicode char buffer */ + Py_ssize_t size, /* number of Py_UNICODE chars to encode */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a Unicode object and returns the result as Python + object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedObject( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +/* Encodes a Unicode object and returns the result as Python string + object. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsEncodedString( + PyObject *unicode, /* Unicode object */ + const char *encoding, /* encoding */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_BuildEncodingMap( + PyObject* string /* 256 character map */ + ); + + +/* --- UTF-7 Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF7( + const char *string, /* UTF-7 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF7Stateful( + const char *string, /* UTF-7 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF7( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + int base64SetO, /* Encode RFC2152 Set O characters in base64 */ + int base64WhiteSpace, /* Encode whitespace (sp, ht, nl, cr) in base64 */ + const char *errors /* error handling */ + ); + +/* --- UTF-8 Codecs ------------------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8( + const char *string, /* UTF-8 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF8Stateful( + const char *string, /* UTF-8 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsUTF8String( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF8( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); + +/* --- UTF-32 Codecs ------------------------------------------------------ */ + +/* Decodes length bytes from a UTF-32 encoded buffer string and returns + the corresponding Unicode object. + + errors (if non-NULL) defines the error handling. It defaults + to "strict". + + If byteorder is non-NULL, the decoder starts decoding using the + given byte order: + + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian + + In native mode, the first four bytes of the stream are checked for a + BOM mark. If found, the BOM mark is analysed, the byte order + adjusted and the BOM skipped. In the other modes, no BOM mark + interpretation is done. After completion, *byteorder is set to the + current byte order at the end of input data. + + If byteorder is NULL, the codec starts in native order mode. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF32( + const char *string, /* UTF-32 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF32Stateful( + const char *string, /* UTF-32 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder, /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +/* Returns a Python string using the UTF-32 encoding in native byte + order. The string always starts with a BOM mark. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsUTF32String( + PyObject *unicode /* Unicode object */ + ); + +/* Returns a Python string object holding the UTF-32 encoded value of + the Unicode data. + + If byteorder is not 0, output is written according to the following + byte order: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is 0, the output string will always start with the + Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is + prepended. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF32( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ); + +/* --- UTF-16 Codecs ------------------------------------------------------ */ + +/* Decodes length bytes from a UTF-16 encoded buffer string and returns + the corresponding Unicode object. + + errors (if non-NULL) defines the error handling. It defaults + to "strict". + + If byteorder is non-NULL, the decoder starts decoding using the + given byte order: + + *byteorder == -1: little endian + *byteorder == 0: native order + *byteorder == 1: big endian + + In native mode, the first two bytes of the stream are checked for a + BOM mark. If found, the BOM mark is analysed, the byte order + adjusted and the BOM skipped. In the other modes, no BOM mark + interpretation is done. After completion, *byteorder is set to the + current byte order at the end of input data. + + If byteorder is NULL, the codec starts in native order mode. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16( + const char *string, /* UTF-16 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUTF16Stateful( + const char *string, /* UTF-16 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + int *byteorder, /* pointer to byteorder to use + 0=native;-1=LE,1=BE; updated on + exit */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +/* Returns a Python string using the UTF-16 encoding in native byte + order. The string always starts with a BOM mark. */ + +PyAPI_FUNC(PyObject*) PyUnicode_AsUTF16String( + PyObject *unicode /* Unicode object */ + ); + +/* Returns a Python string object holding the UTF-16 encoded value of + the Unicode data. + + If byteorder is not 0, output is written according to the following + byte order: + + byteorder == -1: little endian + byteorder == 0: native byte order (writes a BOM mark) + byteorder == 1: big endian + + If byteorder is 0, the output string will always start with the + Unicode BOM mark (U+FEFF). In the other two modes, no BOM mark is + prepended. + + Note that Py_UNICODE data is being interpreted as UTF-16 reduced to + UCS-2. This trick makes it possible to add full UTF-16 capabilities + at a later point without compromising the APIs. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUTF16( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* number of Py_UNICODE chars to encode */ + const char *errors, /* error handling */ + int byteorder /* byteorder to use 0=BOM+native;-1=LE,1=BE */ + ); + +/* --- Unicode-Escape Codecs ---------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeUnicodeEscape( + const char *string, /* Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsUnicodeEscapeString( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeUnicodeEscape( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length /* Number of Py_UNICODE chars to encode */ + ); + +/* --- Raw-Unicode-Escape Codecs ------------------------------------------ */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeRawUnicodeEscape( + const char *string, /* Raw-Unicode-Escape encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsRawUnicodeEscapeString( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeRawUnicodeEscape( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length /* Number of Py_UNICODE chars to encode */ + ); + +/* --- Unicode Internal Codec --------------------------------------------- + + Only for internal use in _codecsmodule.c */ + +PyObject *_PyUnicode_DecodeUnicodeInternal( + const char *string, + Py_ssize_t length, + const char *errors + ); + +/* --- Latin-1 Codecs ----------------------------------------------------- + + Note: Latin-1 corresponds to the first 256 Unicode ordinals. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeLatin1( + const char *string, /* Latin-1 encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsLatin1String( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeLatin1( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); + +/* --- ASCII Codecs ------------------------------------------------------- + + Only 7-bit ASCII data is excepted. All other codes generate errors. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeASCII( + const char *string, /* ASCII encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsASCIIString( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeASCII( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); + +/* --- Character Map Codecs ----------------------------------------------- + + This codec uses mappings to encode and decode characters. + + Decoding mappings must map single string characters to single + Unicode characters, integers (which are then interpreted as Unicode + ordinals) or None (meaning "undefined mapping" and causing an + error). + + Encoding mappings must map single Unicode characters to single + string characters, integers (which are then interpreted as Latin-1 + ordinals) or None (meaning "undefined mapping" and causing an + error). + + If a character lookup fails with a LookupError, the character is + copied as-is meaning that its ordinal value will be interpreted as + Unicode or Latin-1 ordinal resp. Because of this mappings only need + to contain those mappings which map characters to different code + points. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeCharmap( + const char *string, /* Encoded string */ + Py_ssize_t length, /* size of string */ + PyObject *mapping, /* character mapping + (char ordinal -> unicode ordinal) */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsCharmapString( + PyObject *unicode, /* Unicode object */ + PyObject *mapping /* character mapping + (unicode ordinal -> char ordinal) */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeCharmap( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + PyObject *mapping, /* character mapping + (unicode ordinal -> char ordinal) */ + const char *errors /* error handling */ + ); + +/* Translate a Py_UNICODE buffer of the given length by applying a + character mapping table to it and return the resulting Unicode + object. + + The mapping table must map Unicode ordinal integers to Unicode + ordinal integers or None (causing deletion of the character). + + Mapping tables may be dictionaries or sequences. Unmapped character + ordinals (ones which cause a LookupError) are left untouched and + are copied as-is. + +*/ + +PyAPI_FUNC(PyObject *) PyUnicode_TranslateCharmap( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + PyObject *table, /* Translate table */ + const char *errors /* error handling */ + ); + +#ifdef MS_WIN32 + +/* --- MBCS codecs for Windows -------------------------------------------- */ + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCS( + const char *string, /* MBCS encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors /* error handling */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_DecodeMBCSStateful( + const char *string, /* MBCS encoded string */ + Py_ssize_t length, /* size of string */ + const char *errors, /* error handling */ + Py_ssize_t *consumed /* bytes consumed */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_AsMBCSString( + PyObject *unicode /* Unicode object */ + ); + +PyAPI_FUNC(PyObject*) PyUnicode_EncodeMBCS( + const Py_UNICODE *data, /* Unicode char buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + const char *errors /* error handling */ + ); + +#endif /* MS_WIN32 */ + +/* --- Decimal Encoder ---------------------------------------------------- */ + +/* Takes a Unicode string holding a decimal value and writes it into + an output buffer using standard ASCII digit codes. + + The output buffer has to provide at least length+1 bytes of storage + area. The output string is 0-terminated. + + The encoder converts whitespace to ' ', decimal characters to their + corresponding ASCII digit and all other Latin-1 characters except + \0 as-is. Characters outside this range (Unicode ordinals 1-256) + are treated as errors. This includes embedded NULL bytes. + + Error handling is defined by the errors argument: + + NULL or "strict": raise a ValueError + "ignore": ignore the wrong characters (these are not copied to the + output buffer) + "replace": replaces illegal characters with '?' + + Returns 0 on success, -1 on failure. + +*/ + +PyAPI_FUNC(int) PyUnicode_EncodeDecimal( + Py_UNICODE *s, /* Unicode buffer */ + Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ + char *output, /* Output buffer; must have size >= length */ + const char *errors /* error handling */ + ); + +/* --- Methods & Slots ---------------------------------------------------- + + These are capable of handling Unicode objects and strings on input + (we refer to them as strings in the descriptions) and return + Unicode objects or integers as apporpriate. */ + +/* Concat two strings giving a new Unicode string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Concat( + PyObject *left, /* Left string */ + PyObject *right /* Right string */ + ); + +/* Split a string giving a list of Unicode strings. + + If sep is NULL, splitting will be done at all whitespace + substrings. Otherwise, splits occur at the given separator. + + At most maxsplit splits will be done. If negative, no limit is set. + + Separators are not included in the resulting list. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_Split( + PyObject *s, /* String to split */ + PyObject *sep, /* String separator */ + Py_ssize_t maxsplit /* Maxsplit count */ + ); + +/* Dito, but split at line breaks. + + CRLF is considered to be one line break. Line breaks are not + included in the resulting list. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Splitlines( + PyObject *s, /* String to split */ + int keepends /* If true, line end markers are included */ + ); + +/* Partition a string using a given separator. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Partition( + PyObject *s, /* String to partition */ + PyObject *sep /* String separator */ + ); + +/* Partition a string using a given separator, searching from the end of the + string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_RPartition( + PyObject *s, /* String to partition */ + PyObject *sep /* String separator */ + ); + +/* Split a string giving a list of Unicode strings. + + If sep is NULL, splitting will be done at all whitespace + substrings. Otherwise, splits occur at the given separator. + + At most maxsplit splits will be done. But unlike PyUnicode_Split + PyUnicode_RSplit splits from the end of the string. If negative, + no limit is set. + + Separators are not included in the resulting list. + +*/ + +PyAPI_FUNC(PyObject*) PyUnicode_RSplit( + PyObject *s, /* String to split */ + PyObject *sep, /* String separator */ + Py_ssize_t maxsplit /* Maxsplit count */ + ); + +/* Translate a string by applying a character mapping table to it and + return the resulting Unicode object. + + The mapping table must map Unicode ordinal integers to Unicode + ordinal integers or None (causing deletion of the character). + + Mapping tables may be dictionaries or sequences. Unmapped character + ordinals (ones which cause a LookupError) are left untouched and + are copied as-is. + +*/ + +PyAPI_FUNC(PyObject *) PyUnicode_Translate( + PyObject *str, /* String */ + PyObject *table, /* Translate table */ + const char *errors /* error handling */ + ); + +/* Join a sequence of strings using the given separator and return + the resulting Unicode string. */ + +PyAPI_FUNC(PyObject*) PyUnicode_Join( + PyObject *separator, /* Separator string */ + PyObject *seq /* Sequence object */ + ); + +/* Return 1 if substr matches str[start:end] at the given tail end, 0 + otherwise. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Tailmatch( + PyObject *str, /* String */ + PyObject *substr, /* Prefix or Suffix string */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end, /* Stop index */ + int direction /* Tail end: -1 prefix, +1 suffix */ + ); + +/* Return the first position of substr in str[start:end] using the + given search direction or -1 if not found. -2 is returned in case + an error occurred and an exception is set. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Find( + PyObject *str, /* String */ + PyObject *substr, /* Substring to find */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end, /* Stop index */ + int direction /* Find direction: +1 forward, -1 backward */ + ); + +/* Count the number of occurrences of substr in str[start:end]. */ + +PyAPI_FUNC(Py_ssize_t) PyUnicode_Count( + PyObject *str, /* String */ + PyObject *substr, /* Substring to count */ + Py_ssize_t start, /* Start index */ + Py_ssize_t end /* Stop index */ + ); + +/* Replace at most maxcount occurrences of substr in str with replstr + and return the resulting Unicode object. */ + +PyAPI_FUNC(PyObject *) PyUnicode_Replace( + PyObject *str, /* String */ + PyObject *substr, /* Substring to find */ + PyObject *replstr, /* Substring to replace */ + Py_ssize_t maxcount /* Max. number of replacements to apply; + -1 = all */ + ); + +/* Compare two strings and return -1, 0, 1 for less than, equal, + greater than resp. */ + +PyAPI_FUNC(int) PyUnicode_Compare( + PyObject *left, /* Left string */ + PyObject *right /* Right string */ + ); + +/* Rich compare two strings and return one of the following: + + - NULL in case an exception was raised + - Py_True or Py_False for successfuly comparisons + - Py_NotImplemented in case the type combination is unknown + + Note that Py_EQ and Py_NE comparisons can cause a UnicodeWarning in + case the conversion of the arguments to Unicode fails with a + UnicodeDecodeError. + + Possible values for op: + + Py_GT, Py_GE, Py_EQ, Py_NE, Py_LT, Py_LE + +*/ + +PyAPI_FUNC(PyObject *) PyUnicode_RichCompare( + PyObject *left, /* Left string */ + PyObject *right, /* Right string */ + int op /* Operation: Py_EQ, Py_NE, Py_GT, etc. */ + ); + +/* Apply a argument tuple or dictionary to a format string and return + the resulting Unicode string. */ + +PyAPI_FUNC(PyObject *) PyUnicode_Format( + PyObject *format, /* Format string */ + PyObject *args /* Argument tuple or dictionary */ + ); + +/* Checks whether element is contained in container and return 1/0 + accordingly. + + element has to coerce to an one element Unicode string. -1 is + returned in case of an error. */ + +PyAPI_FUNC(int) PyUnicode_Contains( + PyObject *container, /* Container string */ + PyObject *element /* Element string */ + ); + +/* Externally visible for str.strip(unicode) */ +PyAPI_FUNC(PyObject *) _PyUnicode_XStrip( + PyUnicodeObject *self, + int striptype, + PyObject *sepobj + ); + +/* === Characters Type APIs =============================================== */ + +/* Helper array used by Py_UNICODE_ISSPACE(). */ + +PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[]; + +/* These should not be used directly. Use the Py_UNICODE_IS* and + Py_UNICODE_TO* macros instead. + + These APIs are implemented in Objects/unicodectype.c. + +*/ + +PyAPI_FUNC(int) _PyUnicode_IsLowercase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsUppercase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsTitlecase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsWhitespace( + const Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsLinebreak( + const Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(Py_UNICODE) _PyUnicode_ToLowercase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(Py_UNICODE) _PyUnicode_ToUppercase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(Py_UNICODE) _PyUnicode_ToTitlecase( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToDecimalDigit( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_ToDigit( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(double) _PyUnicode_ToNumeric( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsDecimalDigit( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsDigit( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsNumeric( + Py_UNICODE ch /* Unicode character */ + ); + +PyAPI_FUNC(int) _PyUnicode_IsAlpha( + Py_UNICODE ch /* Unicode character */ + ); + +#ifdef __cplusplus +} +#endif +#endif /* Py_USING_UNICODE */ +#endif /* !Py_UNICODEOBJECT_H */ diff --git a/python/include/warnings.h b/python/include/warnings.h new file mode 100644 index 000000000..0818d7a11 --- /dev/null +++ b/python/include/warnings.h @@ -0,0 +1,23 @@ +#ifndef Py_WARNINGS_H +#define Py_WARNINGS_H +#ifdef __cplusplus +extern "C" { +#endif + +PyAPI_FUNC(void) _PyWarnings_Init(void); + +PyAPI_FUNC(int) PyErr_WarnEx(PyObject *, const char *, Py_ssize_t); +PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *, const char *, int, + const char *, PyObject *); + +#define PyErr_WarnPy3k(msg, stacklevel) \ + (Py_Py3kWarningFlag ? PyErr_WarnEx(PyExc_DeprecationWarning, msg, stacklevel) : 0) + +/* DEPRECATED: Use PyErr_WarnEx() instead. */ +#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) + +#ifdef __cplusplus +} +#endif +#endif /* !Py_WARNINGS_H */ + diff --git a/python/include/weakrefobject.h b/python/include/weakrefobject.h new file mode 100644 index 000000000..f15c9d9c1 --- /dev/null +++ b/python/include/weakrefobject.h @@ -0,0 +1,75 @@ +/* Weak references objects for Python. */ + +#ifndef Py_WEAKREFOBJECT_H +#define Py_WEAKREFOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct _PyWeakReference PyWeakReference; + +/* PyWeakReference is the base struct for the Python ReferenceType, ProxyType, + * and CallableProxyType. + */ +struct _PyWeakReference { + PyObject_HEAD + + /* The object to which this is a weak reference, or Py_None if none. + * Note that this is a stealth reference: wr_object's refcount is + * not incremented to reflect this pointer. + */ + PyObject *wr_object; + + /* A callable to invoke when wr_object dies, or NULL if none. */ + PyObject *wr_callback; + + /* A cache for wr_object's hash code. As usual for hashes, this is -1 + * if the hash code isn't known yet. + */ + long hash; + + /* If wr_object is weakly referenced, wr_object has a doubly-linked NULL- + * terminated list of weak references to it. These are the list pointers. + * If wr_object goes away, wr_object is set to Py_None, and these pointers + * have no meaning then. + */ + PyWeakReference *wr_prev; + PyWeakReference *wr_next; +}; + +PyAPI_DATA(PyTypeObject) _PyWeakref_RefType; +PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType; +PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType; + +#define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType) +#define PyWeakref_CheckRefExact(op) \ + (Py_TYPE(op) == &_PyWeakref_RefType) +#define PyWeakref_CheckProxy(op) \ + ((Py_TYPE(op) == &_PyWeakref_ProxyType) || \ + (Py_TYPE(op) == &_PyWeakref_CallableProxyType)) + +/* This macro calls PyWeakref_CheckRef() last since that can involve a + function call; this makes it more likely that the function call + will be avoided. */ +#define PyWeakref_Check(op) \ + (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op)) + + +PyAPI_FUNC(PyObject *) PyWeakref_NewRef(PyObject *ob, + PyObject *callback); +PyAPI_FUNC(PyObject *) PyWeakref_NewProxy(PyObject *ob, + PyObject *callback); +PyAPI_FUNC(PyObject *) PyWeakref_GetObject(PyObject *ref); + +PyAPI_FUNC(Py_ssize_t) _PyWeakref_GetWeakrefCount(PyWeakReference *head); + +PyAPI_FUNC(void) _PyWeakref_ClearRef(PyWeakReference *self); + +#define PyWeakref_GET_OBJECT(ref) (((PyWeakReference *)(ref))->wr_object) + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_WEAKREFOBJECT_H */ diff --git a/python/libs/_bsddb.lib b/python/libs/_bsddb.lib new file mode 100644 index 000000000..9f840ed9b Binary files /dev/null and b/python/libs/_bsddb.lib differ diff --git a/python/libs/_ctypes.lib b/python/libs/_ctypes.lib new file mode 100644 index 000000000..7cc4d0fa7 Binary files /dev/null and b/python/libs/_ctypes.lib differ diff --git a/python/libs/_ctypes_test.lib b/python/libs/_ctypes_test.lib new file mode 100644 index 000000000..2307e980d Binary files /dev/null and b/python/libs/_ctypes_test.lib differ diff --git a/python/libs/_elementtree.lib b/python/libs/_elementtree.lib new file mode 100644 index 000000000..4217b7ead Binary files /dev/null and b/python/libs/_elementtree.lib differ diff --git a/python/libs/_hashlib.lib b/python/libs/_hashlib.lib new file mode 100644 index 000000000..2fee578fe Binary files /dev/null and b/python/libs/_hashlib.lib differ diff --git a/python/libs/_msi.lib b/python/libs/_msi.lib new file mode 100644 index 000000000..ca2b30f6f Binary files /dev/null and b/python/libs/_msi.lib differ diff --git a/python/libs/_multiprocessing.lib b/python/libs/_multiprocessing.lib new file mode 100644 index 000000000..4fc782758 Binary files /dev/null and b/python/libs/_multiprocessing.lib differ diff --git a/python/libs/_socket.lib b/python/libs/_socket.lib new file mode 100644 index 000000000..f795f1470 Binary files /dev/null and b/python/libs/_socket.lib differ diff --git a/python/libs/_sqlite3.lib b/python/libs/_sqlite3.lib new file mode 100644 index 000000000..2b47f4514 Binary files /dev/null and b/python/libs/_sqlite3.lib differ diff --git a/python/libs/_ssl.lib b/python/libs/_ssl.lib new file mode 100644 index 000000000..176c166fd Binary files /dev/null and b/python/libs/_ssl.lib differ diff --git a/python/libs/_testcapi.lib b/python/libs/_testcapi.lib new file mode 100644 index 000000000..ae59b0941 Binary files /dev/null and b/python/libs/_testcapi.lib differ diff --git a/python/libs/_tkinter.lib b/python/libs/_tkinter.lib new file mode 100644 index 000000000..6d8865d5c Binary files /dev/null and b/python/libs/_tkinter.lib differ diff --git a/python/libs/bz2.lib b/python/libs/bz2.lib new file mode 100644 index 000000000..4214d1f8f Binary files /dev/null and b/python/libs/bz2.lib differ diff --git a/python/libs/omf_python27.lib b/python/libs/omf_python27.lib new file mode 100644 index 000000000..a239e707b Binary files /dev/null and b/python/libs/omf_python27.lib differ diff --git a/python/libs/pyexpat.lib b/python/libs/pyexpat.lib new file mode 100644 index 000000000..9e65bc879 Binary files /dev/null and b/python/libs/pyexpat.lib differ diff --git a/python/libs/python27.lib b/python/libs/python27.lib new file mode 100644 index 000000000..94542ea17 Binary files /dev/null and b/python/libs/python27.lib differ diff --git a/python/libs/select.lib b/python/libs/select.lib new file mode 100644 index 000000000..7df0fb69f Binary files /dev/null and b/python/libs/select.lib differ diff --git a/python/libs/unicodedata.lib b/python/libs/unicodedata.lib new file mode 100644 index 000000000..d6e6f64a7 Binary files /dev/null and b/python/libs/unicodedata.lib differ diff --git a/python/libs/winsound.lib b/python/libs/winsound.lib new file mode 100644 index 000000000..efa8af838 Binary files /dev/null and b/python/libs/winsound.lib differ