mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 06:19:18 +02:00
Set dp branch as trunk
This commit is contained in:
181
AdvSound.cpp
Normal file
181
AdvSound.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Timer.h"
|
||||
#include "AdvSound.h"
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
|
||||
__fastcall TAdvancedSound::TAdvancedSound()
|
||||
{
|
||||
// SoundStart=SoundCommencing=SoundShut= NULL;
|
||||
State=ss_Off;
|
||||
fTime=0;
|
||||
fStartLength=0;
|
||||
fShutLength=0;
|
||||
}
|
||||
|
||||
__fastcall TAdvancedSound::~TAdvancedSound()
|
||||
{//Ra: stopowanie siê sypie
|
||||
//SoundStart.Stop();
|
||||
//SoundCommencing.Stop();
|
||||
//SoundShut.Stop();
|
||||
}
|
||||
|
||||
void __fastcall TAdvancedSound::Free()
|
||||
{
|
||||
}
|
||||
|
||||
void __fastcall TAdvancedSound::Init(char *NameOn, char *Name, char *NameOff, double DistanceAttenuation, vector3 pPosition)
|
||||
{
|
||||
SoundStart.Init(NameOn,DistanceAttenuation,pPosition.x,pPosition.y,pPosition.z,true);
|
||||
SoundCommencing.Init(Name,DistanceAttenuation,pPosition.x,pPosition.y,pPosition.z,true);
|
||||
SoundShut.Init(NameOff,DistanceAttenuation,pPosition.x,pPosition.y,pPosition.z,true);
|
||||
fStartLength=SoundStart.GetWaveTime();
|
||||
fShutLength=SoundShut.GetWaveTime();
|
||||
SoundStart.AM=1.0;
|
||||
SoundStart.AA=0.0;
|
||||
SoundStart.FM=1.0;
|
||||
SoundStart.FA=0.0;
|
||||
SoundCommencing.AM=1.0;
|
||||
SoundCommencing.AA=0.0;
|
||||
SoundCommencing.FM=1.0;
|
||||
SoundCommencing.FA=0.0;
|
||||
defAM=1.0;
|
||||
defFM=1.0;
|
||||
SoundShut.AM=1.0;
|
||||
SoundShut.AA=0.0;
|
||||
SoundShut.FM=1.0;
|
||||
SoundShut.FA=0.0;
|
||||
}
|
||||
|
||||
void __fastcall TAdvancedSound::Load(TQueryParserComp *Parser, vector3 pPosition)
|
||||
{
|
||||
AnsiString NameOn= Parser->GetNextSymbol().LowerCase();
|
||||
AnsiString Name= Parser->GetNextSymbol().LowerCase();
|
||||
AnsiString NameOff= Parser->GetNextSymbol().LowerCase();
|
||||
double DistanceAttenuation= Parser->GetNextSymbol().ToDouble();
|
||||
Init(NameOn.c_str(),Name.c_str(),NameOff.c_str(),DistanceAttenuation,pPosition);
|
||||
}
|
||||
|
||||
void __fastcall TAdvancedSound::TurnOn(bool ListenerInside, vector3 NewPosition)
|
||||
{
|
||||
//hunter-311211: nie trzeba czekac na ponowne odtworzenie dzwieku, az sie wylaczy
|
||||
if ((State==ss_Off || State==ss_ShuttingDown) && (SoundStart.AM>0))
|
||||
{
|
||||
SoundStart.ResetPosition();
|
||||
SoundCommencing.ResetPosition();
|
||||
SoundStart.Play(1,0,ListenerInside,NewPosition);
|
||||
// SoundStart->SetVolume(-10000);
|
||||
State= ss_Starting;
|
||||
fTime= 0;
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall TAdvancedSound::TurnOff(bool ListenerInside, vector3 NewPosition)
|
||||
{
|
||||
if ((State==ss_Commencing || State==ss_Starting) && (SoundShut.AM>0))
|
||||
{
|
||||
SoundStart.Stop();
|
||||
SoundCommencing.Stop();
|
||||
SoundShut.ResetPosition();
|
||||
SoundShut.Play(1,0,ListenerInside,NewPosition);
|
||||
State= ss_ShuttingDown;
|
||||
fTime= fShutLength;
|
||||
// SoundShut->SetVolume(0);
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall TAdvancedSound::Update(bool ListenerInside, vector3 NewPosition)
|
||||
{
|
||||
if ((State==ss_Commencing) && (SoundCommencing.AM>0))
|
||||
{
|
||||
// SoundCommencing->SetFrequency();
|
||||
SoundShut.Stop(); //hunter-311211
|
||||
SoundCommencing.Play(1,DSBPLAY_LOOPING,ListenerInside,NewPosition);
|
||||
}
|
||||
else
|
||||
if (State==ss_Starting)
|
||||
{
|
||||
fTime+= Timer::GetDeltaTime();
|
||||
// SoundStart->SetVolume(-1000*(4-fTime)/4);
|
||||
if (fTime>=fStartLength)
|
||||
{
|
||||
State= ss_Commencing;
|
||||
SoundCommencing.ResetPosition();
|
||||
SoundCommencing.Play(1,DSBPLAY_LOOPING,ListenerInside,NewPosition);
|
||||
SoundStart.Stop();
|
||||
|
||||
}
|
||||
else
|
||||
SoundStart.Play(1,0,ListenerInside,NewPosition);
|
||||
}
|
||||
else
|
||||
if (State==ss_ShuttingDown)
|
||||
{
|
||||
fTime-= Timer::GetDeltaTime();
|
||||
// SoundShut->SetVolume(-1000*(4-fTime)/4);
|
||||
if (fTime<=0)
|
||||
{
|
||||
State= ss_Off;
|
||||
SoundShut.Stop();
|
||||
}
|
||||
else
|
||||
SoundShut.Play(1,0,ListenerInside,NewPosition);
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall TAdvancedSound::UpdateAF(double A, double F, bool ListenerInside, vector3 NewPosition)
|
||||
{ //update, ale z amplituda i czestotliwoscia
|
||||
if ((State==ss_Commencing) && (SoundCommencing.AM>0))
|
||||
{
|
||||
SoundShut.Stop(); //hunter-311211
|
||||
SoundCommencing.Play(A,DSBPLAY_LOOPING,ListenerInside,NewPosition);
|
||||
}
|
||||
else
|
||||
if (State==ss_Starting)
|
||||
{
|
||||
fTime+= Timer::GetDeltaTime();
|
||||
// SoundStart->SetVolume(-1000*(4-fTime)/4);
|
||||
if (fTime>=fStartLength)
|
||||
{
|
||||
State= ss_Commencing;
|
||||
SoundCommencing.ResetPosition();
|
||||
SoundCommencing.Play(A,DSBPLAY_LOOPING,ListenerInside,NewPosition);
|
||||
SoundStart.Stop();
|
||||
}
|
||||
else
|
||||
SoundStart.Play(A,0,ListenerInside,NewPosition);
|
||||
}
|
||||
else
|
||||
if (State==ss_ShuttingDown)
|
||||
{
|
||||
fTime-= Timer::GetDeltaTime();
|
||||
// SoundShut->SetVolume(-1000*(4-fTime)/4);
|
||||
if (fTime<=0)
|
||||
{
|
||||
State= ss_Off;
|
||||
SoundShut.Stop();
|
||||
}
|
||||
else
|
||||
SoundShut.Play(A,0,ListenerInside,NewPosition);
|
||||
}
|
||||
SoundCommencing.AdjFreq(F,Timer::GetDeltaTime());
|
||||
}
|
||||
|
||||
void __fastcall TAdvancedSound::CopyIfEmpty(TAdvancedSound &s)
|
||||
{//skopiowanie, gdyby by³ potrzebny, a nie zosta³ wczytany
|
||||
if ((fStartLength>0.0)||(fShutLength>0.0)) return; //coœ jest
|
||||
SoundStart=s.SoundStart;
|
||||
SoundCommencing=s.SoundCommencing;
|
||||
SoundShut=s.SoundShut;
|
||||
State=s.State;
|
||||
fStartLength=s.fStartLength;
|
||||
fShutLength=s.fShutLength;
|
||||
defAM=s.defAM;
|
||||
defFM=s.defFM;
|
||||
};
|
||||
|
||||
37
AdvSound.h
Normal file
37
AdvSound.h
Normal file
@@ -0,0 +1,37 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef AdvSoundH
|
||||
#define AdvSoundH
|
||||
|
||||
#include "Sound.h"
|
||||
#include "RealSound.h"
|
||||
#include "QueryParserComp.hpp"
|
||||
|
||||
typedef enum {ss_Off, ss_Starting, ss_Commencing, ss_ShuttingDown} TSoundState;
|
||||
|
||||
class TAdvancedSound
|
||||
{//klasa dŸwiêków maj¹cych pocz¹tek, dowolnie d³ugi œrodek oraz zakoñczenie (np. Rp1)
|
||||
TRealSound SoundStart;
|
||||
TRealSound SoundCommencing;
|
||||
TRealSound SoundShut;
|
||||
TSoundState State;
|
||||
double fTime;
|
||||
double fStartLength;
|
||||
double fShutLength;
|
||||
double defAM;
|
||||
double defFM;
|
||||
|
||||
public:
|
||||
__fastcall TAdvancedSound();
|
||||
__fastcall ~TAdvancedSound();
|
||||
void __fastcall Init(char *NameOn, char *Name, char *NameOff, double DistanceAttenuation, vector3 pPosition);
|
||||
void __fastcall Load(TQueryParserComp *Parser, vector3 pPosition);
|
||||
void __fastcall TurnOn(bool ListenerInside, vector3 NewPosition);
|
||||
void __fastcall TurnOff(bool ListenerInside, vector3 NewPosition);
|
||||
void __fastcall Free();
|
||||
void __fastcall Update(bool ListenerInside, vector3 NewPosition);
|
||||
void __fastcall UpdateAF(double A, double F, bool ListenerInside, vector3 NewPosition);
|
||||
void __fastcall CopyIfEmpty(TAdvancedSound &s);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
73
AirCoupler.cpp
Normal file
73
AirCoupler.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "AirCoupler.h"
|
||||
#include "Timer.h"
|
||||
|
||||
__fastcall TAirCoupler::TAirCoupler()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
__fastcall TAirCoupler::~TAirCoupler()
|
||||
{
|
||||
}
|
||||
|
||||
int __fastcall TAirCoupler::GetStatus()
|
||||
{//zwraca 1, jeœli istnieje model prosty, 2 gdy skoœny
|
||||
int x=0;
|
||||
if (pModelOn) x=1;
|
||||
if (pModelxOn) x=2;
|
||||
return x;
|
||||
}
|
||||
|
||||
void __fastcall TAirCoupler::Clear()
|
||||
{//zerowanie wskaŸników
|
||||
pModelOn=NULL;
|
||||
pModelOff=NULL;
|
||||
pModelxOn=NULL;
|
||||
bOn=false;
|
||||
bxOn=false;
|
||||
}
|
||||
|
||||
|
||||
void __fastcall TAirCoupler::Init(AnsiString asName, TModel3d *pModel)
|
||||
{//wyszukanie submodeli
|
||||
if (!pModel) return; //nie ma w czym szukaæ
|
||||
pModelOn=pModel->GetFromName(AnsiString(asName+"_on").c_str()); //po³¹czony na wprost
|
||||
pModelOff=pModel->GetFromName(AnsiString(asName+"_off").c_str()); //odwieszony
|
||||
pModelxOn=pModel->GetFromName(AnsiString(asName+"_xon").c_str()); //po³¹czony na skos
|
||||
}
|
||||
|
||||
void __fastcall TAirCoupler::Load(TQueryParserComp *Parser, TModel3d *pModel)
|
||||
{
|
||||
AnsiString str=Parser->GetNextSymbol().LowerCase();
|
||||
if (pModel)
|
||||
Init(str,pModel);
|
||||
else
|
||||
{
|
||||
pModelOn=NULL;
|
||||
pModelxOn=NULL;
|
||||
pModelOff=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall TAirCoupler::Update()
|
||||
{
|
||||
// if ((pModelOn!=NULL) && (pModelOn!=NULL))
|
||||
{
|
||||
if (pModelOn)
|
||||
pModelOn->iVisible=bOn;
|
||||
if (pModelOff)
|
||||
pModelOff->iVisible=!(bOn||bxOn);
|
||||
if (pModelxOn)
|
||||
pModelxOn->iVisible=bxOn;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
32
AirCoupler.h
Normal file
32
AirCoupler.h
Normal file
@@ -0,0 +1,32 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef AirCouplerH
|
||||
#define AirCouplerH
|
||||
|
||||
#include "Model3d.h"
|
||||
#include "QueryParserComp.hpp"
|
||||
|
||||
class TAirCoupler
|
||||
{
|
||||
private:
|
||||
// TButtonType eType;
|
||||
TSubModel *pModelOn,*pModelOff,*pModelxOn;
|
||||
bool bOn;
|
||||
bool bxOn;
|
||||
void __fastcall Update();
|
||||
public:
|
||||
__fastcall TAirCoupler();
|
||||
__fastcall ~TAirCoupler();
|
||||
void __fastcall Clear();
|
||||
inline void TurnOn() { bOn=true; bxOn=false; Update(); };
|
||||
inline void TurnOff() { bOn=false; bxOn=false; Update(); };
|
||||
inline void TurnxOn() { bOn=false; bxOn=true; Update(); };
|
||||
// inline bool Active() { if ((pModelOn)||(pModelOff)) return true; return false;};
|
||||
int __fastcall GetStatus();
|
||||
void __fastcall Init(AnsiString asName, TModel3d *pModel);
|
||||
void __fastcall Load(TQueryParserComp *Parser, TModel3d *pModel);
|
||||
// bool __fastcall Render();
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
787
AnimModel.cpp
Normal file
787
AnimModel.cpp
Normal file
@@ -0,0 +1,787 @@
|
||||
//---------------------------------------------------------------------------
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak and others
|
||||
|
||||
*/
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "AnimModel.h"
|
||||
#include "usefull.h"
|
||||
#include "Timer.h"
|
||||
#include "MdlMngr.h"
|
||||
//McZapkie:
|
||||
#include "Texture.h"
|
||||
#include "Globals.h"
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
__fastcall TAnimAdvanced::TAnimAdvanced()
|
||||
{
|
||||
};
|
||||
__fastcall TAnimAdvanced::~TAnimAdvanced()
|
||||
{
|
||||
//delete[] pVocaloidMotionData; //plik został zmodyfikowany
|
||||
};
|
||||
|
||||
int __fastcall TAnimAdvanced::SortByBone()
|
||||
{//sortowanie pliku animacji w celu optymalniejszego wykonania
|
||||
//rekordy zostają ułożone wg kolejnych ramek dla każdej kości
|
||||
//ułożenie kości alfabetycznie nie jest niezbędne, ale upraszcza sortowanie bąbelkowe
|
||||
TAnimVocaloidFrame buf; //bufor roboczy (przydało by się pascalowe Swap()
|
||||
int i,j,k,swaps=0,last=iMovements-1,e;
|
||||
for (i=0;i<iMovements;++i)
|
||||
for (j=0;j<15;++j)
|
||||
if (pMovementData[i].cBone[j]=='\0') //jeśli znacznik końca
|
||||
for (++j;j<15;++j)
|
||||
pMovementData[i].cBone[j]='\0'; //zerowanie bajtów za znacznikiem końca
|
||||
for (i=0;i<last;++i) //do przedostatniego
|
||||
{//dopóki nie posortowane
|
||||
j=i; //z którym porównywać
|
||||
k=i; //z którym zamienić (nie trzeba zamieniać, jeśli ==i)
|
||||
while (++j<iMovements)
|
||||
{e=strcmp(pMovementData[k].cBone,pMovementData[j].cBone); //numery trzeba porównywać inaczej
|
||||
if (e>0)
|
||||
k=j; //trzeba zamienić - ten pod j jest mniejszy
|
||||
else if (!e)
|
||||
if (pMovementData[k].iFrame>pMovementData[j].iFrame)
|
||||
k=j; //numer klatki pod j jest mniejszy
|
||||
}
|
||||
if (k>i)
|
||||
{//jeśli trzeba przestawić
|
||||
//buf=pMovementData[i];
|
||||
//pMovementData[i]=pMovementData[k];
|
||||
//pMovementData[k]=buf;
|
||||
memcpy(&buf,pMovementData+i,sizeof(TAnimVocaloidFrame));
|
||||
memcpy(pMovementData+i,pMovementData+k,sizeof(TAnimVocaloidFrame));
|
||||
memcpy(pMovementData+k,&buf,sizeof(TAnimVocaloidFrame));
|
||||
++swaps;
|
||||
}
|
||||
}
|
||||
return swaps;
|
||||
};
|
||||
|
||||
__fastcall TAnimContainer::TAnimContainer()
|
||||
{
|
||||
pNext=NULL;
|
||||
vRotateAngles=vector3(0.0f,0.0f,0.0f); //aktualne kąty obrotu
|
||||
vDesiredAngles=vector3(0.0f,0.0f,0.0f); //docelowe kąty obrotu
|
||||
fRotateSpeed=0.0;
|
||||
vTranslation=vector3(0.0f,0.0f,0.0f); //aktualne przesunięcie
|
||||
vTranslateTo=vector3(0.0f,0.0f,0.0f); //docelowe przesunięcie
|
||||
fTranslateSpeed=0.0;
|
||||
fAngleSpeed=0.0;
|
||||
pSubModel=NULL;
|
||||
iAnim=0; //położenie początkowe
|
||||
pMovementData=NULL; //nie ma zaawansowanej animacji
|
||||
mAnim=NULL; //nie ma macierzy obrotu dla submodelu
|
||||
evDone=NULL; //powiadamianie o zakończeniu animacji
|
||||
acAnimNext=NULL; //na razie jest poza listą
|
||||
}
|
||||
|
||||
__fastcall TAnimContainer::~TAnimContainer()
|
||||
{
|
||||
SafeDelete(pNext);
|
||||
delete mAnim; //AnimContainer jest właścicielem takich macierzy
|
||||
}
|
||||
|
||||
bool __fastcall TAnimContainer::Init(TSubModel *pNewSubModel)
|
||||
{
|
||||
fRotateSpeed=0.0f;
|
||||
pSubModel=pNewSubModel;
|
||||
return (pSubModel!=NULL);
|
||||
}
|
||||
|
||||
void __fastcall TAnimContainer::SetRotateAnim(vector3 vNewRotateAngles, double fNewRotateSpeed)
|
||||
{
|
||||
if (!this) return; //wywoływane z eventu, gdy brak modelu
|
||||
vDesiredAngles=vNewRotateAngles;
|
||||
fRotateSpeed=fNewRotateSpeed;
|
||||
iAnim|=1;
|
||||
/* //Ra 2014-07: jeśli model nie jest renderowany, to obliczyć czas animacji i dodać event wewnętrzny
|
||||
//można by też ustawić czas początku animacji zamiast pobierać czas ramki i liczyć różnicę
|
||||
*/
|
||||
if (evDone)
|
||||
{//dołączyć model do listy aniomowania, żeby animacje były przeliczane również bez wyświetlania
|
||||
if (iAnim>=0)
|
||||
{//jeśli nie jest jeszcze na liście animacyjnej
|
||||
acAnimNext=TAnimModel::acAnimList; //pozostałe doklić sobie jako ogon
|
||||
TAnimModel::acAnimList=this; //a wstawić się na początek
|
||||
iAnim|=0x80000000; //dodany do listy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall TAnimContainer::SetTranslateAnim(vector3 vNewTranslate, double fNewSpeed)
|
||||
{
|
||||
if (!this) return; //wywoływane z eventu, gdy brak modelu
|
||||
vTranslateTo=vNewTranslate;
|
||||
fTranslateSpeed=fNewSpeed;
|
||||
iAnim|=2;
|
||||
/* //Ra 2014-07: jeśli model nie jest renderowany, to obliczyć czas animacji i dodać event wewnętrzny
|
||||
//można by też ustawić czas początku animacji zamiast pobierać czas ramki i liczyć różnicę
|
||||
*/
|
||||
if (evDone)
|
||||
{//dołączyć model do listy aniomowania, żeby animacje były przeliczane również bez wyświetlania
|
||||
if (iAnim>=0)
|
||||
{//jeśli nie jest jeszcze na liście animacyjnej
|
||||
acAnimNext=TAnimModel::acAnimList; //pozostałe doklić sobie jako ogon
|
||||
TAnimModel::acAnimList=this; //a wstawić się na początek
|
||||
iAnim|=0x80000000; //dodany do listy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall TAnimContainer::AnimSetVMD(double fNewSpeed)
|
||||
{
|
||||
if (!this) return; //wywoływane z eventu, gdy brak modelu
|
||||
//skala do ustalenia, "cal" japoński (sun) to nieco ponad 3cm
|
||||
//X-w lewo, Y-w górę, Z-do tyłu
|
||||
//minimalna wysokość to -7.66, a nadal musi być ponad podłogą
|
||||
//if (pMovementData->iFrame>0) return; //tylko pierwsza ramka
|
||||
vTranslateTo=vector3(0.1*pMovementData->f3Vector.x,0.1*pMovementData->f3Vector.z,0.1*pMovementData->f3Vector.y);
|
||||
if (LengthSquared3(vTranslateTo)>0.0?true:LengthSquared3(vTranslation)>0.0)
|
||||
{//jeśli ma być przesunięte albo jest przesunięcie
|
||||
iAnim|=2; //wyłączy się samo
|
||||
if (fNewSpeed>0.0)
|
||||
fTranslateSpeed=fNewSpeed; //prędkość jest mnożnikiem, nie podlega skalowaniu
|
||||
else //za późno na animacje, trzeba przestawić
|
||||
vTranslation=vTranslateTo;
|
||||
}
|
||||
//if ((qCurrent.w<1.0)||(pMovementData->qAngle.w<1.0))
|
||||
{//jeśli jest jakiś obrót
|
||||
if (!mAnim)
|
||||
{mAnim=new float4x4(); //będzie potrzebna macierz animacji
|
||||
mAnim->Identity(); //jedynkowanie na początek
|
||||
}
|
||||
iAnim|=4; //animacja kwaternionowa
|
||||
qStart=qCurrent; //potrzebna początkowa do interpolacji
|
||||
//---+ - też niby dobrze, ale nie tak trąca włosy na początku (macha w dół)
|
||||
//-+-+ - dłoń ma w górze zamiast na pasie w pozycji początkowej
|
||||
//+--+ - głowa do tyłu (broda w górę) w pozycji początkowej
|
||||
//--++ - pozycja początkowa dobra, trąca u góry, ale z rękami jakoś nie tak, kółko w przeciwną stronę
|
||||
//++++ - kładzie się brzuchem do góry
|
||||
//-+++ - ręce w górze na początku, zamiast w dół, łokieć jakby w przeciwną stronę
|
||||
//+-++ - nie podnosi ręki do głowy
|
||||
//++-+ - dłoń ma w górze zamiast na pasie
|
||||
qDesired=Normalize(float4(-pMovementData->qAngle.x,-pMovementData->qAngle.z,-pMovementData->qAngle.y,pMovementData->qAngle.w)); //tu trzeba będzie osie zamienić
|
||||
if (fNewSpeed>0.0)
|
||||
{fAngleSpeed=fNewSpeed; //wtedy animować za pomocą interpolacji
|
||||
fAngleCurrent=0.0; //początek interpolacji
|
||||
}
|
||||
else
|
||||
{//za późno na animację, można tylko przestawić w docelowe miejsce
|
||||
fAngleSpeed=0.0;
|
||||
fAngleCurrent=1.0; //interpolacja zakończona
|
||||
qCurrent=qDesired;
|
||||
}
|
||||
}
|
||||
//if (!strcmp(pSubModel->pName,"?Z?“?^?[")) //jak główna kość
|
||||
//if (!strcmp(pSubModel->pName,"Ť¶‚‚Ü?ć‚h‚j")) //IK lewej stopy
|
||||
// WriteLog(AnsiString(pMovementData->iFrame)+": "+AnsiString(pMovementData->f3Vector.x)+" "+AnsiString(pMovementData->f3Vector.y)+" "+AnsiString(pMovementData->f3Vector.z));
|
||||
}
|
||||
|
||||
void __fastcall TAnimContainer::UpdateModel()
|
||||
{//przeliczanie animacji wykonać tylko raz na model
|
||||
if (pSubModel) //pozbyć się tego - sprawdzać wcześniej
|
||||
{
|
||||
if (fTranslateSpeed!=0.0)
|
||||
{
|
||||
vector3 dif=vTranslateTo-vTranslation; //wektor w kierunku docelowym
|
||||
double l=LengthSquared3(dif); //długość wektora potrzebnego przemieszczenia
|
||||
if (l>=0.0001)
|
||||
{//jeśli do przemieszczenia jest ponad 1cm
|
||||
vector3 s=SafeNormalize(dif); //jednostkowy wektor kierunku
|
||||
s=s*(fTranslateSpeed*Timer::GetDeltaTime()); //przemieszczenie w podanym czasie z daną prędkością
|
||||
if (LengthSquared3(s)<l) //żeby nie jechało na drugą stronę
|
||||
vTranslation+=s;
|
||||
else
|
||||
vTranslation=vTranslateTo; //koniec animacji, "koniec animowania" uruchomi się w następnej klatce
|
||||
}
|
||||
else
|
||||
{//koniec animowania
|
||||
vTranslation=vTranslateTo;
|
||||
fTranslateSpeed=0.0; //wyłączenie przeliczania wektora
|
||||
if (LengthSquared3(vTranslation)<=0.0001) //jeśli jest w punkcie początkowym
|
||||
iAnim&=~2; //wyłączyć zmianę pozycji submodelu
|
||||
if (evDone) Global::AddToQuery(evDone,NULL); //wykonanie eventu informującego o zakończeniu
|
||||
}
|
||||
}
|
||||
if (fRotateSpeed!=0)
|
||||
{
|
||||
|
||||
/*
|
||||
double dif= fDesiredAngle-fAngle;
|
||||
double s= fRotateSpeed*sign(dif)*Timer::GetDeltaTime();
|
||||
if ((abs(s)-abs(dif))>0)
|
||||
fAngle= fDesiredAngle;
|
||||
else
|
||||
fAngle+= s;
|
||||
|
||||
while (fAngle>360) fAngle-= 360;
|
||||
while (fAngle<-360) fAngle+= 360;
|
||||
pSubModel->SetRotate(vRotateAxis,fAngle);
|
||||
*/
|
||||
|
||||
bool anim=false;
|
||||
vector3 dif=vDesiredAngles-vRotateAngles;
|
||||
double s;
|
||||
s=fRotateSpeed*sign(dif.x)*Timer::GetDeltaTime();
|
||||
if (fabs(s)>=fabs(dif.x))
|
||||
vRotateAngles.x=vDesiredAngles.x;
|
||||
else
|
||||
{vRotateAngles.x+=s; anim=true;}
|
||||
s=fRotateSpeed*sign(dif.y)*Timer::GetDeltaTime();
|
||||
if (fabs(s)>=fabs(dif.y))
|
||||
vRotateAngles.y=vDesiredAngles.y;
|
||||
else
|
||||
{vRotateAngles.y+=s; anim=true;}
|
||||
s=fRotateSpeed*sign(dif.z)*Timer::GetDeltaTime();
|
||||
if (fabs(s)>=fabs(dif.z))
|
||||
vRotateAngles.z=vDesiredAngles.z;
|
||||
else
|
||||
{vRotateAngles.z+=s; anim=true;}
|
||||
while (vRotateAngles.x>= 360) vRotateAngles.x-=360;
|
||||
while (vRotateAngles.x<=-360) vRotateAngles.x+=360;
|
||||
while (vRotateAngles.y>= 360) vRotateAngles.y-=360;
|
||||
while (vRotateAngles.y<=-360) vRotateAngles.y+=360;
|
||||
while (vRotateAngles.z>= 360) vRotateAngles.z-=360;
|
||||
while (vRotateAngles.z<=-360) vRotateAngles.z+=360;
|
||||
if (vRotateAngles.x==0.0)
|
||||
if (vRotateAngles.y==0.0)
|
||||
if (vRotateAngles.z==0.0)
|
||||
iAnim&=~1; //kąty są zerowe
|
||||
if (!anim)
|
||||
{//nie potrzeba przeliczać już
|
||||
fRotateSpeed=0.0;
|
||||
if (evDone) Global::AddToQuery(evDone,NULL); //wykonanie eventu informującego o zakończeniu
|
||||
}
|
||||
}
|
||||
if (fAngleSpeed!=0.0)
|
||||
{//obrót kwaternionu (interpolacja)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TAnimContainer::PrepareModel()
|
||||
{//tutaj zostawić tylko ustawienie submodelu, przeliczanie ma być w UpdateModel()
|
||||
if (pSubModel) //pozbyć się tego - sprawdzać wcześniej
|
||||
{
|
||||
//nanoszenie animacji na wzorzec
|
||||
if (iAnim&1) //zmieniona pozycja względem początkowej
|
||||
pSubModel->SetRotateXYZ(vRotateAngles); //ustawia typ animacji
|
||||
if (iAnim&2) //zmieniona pozycja względem początkowej
|
||||
pSubModel->SetTranslate(vTranslation);
|
||||
if (iAnim&4) //zmieniona pozycja względem początkowej
|
||||
{
|
||||
if (fAngleSpeed>0.0f)
|
||||
{fAngleCurrent+=fAngleSpeed*Timer::GetDeltaTime(); //aktualny parametr interpolacji
|
||||
if (fAngleCurrent>=1.0f)
|
||||
{//interpolacja zakończona, ustawienie na pozycję końcową
|
||||
qCurrent=qDesired;
|
||||
fAngleSpeed=0.0; //wyłączenie przeliczania wektora
|
||||
if (evDone) Global::AddToQuery(evDone,NULL); //wykonanie eventu informującego o zakończeniu
|
||||
}
|
||||
else
|
||||
{//obliczanie pozycji pośredniej
|
||||
//normalizacja jest wymagana do interpolacji w następnej animacji
|
||||
qCurrent=Normalize(Slerp(qStart,qDesired,fAngleCurrent)); //interpolacja sferyczna kąta
|
||||
//qCurrent=Slerp(qStart,qDesired,fAngleCurrent); //interpolacja sferyczna kąta
|
||||
if (qCurrent.w==1.0) //rozpoznać brak obrotu i wyłączyć w iAnim w takim przypadku
|
||||
iAnim&=~4; //kąty są zerowe
|
||||
}
|
||||
}
|
||||
mAnim->Quaternion(&qCurrent); //wypełnienie macierzy (wymaga normalizacji?)
|
||||
pSubModel->mAnimMatrix=mAnim; //użyczenie do submodelu (na czas renderowania!)
|
||||
}
|
||||
}
|
||||
//if (!strcmp(pSubModel->pName,"?Z?“?^?[")) //jak główna kość
|
||||
// WriteLog(AnsiString(pMovementData->iFrame)+": "+AnsiString(iAnim)+" "+AnsiString(vTranslation.x)+" "+AnsiString(vTranslation.y)+" "+AnsiString(vTranslation.z));
|
||||
}
|
||||
|
||||
void __fastcall TAnimContainer::UpdateModelIK()
|
||||
{//odwrotna kinematyka wyliczana dopiero po ustawieniu macierzy w submodelach
|
||||
if (pSubModel) //pozbyć się tego - sprawdzać wcześniej
|
||||
{
|
||||
if (pSubModel->b_Anim&at_IK)
|
||||
{//odwrotna kinematyka
|
||||
float3 d,k;
|
||||
TSubModel *ch=pSubModel->ChildGet();
|
||||
switch (pSubModel->b_Anim)
|
||||
{
|
||||
case at_IK11: //stopa: ustawić w kierunku czubka (pierwszy potomny)
|
||||
d=ch->Translation1Get(); //wektor względem aktualnego układu (nie uwzględnia obrotu)
|
||||
k=float3(RadToDeg(atan2(d.z,hypot(d.x,d.y))),0.0,-RadToDeg(atan2(d.y,d.x))); //proste skierowanie na punkt
|
||||
pSubModel->SetRotateIK1(k);
|
||||
//if (!strcmp(pSubModel->pName,"?Z?“?^?[")) //jak główna kość
|
||||
// WriteLog("--> "+AnsiString(k.x)+" "+AnsiString(k.y)+" "+AnsiString(k.z));
|
||||
//Ra: to już jest dobrze, może być inna ćwiartka i znak
|
||||
break;
|
||||
case at_IK22: //udo: ustawić w kierunku pierwszej potomnej pierwszej potomnej (kostki)
|
||||
//pozycję kostki należy określić względem kości centralnej (+biodro może być pochylone)
|
||||
//potem wyliczyć ewentualne odchylenie w tej i następnej
|
||||
//w sumie to proste, jak wyznaczenie kątów w trójkącie o znanej długości boków...
|
||||
d=ch->Translation2Get(); //wektor względem aktualnego układu (nie uwzględnia obrotu)
|
||||
//if ()
|
||||
{//kość IK jest dalej niż pozycja spoczynkowa
|
||||
k=float3(RadToDeg(atan2(d.z,hypot(d.x,d.y))),0.0,-RadToDeg(atan2(d.y,d.x))); //proste skierowanie na punkt
|
||||
pSubModel->SetRotateIK1(k);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool __fastcall TAnimContainer::InMovement()
|
||||
{//czy trwa animacja - informacja dla obrotnicy
|
||||
return (fRotateSpeed!=0.0)||(fTranslateSpeed!=0.0);
|
||||
}
|
||||
|
||||
void __fastcall TAnimContainer::EventAssign(TEvent *ev)
|
||||
{//przypisanie eventu wykonywanego po zakończeniu animacji
|
||||
evDone=ev;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
__fastcall TAnimModel::TAnimModel()
|
||||
{
|
||||
pRoot=NULL;
|
||||
pModel=NULL;
|
||||
iNumLights=0;
|
||||
fBlinkTimer=0;
|
||||
ReplacableSkinId[0]=0;
|
||||
ReplacableSkinId[1]=0;
|
||||
ReplacableSkinId[2]=0;
|
||||
ReplacableSkinId[3]=0;
|
||||
ReplacableSkinId[4]=0;
|
||||
for (int i=0;i<iMaxNumLights;i++)
|
||||
{
|
||||
LightsOn[i]=LightsOff[i]=NULL; //normalnie nie ma
|
||||
lsLights[i]=ls_Off; //a jeśli są, to wyłączone
|
||||
}
|
||||
vAngle.x=vAngle.y=vAngle.z=0.0; //zerowanie obrotów egzemplarza
|
||||
pAdvanced=NULL; //nie ma zaawansowanej animacji
|
||||
fDark=0.25; //standardowy próg zaplania
|
||||
fOnTime=0.66;
|
||||
fOffTime=fOnTime+0.66;
|
||||
}
|
||||
|
||||
__fastcall TAnimModel::~TAnimModel()
|
||||
{
|
||||
delete pAdvanced; //nie ma zaawansowanej animacji
|
||||
SafeDelete(pRoot);
|
||||
}
|
||||
|
||||
bool __fastcall TAnimModel::Init(TModel3d *pNewModel)
|
||||
{
|
||||
fBlinkTimer=double(random(1000*fOffTime))/(1000*fOffTime);;
|
||||
pModel=pNewModel;
|
||||
return (pModel!=NULL);
|
||||
}
|
||||
|
||||
bool __fastcall TAnimModel::Init(AnsiString asName, AnsiString asReplacableTexture)
|
||||
{
|
||||
if (asReplacableTexture.SubString(1,1)=="*") //od gwiazdki zaczynają się teksty na wyświetlaczach
|
||||
asText=asReplacableTexture.SubString(2,asReplacableTexture.Length()-1); //zapamiętanie tekstu
|
||||
else if (asReplacableTexture!="none")
|
||||
ReplacableSkinId[1]=TTexturesManager::GetTextureID(NULL,NULL,asReplacableTexture.c_str());
|
||||
if (TTexturesManager::GetAlpha(ReplacableSkinId[1]))
|
||||
iTexAlpha=0x31310031; //tekstura z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
else
|
||||
iTexAlpha=0x30300030; //tekstura nieprzezroczysta - nie renderować w cyklu przezroczystych
|
||||
return (Init(TModelsManager::GetModel(asName.c_str())));
|
||||
}
|
||||
|
||||
bool __fastcall TAnimModel::Load(cParser *parser, bool ter)
|
||||
{//rozpoznanie wpisu modelu i ustawienie świateł
|
||||
AnsiString str;
|
||||
std::string token;
|
||||
parser->getTokens(); //nazwa modelu
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
parser->getTokens(1,false); //tekstura (zmienia na małe)
|
||||
*parser >> token;
|
||||
if (!Init(str,AnsiString(token.c_str())))
|
||||
{if (str!="notload")
|
||||
{//gdy brak modelu
|
||||
if (ter) //jeśli teren
|
||||
{if (str.SubString(str.Length()-3,4)==".t3d")
|
||||
str[str.Length()-2]='e';
|
||||
Global::asTerrainModel=str;
|
||||
WriteLog(AnsiString("Terrain model \""+str+"\" will be created."));
|
||||
}
|
||||
else
|
||||
ErrorLog(AnsiString("Missed file: "+str));
|
||||
}
|
||||
}
|
||||
else
|
||||
{//wiązanie świateł, o ile model wczytany
|
||||
LightsOn[0]=pModel->GetFromName("Light_On00");
|
||||
LightsOn[1]=pModel->GetFromName("Light_On01");
|
||||
LightsOn[2]=pModel->GetFromName("Light_On02");
|
||||
LightsOn[3]=pModel->GetFromName("Light_On03");
|
||||
LightsOn[4]=pModel->GetFromName("Light_On04");
|
||||
LightsOn[5]=pModel->GetFromName("Light_On05");
|
||||
LightsOn[6]=pModel->GetFromName("Light_On06");
|
||||
LightsOn[7]=pModel->GetFromName("Light_On07");
|
||||
LightsOff[0]=pModel->GetFromName("Light_Off00");
|
||||
LightsOff[1]=pModel->GetFromName("Light_Off01");
|
||||
LightsOff[2]=pModel->GetFromName("Light_Off02");
|
||||
LightsOff[3]=pModel->GetFromName("Light_Off03");
|
||||
LightsOff[4]=pModel->GetFromName("Light_Off04");
|
||||
LightsOff[5]=pModel->GetFromName("Light_Off05");
|
||||
LightsOff[6]=pModel->GetFromName("Light_Off06");
|
||||
LightsOff[7]=pModel->GetFromName("Light_Off07");
|
||||
}
|
||||
for (int i=0;i<iMaxNumLights;++i)
|
||||
if (LightsOn[i]||LightsOff[i]) //Ra: zlikwidowałem wymóg istnienia obu
|
||||
iNumLights=i+1;
|
||||
int i=0;
|
||||
int ti;
|
||||
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
|
||||
if (token.compare( "lights" ) == 0)
|
||||
{
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
do
|
||||
{
|
||||
ti=str.ToDouble(); //stan światła jest liczbą z ułamkiem
|
||||
LightSet(i,ti);
|
||||
i++;
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
} while (str!="endmodel");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TAnimContainer* __fastcall TAnimModel::AddContainer(char *pName)
|
||||
{//dodanie sterowania submodelem dla egzemplarza
|
||||
if (!pModel) return NULL;
|
||||
TSubModel *tsb=pModel->GetFromName(pName);
|
||||
if (tsb)
|
||||
{
|
||||
TAnimContainer *tmp=new TAnimContainer();
|
||||
tmp->Init(tsb);
|
||||
tmp->pNext=pRoot;
|
||||
pRoot=tmp;
|
||||
return tmp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TAnimContainer* __fastcall TAnimModel::GetContainer(char *pName)
|
||||
{//szukanie/dodanie sterowania submodelem dla egzemplarza
|
||||
if (!pName) return pRoot; //pobranie pierwszego (dla obrotnicy)
|
||||
TAnimContainer *pCurrent;
|
||||
for (pCurrent=pRoot;pCurrent!=NULL;pCurrent=pCurrent->pNext)
|
||||
//if (pCurrent->GetName()==pName)
|
||||
if (stricmp(pCurrent->NameGet(),pName)==0)
|
||||
return pCurrent;
|
||||
return AddContainer(pName);
|
||||
}
|
||||
|
||||
void __fastcall TAnimModel::RaAnimate()
|
||||
{//przeliczenie animacji - jednorazowo na klatkę
|
||||
//Ra 2F1I: to by można pomijać dla modeli bez animacji, których jest większość
|
||||
TAnimContainer *pCurrent;
|
||||
for (pCurrent=pRoot;pCurrent!=NULL;pCurrent=pCurrent->pNext)
|
||||
if (!pCurrent->evDone) //jeśli jest bez eventu
|
||||
pCurrent->UpdateModel(); //przeliczenie animacji każdego submodelu
|
||||
//if () //tylko dla modeli z IK !!!!
|
||||
for (pCurrent=pRoot;pCurrent!=NULL;pCurrent=pCurrent->pNext) //albo osobny łańcuch
|
||||
pCurrent->UpdateModelIK(); //przeliczenie odwrotnej kinematyki
|
||||
};
|
||||
|
||||
void __fastcall TAnimModel::RaPrepare()
|
||||
{//ustawia światła i animacje we wzorcu modelu przed renderowaniem egzemplarza
|
||||
fBlinkTimer-=Timer::GetDeltaTime();
|
||||
if (fBlinkTimer<=0) fBlinkTimer=fOffTime;
|
||||
bool state; //stan światła
|
||||
for (int i=0;i<iNumLights;i++)
|
||||
{switch (lsLights[i])
|
||||
{case ls_Blink: //migotanie
|
||||
state=fBlinkTimer<fOnTime; break;
|
||||
case ls_Dark: //zapalone, gdy ciemno
|
||||
state=Global::fLuminance<=fDark; break;
|
||||
default: //zapalony albo zgaszony
|
||||
state=(lsLights[i]==ls_On);
|
||||
}
|
||||
if (LightsOn[i]) LightsOn[i]->iVisible=state;
|
||||
if (LightsOff[i]) LightsOff[i]->iVisible=!state;
|
||||
}
|
||||
TSubModel::iInstance=(int)this; //żeby nie robić cudzych animacji
|
||||
TSubModel::pasText=&asText; //przekazanie tekstu do wyświetlacza (!!!! do przemyślenia)
|
||||
if (pAdvanced) //jeśli jest zaawansowana animacja
|
||||
Advanced(); //wykonać co tam trzeba
|
||||
TAnimContainer *pCurrent;
|
||||
for (pCurrent=pRoot;pCurrent!=NULL;pCurrent=pCurrent->pNext)
|
||||
pCurrent->PrepareModel(); //ustawienie animacji egzemplarza dla każdego submodelu
|
||||
//if () //tylko dla modeli z IK !!!!
|
||||
// for (pCurrent=pRoot;pCurrent!=NULL;pCurrent=pCurrent->pNext) //albo osobny łańcuch
|
||||
// pCurrent->UpdateModelIK(); //przeliczenie odwrotnej kinematyki
|
||||
}
|
||||
|
||||
void __fastcall TAnimModel::RenderVBO(vector3 pPosition,double fAngle)
|
||||
{//sprawdza światła i rekurencyjnie renderuje TModel3d
|
||||
RaAnimate(); //jednorazowe przeliczenie animacji
|
||||
RaPrepare();
|
||||
if (pModel) //renderowanie rekurencyjne submodeli
|
||||
pModel->RaRender(pPosition,fAngle,ReplacableSkinId,iTexAlpha);
|
||||
}
|
||||
|
||||
void __fastcall TAnimModel::RenderAlphaVBO(vector3 pPosition,double fAngle)
|
||||
{
|
||||
RaPrepare();
|
||||
if (pModel) //renderowanie rekurencyjne submodeli
|
||||
pModel->RaRenderAlpha(pPosition,fAngle,ReplacableSkinId,iTexAlpha);
|
||||
};
|
||||
|
||||
void __fastcall TAnimModel::RenderDL(vector3 pPosition,double fAngle)
|
||||
{
|
||||
RaAnimate(); //jednorazowe przeliczenie animacji
|
||||
RaPrepare();
|
||||
if (pModel) //renderowanie rekurencyjne submodeli
|
||||
pModel->Render(pPosition,fAngle,ReplacableSkinId,iTexAlpha);
|
||||
}
|
||||
|
||||
void __fastcall TAnimModel::RenderAlphaDL(vector3 pPosition,double fAngle)
|
||||
{
|
||||
RaPrepare();
|
||||
if (pModel)
|
||||
pModel->RenderAlpha(pPosition,fAngle,ReplacableSkinId,iTexAlpha);
|
||||
};
|
||||
|
||||
int __fastcall TAnimModel::Flags()
|
||||
{//informacja dla TGround, czy ma być w Render, RenderAlpha, czy RenderMixed
|
||||
int i=pModel?pModel->Flags():0; //pobranie flag całego modelu
|
||||
if (ReplacableSkinId[1]>0) //jeśli ma wymienną teksturę 0
|
||||
i|=(i&0x01010001)*((iTexAlpha&1)?0x20:0x10);
|
||||
//if (ReplacableSkinId[2]>0) //jeśli ma wymienną teksturę 1
|
||||
// i|=(i&0x02020002)*((iTexAlpha&1)?0x10:0x08);
|
||||
//if (ReplacableSkinId[3]>0) //jeśli ma wymienną teksturę 2
|
||||
// i|=(i&0x04040004)*((iTexAlpha&1)?0x08:0x04);
|
||||
//if (ReplacableSkinId[4]>0) //jeśli ma wymienną teksturę 3
|
||||
// i|=(i&0x08080008)*((iTexAlpha&1)?0x04:0x02);
|
||||
return i;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//2011-03-16 cztery nowe funkcje renderowania z możliwością pochylania obiektów
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void __fastcall TAnimModel::RenderDL(vector3* vPosition)
|
||||
{
|
||||
RaAnimate(); //jednorazowe przeliczenie animacji
|
||||
RaPrepare();
|
||||
if (pModel) //renderowanie rekurencyjne submodeli
|
||||
pModel->Render(vPosition,&vAngle,ReplacableSkinId,iTexAlpha);
|
||||
};
|
||||
void __fastcall TAnimModel::RenderAlphaDL(vector3* vPosition)
|
||||
{
|
||||
RaPrepare();
|
||||
if (pModel) //renderowanie rekurencyjne submodeli
|
||||
pModel->RenderAlpha(vPosition,&vAngle,ReplacableSkinId,iTexAlpha);
|
||||
};
|
||||
void __fastcall TAnimModel::RenderVBO(vector3* vPosition)
|
||||
{
|
||||
RaAnimate(); //jednorazowe przeliczenie animacji
|
||||
RaPrepare();
|
||||
if (pModel) //renderowanie rekurencyjne submodeli
|
||||
pModel->RaRender(vPosition,&vAngle,ReplacableSkinId,iTexAlpha);
|
||||
};
|
||||
void __fastcall TAnimModel::RenderAlphaVBO(vector3* vPosition)
|
||||
{
|
||||
RaPrepare();
|
||||
if (pModel) //renderowanie rekurencyjne submodeli
|
||||
pModel->RaRenderAlpha(vPosition,&vAngle,ReplacableSkinId,iTexAlpha);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TAnimModel::TerrainLoaded()
|
||||
{//zliczanie kwadratów kilometrowych (główna linia po Next) do tworznia tablicy
|
||||
return (this?pModel!=NULL:false);
|
||||
};
|
||||
int __fastcall 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)
|
||||
{//pobieranie wskaźników do pierwszego submodelu
|
||||
return pModel?pModel->TerrainSquare(n):0;
|
||||
};
|
||||
void __fastcall TAnimModel::TerrainRenderVBO(int n)
|
||||
{//renderowanie terenu z VBO
|
||||
if (pModel) pModel->TerrainRenderVBO(n);
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void __fastcall TAnimModel::Advanced()
|
||||
{//wykonanie zaawansowanych animacji na submodelach
|
||||
pAdvanced->fCurrent+=pAdvanced->fFrequency*Timer::GetDeltaTime(); //aktualna ramka zmiennoprzecinkowo
|
||||
int frame=floor(pAdvanced->fCurrent); //numer klatki jako int
|
||||
TAnimContainer *pCurrent;
|
||||
if (pAdvanced->fCurrent>=pAdvanced->fLast)
|
||||
{//animacja została zakończona
|
||||
delete pAdvanced;
|
||||
pAdvanced=NULL; //dalej już nic
|
||||
for (pCurrent=pRoot;pCurrent!=NULL;pCurrent=pCurrent->pNext)
|
||||
if (pCurrent->pMovementData) //jeśli obsługiwany tabelką animacji
|
||||
pCurrent->pMovementData=NULL; //usuwanie wskaźników
|
||||
}
|
||||
else
|
||||
{//coś trzeba poanimować - wszystkie animowane submodele są w tym łańcuchu
|
||||
for (pCurrent=pRoot;pCurrent!=NULL;pCurrent=pCurrent->pNext)
|
||||
if (pCurrent->pMovementData) //jeśli obsługiwany tabelką animacji
|
||||
if (frame>=pCurrent->pMovementData->iFrame) //koniec czekania
|
||||
if (!strcmp(pCurrent->pMovementData->cBone,(pCurrent->pMovementData+1)->cBone))
|
||||
{//jak kolejna ramka dotyczy tego samego submodelu, ustawić animację do kolejnej ramki
|
||||
++pCurrent->pMovementData; //kolejna klatka
|
||||
pCurrent->AnimSetVMD(pAdvanced->fFrequency/(double(pCurrent->pMovementData->iFrame)-pAdvanced->fCurrent));
|
||||
}
|
||||
else
|
||||
pCurrent->pMovementData=NULL; //inna nazwa, animowanie zakończone w aktualnym położeniu
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TAnimModel::AnimationVND(void* pData, double a, double b, double c, double d)
|
||||
{//rozpoczęcie wykonywania animacji z podanego pliku
|
||||
//tabela w pliku musi być posortowana wg klatek dla kolejnych kości!
|
||||
//skrócone nagranie ma 3:42 = 222 sekundy, animacja kończy się na klatce 6518
|
||||
//daje to 29.36 (~=30) klatek na sekundę
|
||||
//w opisach jest podawane 24 albo 36 jako standard => powiedzmy, parametr (d) to FPS animacji
|
||||
delete pAdvanced; //usunięcie ewentualnego poprzedniego
|
||||
pAdvanced=NULL; //gdyby się nie udało rozpoznać pliku
|
||||
if (AnsiString((char*)pData)=="Vocaloid Motion Data 0002")
|
||||
{
|
||||
pAdvanced=new TAnimAdvanced();
|
||||
pAdvanced->pVocaloidMotionData=(char*)pData; //podczepienie pliku danych
|
||||
pAdvanced->iMovements=*((int*)(((char*)pData)+50)); //numer ostatniej klatki
|
||||
pAdvanced->pMovementData=(TAnimVocaloidFrame*)(((char*)pData)+54); //rekordy animacji
|
||||
//WriteLog(sizeof(TAnimVocaloidFrame));
|
||||
pAdvanced->fFrequency=d;
|
||||
pAdvanced->fCurrent=0.0; //aktualna ramka
|
||||
pAdvanced->fLast=0.0; //ostatnia ramka
|
||||
/*
|
||||
if (0) //jeśli włączone sortowanie plików VMD (trochę się przeciąga)
|
||||
if (pAdvanced->SortByBone()) //próba posortowania
|
||||
{//zapisać posortowany plik, jeśli dokonano zmian
|
||||
TFileStream *fs=new TFileStream("models\\1.vmd",fmCreate);
|
||||
fs->Write(pData,2198342); //2948728);
|
||||
delete fs;
|
||||
}
|
||||
*/
|
||||
|
||||
int i,j,k,idx;
|
||||
AnsiString name;
|
||||
TAnimContainer *pSub;
|
||||
for (i=0;i<pAdvanced->iMovements;++i)
|
||||
{if (strcmp(pAdvanced->pMovementData[i].cBone,name.c_str()))
|
||||
{//jeśli pozycja w tabelce nie była wyszukiwana w submodelach
|
||||
pSub=GetContainer(pAdvanced->pMovementData[i].cBone); //szukanie
|
||||
if (pSub) //znaleziony
|
||||
{pSub->pMovementData=pAdvanced->pMovementData+i; //gotów do animowania
|
||||
pSub->AnimSetVMD(0.0); //usuawienie pozycji początkowej (powinna być zerowa, inaczej będzie skok)
|
||||
}
|
||||
name=AnsiString(pAdvanced->pMovementData[i].cBone); //nowa nazwa do pomijania
|
||||
}
|
||||
if (pAdvanced->fLast<pAdvanced->pMovementData[i].iFrame)
|
||||
pAdvanced->fLast=pAdvanced->pMovementData[i].iFrame;
|
||||
}
|
||||
/*
|
||||
for (i=0;i<pAdvanced->iMovements;++i)
|
||||
if (AnsiString(pAdvanced->pMovementData[i+1].cBone)!=AnsiString(pAdvanced->pMovementData[i].cBone))
|
||||
{//generowane dla ostatniej klatki danej kości
|
||||
name="";
|
||||
for (j=0;j<15;j++)
|
||||
name+=IntToHex((unsigned char)pAdvanced->pMovementData[i].cBone[j],2);
|
||||
WriteLog(name+","
|
||||
+AnsiString(pAdvanced->pMovementData[i].cBone)+","
|
||||
+AnsiString(idx)+"," //indeks
|
||||
+AnsiString(i+1-idx)+"," //ile pozycji animacji
|
||||
+AnsiString(k)+"," //pierwsza klatka
|
||||
+AnsiString(pAdvanced->pMovementData[i].iFrame)+"," //ostatnia klatka
|
||||
+AnsiString(pAdvanced->pMovementData[i].f3Vector.x)+","
|
||||
+AnsiString(pAdvanced->pMovementData[i].f3Vector.y)+","
|
||||
+AnsiString(pAdvanced->pMovementData[i].f3Vector.z)+","
|
||||
+AnsiString(pAdvanced->pMovementData[i].fAngle[0])+","
|
||||
+AnsiString(pAdvanced->pMovementData[i].fAngle[1])+","
|
||||
+AnsiString(pAdvanced->pMovementData[i].fAngle[2])+","
|
||||
+AnsiString(pAdvanced->pMovementData[i].fAngle[3])
|
||||
|
||||
);
|
||||
idx=i+1;
|
||||
k=pAdvanced->pMovementData[i+1].iFrame; //pierwsza klatka następnego
|
||||
}
|
||||
else
|
||||
if (pAdvanced->pMovementData[i].iFrame>0)
|
||||
if ((k>pAdvanced->pMovementData[i].iFrame)||(k==0))
|
||||
k=pAdvanced->pMovementData[i].iFrame; //pierwsza niezerowa ramka
|
||||
*/
|
||||
/*
|
||||
for (i=0;i<pAdvanced->iMovements;++i)
|
||||
if (AnsiString(pAdvanced->pMovementData[i].cBone)=="\x89\x45\x90\x65\x8E\x77\x82\x4F")
|
||||
{name="";
|
||||
for (j=0;j<15;j++)
|
||||
name+=IntToHex((unsigned char)pAdvanced->pMovementData[i].cBone[j],2);
|
||||
WriteLog(name+","
|
||||
+AnsiString(i)+"," //pozycja w tabeli
|
||||
+AnsiString(pAdvanced->pMovementData[i].iFrame)+"," //pierwsza klatka
|
||||
);
|
||||
}
|
||||
*/
|
||||
}
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TAnimModel::LightSet(int n,float v)
|
||||
{//ustawienie światła (n) na wartość (v)
|
||||
if (n>=iMaxNumLights) return; //przekroczony zakres
|
||||
lsLights[n]=TLightState(int(v));
|
||||
switch (lsLights[n])
|
||||
{//interpretacja ułamka zależnie od typu
|
||||
case 0: //ustalenie czasu migotania, t<1s (f>1Hz), np. 0.1 => t=0.1 (f=10Hz)
|
||||
break;
|
||||
case 1: //ustalenie wypełnienia ułamkiem, np. 1.25 => zapalony przez 1/4 okresu
|
||||
break;
|
||||
case 2: //ustalenie częstotliwości migotania, f<1Hz (t>1s), np. 2.2 => f=0.2Hz (t=5s)
|
||||
break;
|
||||
case 3: //zapalenie świateł zależne od oświetlenia scenerii
|
||||
if (v>3.0)
|
||||
fDark=v-3.0; //ustawienie indywidualnego progu zapalania
|
||||
else
|
||||
fDark=0.25; //standardowy próg zaplania
|
||||
break;
|
||||
}
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
void __fastcall TAnimModel::AnimUpdate(double dt)
|
||||
{//wykonanie zakolejkowanych animacji, nawet gdy modele nie są aktualnie wyświetlane
|
||||
TAnimContainer *p=TAnimModel::acAnimList;
|
||||
while (p)
|
||||
{//jeśli w ogóle jest co animować
|
||||
//if ((*p)->fTranslateSpeed==0.0)
|
||||
// if ((*p)->fRotateSpeed==0.0)
|
||||
// {//jak się naanimował, to usunąć z listy
|
||||
// *p=(*p)->ListRemove(); //zwraca wskaźnik do kolejnego z listy
|
||||
// }
|
||||
p->UpdateModel();
|
||||
p=p->acAnimNext; //na razie bez usuwania z listy, bo głównie obrotnica na nią wchodzi
|
||||
}
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
148
AnimModel.h
Normal file
148
AnimModel.h
Normal file
@@ -0,0 +1,148 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef AnimModelH
|
||||
#define AnimModelH
|
||||
|
||||
#include "Model3d.h"
|
||||
|
||||
const int iMaxNumLights=8;
|
||||
|
||||
//typy stanu œwiate³
|
||||
typedef enum {
|
||||
ls_Off=0, //zgaszone
|
||||
ls_On=1, //zapalone
|
||||
ls_Blink=2, //migaj¹ce
|
||||
ls_Dark=3 //Ra: zapalajce siê automatycznie, gdy zrobi siê ciemno
|
||||
} TLightState;
|
||||
|
||||
class TAnimVocaloidFrame
|
||||
{//ramka animacji typu Vocaloid Motion Data z programu MikuMikuDance
|
||||
public:
|
||||
char cBone[15]; //nazwa koœci, mo¿e byæ po japoñsku
|
||||
int iFrame; //numer ramki
|
||||
float3 f3Vector; //przemieszczenie
|
||||
float4 qAngle; //kwaternion obrotu
|
||||
char cBezier[64]; //krzywe Béziera do interpolacji dla x,y,z i obrotu
|
||||
};
|
||||
|
||||
class TEvent;
|
||||
|
||||
class TAnimContainer
|
||||
{//opakowanie submodelu, okreœlaj¹ce animacjê egzemplarza - obs³ugiwane jako lista
|
||||
friend class TAnimModel;
|
||||
private:
|
||||
vector3 vRotateAngles; //dla obrotów Eulera
|
||||
vector3 vDesiredAngles;
|
||||
double fRotateSpeed;
|
||||
vector3 vTranslation;
|
||||
vector3 vTranslateTo;
|
||||
double fTranslateSpeed; //mo¿e tu daæ wektor?
|
||||
float4 qCurrent; //aktualny interpolowany
|
||||
float4 qStart; //pozycja pocz¹tkowa (0 dla interpolacji)
|
||||
float4 qDesired; //pozycja koñcowa (1 dla interpolacji)
|
||||
float fAngleCurrent; //parametr interpolacyjny: 0=start, 1=docelowy
|
||||
float fAngleSpeed; //zmiana parametru interpolacji w sekundach
|
||||
TSubModel *pSubModel;
|
||||
float4x4 *mAnim; //macierz do animacji kwaternionowych
|
||||
//dla kinematyki odwróconej u¿ywane s¹ kwaterniony
|
||||
float fLength; //d³ugoœæ koœci dla IK
|
||||
int iAnim; //animacja: +1-obrót Eulera, +2-przesuw, +4-obrót kwaternionem, +8-IK
|
||||
//+0x80000000: animacja z eventem, wykonywana poza wyœwietlaniem
|
||||
//+0x100: pierwszy stopieñ IK - obróciæ w stronê pierwszego potomnego (dziecka)
|
||||
//+0x200: drugi stopieñ IK - dostosowaæ do pozycji potomnego potomnego (wnuka)
|
||||
union
|
||||
{//mog¹ byæ animacje klatkowe ró¿nego typu, wskaŸniki u¿ywa AnimModel
|
||||
TAnimVocaloidFrame *pMovementData; //wskaŸnik do klatki
|
||||
};
|
||||
TEvent *evDone; //ewent wykonywany po zakoñczeniu animacji, np. zapór, obrotnicy
|
||||
public:
|
||||
TAnimContainer *pNext;
|
||||
TAnimContainer *acAnimNext; //lista animacji z eventem, które musz¹ byæ przeliczane równie¿ bez wyœwietlania
|
||||
__fastcall TAnimContainer();
|
||||
__fastcall ~TAnimContainer();
|
||||
bool __fastcall Init(TSubModel *pNewSubModel);
|
||||
//std::string inline __fastcall GetName() { return std::string(pSubModel?pSubModel->asName.c_str():""); };
|
||||
//std::string inline __fastcall GetName() { return std::string(pSubModel?pSubModel->pName:""); };
|
||||
char* __fastcall NameGet() {return (pSubModel?pSubModel->pName:NULL);};
|
||||
//void __fastcall SetRotateAnim(vector3 vNewRotateAxis, double fNewDesiredAngle, double fNewRotateSpeed, bool bResetAngle=false);
|
||||
void __fastcall SetRotateAnim(vector3 vNewRotateAngles, double fNewRotateSpeed);
|
||||
void __fastcall SetTranslateAnim(vector3 vNewTranslate, double fNewSpeed);
|
||||
void __fastcall AnimSetVMD(double fNewSpeed);
|
||||
void __fastcall PrepareModel();
|
||||
void __fastcall UpdateModel();
|
||||
void __fastcall UpdateModelIK();
|
||||
bool __fastcall InMovement(); //czy w trakcie animacji?
|
||||
double _fastcall AngleGet() {return vRotateAngles.z;}; //jednak ostatnia, T3D ma inny uk³ad
|
||||
vector3 _fastcall TransGet() {return vector3(-vTranslation.x,vTranslation.z,vTranslation.y);}; //zmiana, bo T3D ma inny uk³ad
|
||||
void __fastcall WillBeAnimated() {if (pSubModel) pSubModel->WillBeAnimated();};
|
||||
void __fastcall EventAssign(TEvent *ev);
|
||||
TEvent* __fastcall Event() {return evDone;};
|
||||
};
|
||||
|
||||
class TAnimAdvanced
|
||||
{//obiekt zaawansowanej animacji submodelu
|
||||
public:
|
||||
TAnimVocaloidFrame *pMovementData;
|
||||
unsigned char *pVocaloidMotionData; //plik animacyjny dla egzemplarza (z eventu)
|
||||
double fFrequency; //przeliczenie czasu rzeczywistego na klatki animacji
|
||||
double fCurrent; //klatka animacji wyœwietlona w poprzedniej klatce renderingu
|
||||
double fLast; //klatka koñcz¹ca animacjê
|
||||
int iMovements;
|
||||
__fastcall TAnimAdvanced();
|
||||
__fastcall ~TAnimAdvanced();
|
||||
int __fastcall SortByBone();
|
||||
};
|
||||
|
||||
class TAnimModel
|
||||
{//opakowanie modelu, okreœlaj¹ce stan egzemplarza
|
||||
private:
|
||||
TAnimContainer *pRoot; //pojemniki steruj¹ce, tylko dla aniomowanych submodeli
|
||||
TModel3d *pModel;
|
||||
double fBlinkTimer;
|
||||
int iNumLights;
|
||||
TSubModel *LightsOn[iMaxNumLights]; //Ra: te wskaŸniki powinny byæ w ramach TModel3d
|
||||
TSubModel *LightsOff[iMaxNumLights];
|
||||
vector3 vAngle; //bazowe obroty egzemplarza wzglêdem osi
|
||||
int iTexAlpha; //¿eby nie sprawdzaæ za ka¿dym razem, dla 4 wymiennych tekstur
|
||||
AnsiString asText; //tekst dla wyœwietlacza znakowego
|
||||
TAnimAdvanced *pAdvanced;
|
||||
void __fastcall Advanced();
|
||||
TLightState lsLights[iMaxNumLights];
|
||||
float fDark; //poziom zapalanie œwiat³a (powinno byæ chyba powi¹zane z danym œwiat³em?)
|
||||
float fOnTime,fOffTime; //by³y sta³ymi, teraz mog¹ byæ zmienne dla ka¿dego egzemplarza
|
||||
private:
|
||||
void __fastcall RaAnimate(); //przeliczenie animacji egzemplarza
|
||||
void __fastcall RaPrepare(); //ustawienie animacji egzemplarza na wzorcu
|
||||
public:
|
||||
GLuint ReplacableSkinId[5]; //McZapkie-020802: zmienialne skory
|
||||
static TAnimContainer *acAnimList; //lista animacji z eventem, które musz¹ byæ przeliczane równie¿ bez wyœwietlania
|
||||
__fastcall TAnimModel();
|
||||
__fastcall ~TAnimModel();
|
||||
bool __fastcall Init(TModel3d *pNewModel);
|
||||
bool __fastcall Init(AnsiString asName,AnsiString asReplacableTexture);
|
||||
bool __fastcall Load(cParser *parser, bool ter=false);
|
||||
TAnimContainer* __fastcall AddContainer(char *pName);
|
||||
TAnimContainer* __fastcall GetContainer(char *pName);
|
||||
void __fastcall RenderDL(vector3 pPosition=vector3(0,0,0),double fAngle=0);
|
||||
void __fastcall RenderAlphaDL(vector3 pPosition=vector3(0,0,0),double fAngle=0);
|
||||
void __fastcall RenderVBO(vector3 pPosition=vector3(0,0,0),double fAngle=0);
|
||||
void __fastcall RenderAlphaVBO(vector3 pPosition=vector3(0,0,0),double fAngle=0);
|
||||
void __fastcall RenderDL(vector3* vPosition);
|
||||
void __fastcall RenderAlphaDL(vector3* vPosition);
|
||||
void __fastcall RenderVBO(vector3* vPosition);
|
||||
void __fastcall RenderAlphaVBO(vector3* vPosition);
|
||||
int __fastcall Flags();
|
||||
void __fastcall RaAnglesSet(double a,double b,double c)
|
||||
{vAngle.x=a; vAngle.y=b; vAngle.z=c;};
|
||||
bool __fastcall TerrainLoaded();
|
||||
int __fastcall TerrainCount();
|
||||
TSubModel* __fastcall TerrainSquare(int n);
|
||||
void __fastcall TerrainRenderVBO(int n);
|
||||
void __fastcall AnimationVND(void* pData, double a, double b, double c, double d);
|
||||
void __fastcall LightSet(int n,float v);
|
||||
static void __fastcall AnimUpdate(double dt);
|
||||
};
|
||||
TAnimContainer *TAnimModel::acAnimList=NULL;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
70
Button.cpp
Normal file
70
Button.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Button.h"
|
||||
#include "Console.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
|
||||
__fastcall TButton::TButton()
|
||||
{
|
||||
iFeedbackBit=0;
|
||||
Clear();
|
||||
};
|
||||
|
||||
__fastcall TButton::~TButton()
|
||||
{
|
||||
};
|
||||
|
||||
void __fastcall TButton::Clear(int i)
|
||||
{
|
||||
pModelOn=NULL;
|
||||
pModelOff=NULL;
|
||||
bOn=false;
|
||||
if (i>=0) FeedbackBitSet(i);
|
||||
Update(); //kasowanie bitu Feedback, o ile jakiœ ustawiony
|
||||
};
|
||||
|
||||
void __fastcall TButton::Init(AnsiString asName,TModel3d *pModel,bool bNewOn)
|
||||
{
|
||||
if (!pModel) return; //nie ma w czym szukaæ
|
||||
pModelOn=pModel->GetFromName(AnsiString(asName+"_on").c_str());
|
||||
pModelOff=pModel->GetFromName(AnsiString(asName+"_off").c_str());
|
||||
bOn=bNewOn;
|
||||
Update();
|
||||
};
|
||||
|
||||
void __fastcall TButton::Load(TQueryParserComp *Parser,TModel3d *pModel1,TModel3d *pModel2)
|
||||
{
|
||||
AnsiString str=Parser->GetNextSymbol().LowerCase();
|
||||
if (pModel1)
|
||||
{//poszukiwanie submodeli w modelu
|
||||
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)
|
||||
}
|
||||
else
|
||||
{
|
||||
pModelOn=NULL;
|
||||
pModelOff=NULL;
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TButton::Update()
|
||||
{
|
||||
if (pModelOn) pModelOn->iVisible=bOn;
|
||||
if (pModelOff) pModelOff->iVisible=!bOn;
|
||||
if (iFeedbackBit) //je¿eli generuje informacjê zwrotn¹
|
||||
{if (bOn) //zapalenie
|
||||
Console::BitsSet(iFeedbackBit);
|
||||
else
|
||||
Console::BitsClear(iFeedbackBit);
|
||||
}
|
||||
};
|
||||
|
||||
31
Button.h
Normal file
31
Button.h
Normal file
@@ -0,0 +1,31 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef ButtonH
|
||||
#define ButtonH
|
||||
|
||||
#include "Model3d.h"
|
||||
#include "QueryParserComp.hpp"
|
||||
|
||||
class TButton
|
||||
{//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;
|
||||
int iFeedbackBit; //Ra: bit informacji zwrotnej, do wyprowadzenia na pulpit
|
||||
void __fastcall Update();
|
||||
public:
|
||||
__fastcall TButton();
|
||||
__fastcall ~TButton();
|
||||
void __fastcall Clear(int i=-1);
|
||||
inline void FeedbackBitSet(int i) {iFeedbackBit=1<<i;};
|
||||
inline void Turn(bool to) { bOn=to; Update(); };
|
||||
inline void TurnOn() { bOn=true; Update(); };
|
||||
inline void TurnOff() { bOn=false; Update(); };
|
||||
inline void Switch() { bOn=!bOn; Update(); };
|
||||
inline bool Active() { return (pModelOn)||(pModelOff);};
|
||||
void __fastcall Init(AnsiString asName,TModel3d *pModel,bool bNewOn=false);
|
||||
void __fastcall Load(TQueryParserComp *Parser,TModel3d *pModel1,TModel3d *pModel2=NULL);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
196
Camera.cpp
Normal file
196
Camera.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
|
||||
#include "opengl/glew.h"
|
||||
#include "opengl/glut.h"
|
||||
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Camera.h"
|
||||
#include "Usefull.h"
|
||||
#include "Globals.h"
|
||||
#include "Timer.h"
|
||||
#include "mover.h"
|
||||
#include "Console.h"
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
|
||||
//TViewPyramid TCamera::OrgViewPyramid;
|
||||
//={vector3(-1,1,1),vector3(1,1,1),vector3(-1,-1,1),vector3(1,-1,1),vector3(0,0,0)};
|
||||
|
||||
const vector3 OrgCrossPos= vector3(0,-10,0);
|
||||
|
||||
void __fastcall TCamera::Init(vector3 NPos, vector3 NAngle)
|
||||
{
|
||||
|
||||
pOffset= vector3(-0.0,0,0);
|
||||
vUp= vector3(0,1,0);
|
||||
// pOffset= vector3(-0.8,0,0);
|
||||
CrossPos= OrgCrossPos;
|
||||
CrossDist= 10;
|
||||
Velocity=vector3(0,0,0);
|
||||
OldVelocity= vector3(0,0,0);
|
||||
Pitch= NAngle.x;
|
||||
Yaw= NAngle.y;
|
||||
Roll= NAngle.z;
|
||||
Pos= NPos;
|
||||
|
||||
// Type= tp_Follow;
|
||||
Type= (Global::bFreeFly ? tp_Free : tp_Follow);
|
||||
// Type= tp_Free;
|
||||
};
|
||||
|
||||
void __fastcall TCamera::OnCursorMove(double x, double y)
|
||||
{
|
||||
//McZapkie-170402: zeby mysz dzialala zawsze if (Type==tp_Follow)
|
||||
Pitch+=y;
|
||||
Yaw+=-x;
|
||||
if (Yaw>M_PI)
|
||||
Yaw-=2*M_PI;
|
||||
else if (Yaw<-M_PI)
|
||||
Yaw+=2*M_PI;
|
||||
if (Type==tp_Follow) //je¿eli jazda z pojazdem
|
||||
{
|
||||
Fix(Pitch,-M_PI_4,M_PI_4); //ograniczenie k¹ta spogl¹dania w dó³ i w górê
|
||||
//Fix(Yaw,-M_PI,M_PI);
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall TCamera::Update()
|
||||
{
|
||||
//ABu: zmiana i uniezaleznienie predkosci od FPS
|
||||
double a= (Console::Pressed(VK_SHIFT)?5.00:1.00);
|
||||
if (Console::Pressed(VK_CONTROL))
|
||||
a=a*100;
|
||||
// OldVelocity=Velocity;
|
||||
if (FreeFlyModeFlag==true)
|
||||
Type=tp_Free;
|
||||
else
|
||||
Type=tp_Follow;
|
||||
if (Type==tp_Free)
|
||||
{
|
||||
if (Console::Pressed(Global::Keys[k_MechUp])) Velocity.y+=a;
|
||||
if (Console::Pressed(Global::Keys[k_MechDown])) Velocity.y-=a;
|
||||
//McZapkie-170402: zeby nie bylo konfliktow
|
||||
/*
|
||||
if (Console::Pressed(VkKeyScan('d')))
|
||||
Velocity.x+= a*Timer::GetDeltaTime();
|
||||
if (Console::Pressed(VkKeyScan('a')))
|
||||
Velocity.x-= a*Timer::GetDeltaTime();
|
||||
if (Console::Pressed(VkKeyScan('w')))
|
||||
Velocity.z-= a*Timer::GetDeltaTime();
|
||||
if (Console::Pressed(VkKeyScan('s')))
|
||||
Velocity.z+= a*Timer::GetDeltaTime();
|
||||
|
||||
if (Console::Pressed(VK_NUMPAD4) || Console::Pressed(VK_NUMPAD7) || Console::Pressed(VK_NUMPAD1))
|
||||
Yaw+= +1*M_PI*Timer::GetDeltaTime();
|
||||
|
||||
if (Console::Pressed(VK_NUMPAD6) || Console::Pressed(VK_NUMPAD9) || Console::Pressed(VK_NUMPAD3))
|
||||
Yaw+= -1*M_PI*Timer::GetDeltaTime();
|
||||
|
||||
if (Pressed(VK_NUMPAD2) || Console::Pressed(VK_NUMPAD1) || Console::Pressed(VK_NUMPAD3))
|
||||
Pitch+= -1*M_PI*Timer::GetDeltaTime();
|
||||
|
||||
if (Console::Pressed(VK_NUMPAD8) || Console::Pressed(VK_NUMPAD7) || Console::Pressed(VK_NUMPAD9))
|
||||
Pitch+= +1*M_PI*Timer::GetDeltaTime();
|
||||
if (Console::Pressed(VkKeyScan('.')))
|
||||
Roll+= -1*M_PI*Timer::GetDeltaTime();
|
||||
if (Console::Pressed(VkKeyScan(',')))
|
||||
Roll+= +1*M_PI*Timer::GetDeltaTime();
|
||||
|
||||
if (Console::Pressed(VK_NUMPAD5))
|
||||
Pitch=Roll= 0.0f;
|
||||
*/
|
||||
|
||||
//McZapkie-170402: poruszanie i rozgladanie we free takie samo jak w follow
|
||||
if (Console::Pressed(Global::Keys[k_MechRight])) Velocity.x+=a;
|
||||
if (Console::Pressed(Global::Keys[k_MechLeft])) Velocity.x-=a;
|
||||
if (Console::Pressed(Global::Keys[k_MechForward])) Velocity.z-=a;
|
||||
if (Console::Pressed(Global::Keys[k_MechBackward])) Velocity.z+=a;
|
||||
//gora-dol
|
||||
//if (Console::Pressed(VK_NUMPAD9)) Pos.y+=0.1;
|
||||
//if (Console::Pressed(VK_NUMPAD3)) Pos.y-=0.1;
|
||||
|
||||
//McZapkie: zeby nie hustalo przy malym FPS:
|
||||
// Velocity= (Velocity+OldVelocity)/2;
|
||||
// matrix4x4 mat;
|
||||
vector3 Vec=Velocity;
|
||||
Vec.RotateY(Yaw);
|
||||
Pos=Pos+Vec*Timer::GetDeltaRenderTime(); //czas bez pauzy
|
||||
Velocity=Velocity/2; //p³ynne hamowanie ruchu
|
||||
// double tmp= 10*DeltaTime;
|
||||
// Velocity+= -Velocity*10 * Timer::GetDeltaTime();//( tmp<1 ? tmp : 1 );
|
||||
// Type= tp_Free;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vector3 __fastcall TCamera::GetDirection()
|
||||
{
|
||||
matrix4x4 mat;
|
||||
vector3 Vec;
|
||||
Vec= vector3(0,0,1);
|
||||
Vec.RotateY(Yaw);
|
||||
|
||||
return (Normalize(Vec));
|
||||
}
|
||||
|
||||
//bool __fastcall TCamera::GetMatrix(matrix4x4 &Matrix)
|
||||
bool __fastcall TCamera::SetMatrix()
|
||||
{
|
||||
glRotated(-Roll*180.0f/M_PI,0,0,1); //po wy³¹czeniu tego krêci siê pojazd, a sceneria nie
|
||||
glRotated(-Pitch*180.0f/M_PI,1,0,0);
|
||||
glRotated(-Yaw*180.0f/M_PI,0,1,0); //w zewnêtrznym widoku: kierunek patrzenia
|
||||
|
||||
if (Type==tp_Follow)
|
||||
{
|
||||
// gluLookAt(Pos.x+pOffset.x,Pos.y+pOffset.y,Pos.z+pOffset.z,
|
||||
// LookAt.x+pOffset.x,LookAt.y+pOffset.y,LookAt.z+pOffset.z,vUp.x,vUp.y,vUp.z);
|
||||
// gluLookAt(Pos.x+pOffset.x,Pos.y+pOffset.y,Pos.z+pOffset.z,
|
||||
// LookAt.x+pOffset.x,LookAt.y+pOffset.y,LookAt.z+pOffset.z,vUp.x,vUp.y,vUp.z);
|
||||
gluLookAt(Pos.x,Pos.y,Pos.z,LookAt.x,LookAt.y,LookAt.z,vUp.x,vUp.y,vUp.z); //Ra: pOffset is zero
|
||||
// gluLookAt(Pos.x,Pos.y,Pos.z,Pos.x+Velocity.x,Pos.y+Velocity.y,Pos.z+Velocity.z,0,1,0);
|
||||
// return true;
|
||||
}
|
||||
|
||||
if (Type==tp_Satelite)
|
||||
Pitch= M_PI*0.5;
|
||||
|
||||
if (Type!=tp_Follow)
|
||||
{
|
||||
glTranslated(-Pos.x,-Pos.y,-Pos.z); //nie zmienia kierunku patrzenia
|
||||
}
|
||||
|
||||
Global::SetCameraPosition(Pos); //by³o +pOffset
|
||||
return true;
|
||||
}
|
||||
|
||||
void __fastcall TCamera::SetCabMatrix(vector3 &p)
|
||||
{//ustawienie widoku z kamery bez przesuniêcia robionego przez OpenGL - nie powinno tak trz¹œæ
|
||||
glRotated(-Roll*180.0f/M_PI,0,0,1);
|
||||
glRotated(-Pitch*180.0f/M_PI,1,0,0);
|
||||
glRotated(-Yaw*180.0f/M_PI,0,1,0); //w zewnêtrznym widoku: kierunek patrzenia
|
||||
if (Type==tp_Follow)
|
||||
gluLookAt(Pos.x-p.x,Pos.y-p.y,Pos.z-p.z,LookAt.x-p.x,LookAt.y-p.y,LookAt.z-p.z,vUp.x,vUp.y,vUp.z); //Ra: pOffset is zero
|
||||
}
|
||||
|
||||
void __fastcall TCamera::RaLook()
|
||||
{//zmiana kierunku patrzenia - przelicza Yaw
|
||||
vector3 where=LookAt-Pos+vector3(0,3,0); //trochê w górê od szyn
|
||||
if ((where.x!=0.0)||(where.z!=0.0))
|
||||
Yaw=atan2(-where.x,-where.z); //k¹t horyzontalny
|
||||
double l=Length3(where);
|
||||
if (l>0.0)
|
||||
Pitch=asin(where.y/l); //k¹t w pionie
|
||||
};
|
||||
|
||||
void __fastcall TCamera::Stop()
|
||||
{//wy³¹cznie bezw³adnego ruchu po powrocie do kabiny
|
||||
Type=tp_Follow;
|
||||
Velocity=vector3(0,0,0);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
47
Camera.h
Normal file
47
Camera.h
Normal file
@@ -0,0 +1,47 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef CameraH
|
||||
#define CameraH
|
||||
|
||||
|
||||
#include "dumb3d.h"
|
||||
using namespace Math3D;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
enum TCameraType
|
||||
{//tryby pracy kamery
|
||||
tp_Follow, //jazda z pojazdem
|
||||
tp_Free, //stoi na scenerii
|
||||
tp_Satelite //widok z góry (nie używany)
|
||||
};
|
||||
|
||||
class TCamera
|
||||
{
|
||||
private:
|
||||
vector3 pOffset; //nie używane (zerowe)
|
||||
public: //McZapkie: potrzebuje do kiwania na boki
|
||||
double Pitch;
|
||||
double Yaw; //w środku: 0=do przodu; na zewnątrz: 0=na południe
|
||||
double Roll;
|
||||
TCameraType Type;
|
||||
vector3 Pos; //współrzędne obserwatora
|
||||
vector3 LookAt; //współrzędne punktu, na który ma patrzeć
|
||||
vector3 vUp;
|
||||
vector3 Velocity;
|
||||
vector3 OldVelocity; //lepiej usredniac zeby nie bylo rozbiezne przy malym FPS
|
||||
vector3 CrossPos;
|
||||
double CrossDist;
|
||||
void __fastcall Init(vector3 NPos, vector3 NAngle);
|
||||
void __fastcall Reset() { Pitch=Yaw=Roll= 0; };
|
||||
void __fastcall OnCursorMove(double x, double y);
|
||||
void __fastcall Update();
|
||||
vector3 __fastcall GetDirection();
|
||||
//vector3 inline __fastcall GetCrossPos() { return Pos+GetDirection()*CrossDist+CrossPos; };
|
||||
|
||||
bool __fastcall SetMatrix();
|
||||
void __fastcall SetCabMatrix(vector3 &p);
|
||||
void __fastcall RaLook();
|
||||
void __fastcall Stop();
|
||||
//bool __fastcall GetMatrix(matrix4x4 &Matrix);
|
||||
vector3 PtNext, PtPrev;
|
||||
};
|
||||
#endif
|
||||
10
Classes.cpp
Normal file
10
Classes.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <vcl.h>
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Classes.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
54
Classes.h
Normal file
54
Classes.h
Normal file
@@ -0,0 +1,54 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef ClassesH
|
||||
#define ClassesH
|
||||
//---------------------------------------------------------------------------
|
||||
//Ra: zestaw klas do robienia wskaźników, aby uporządkować nagłówki
|
||||
//---------------------------------------------------------------------------
|
||||
class TTrack; //odcinek trajektorii
|
||||
class TEvent;
|
||||
class TTrain; //pojazd sterowany
|
||||
class TDynamicObject; //pojazd w scenerii
|
||||
class TGroundNode; //statyczny obiekt scenerii
|
||||
class TAnimModel; //opakowanie egzemplarz modelu
|
||||
class TAnimContainer; //fragment opakowania egzemplarza modelu
|
||||
//class TModel3d; //siatka modelu wspólna dla egzemplarzy
|
||||
class TSubModel; //fragment modelu (tu do wyświetlania terenu)
|
||||
class TMemCell; //komórka pamięci
|
||||
class cParser;
|
||||
class TRealSound; //dźwięk ze współrzędnymi XYZ
|
||||
class TTextSound; //dźwięk ze stenogramem
|
||||
class TEventLauncher;
|
||||
class TTraction; //drut
|
||||
class TTractionPowerSource; //zasilanie drutów
|
||||
|
||||
class TMoverParameters;
|
||||
namespace _mover
|
||||
{
|
||||
class TLocation;
|
||||
class TRotation;
|
||||
};
|
||||
|
||||
namespace Mtable
|
||||
{
|
||||
class TTrainParameters; //rozkład jazdy
|
||||
};
|
||||
|
||||
class TController; //obiekt sterujący pociągiem (AI)
|
||||
class TNames; //obiekt sortujący nazwy
|
||||
|
||||
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_ChangeDirection,
|
||||
cm_PassengerStopPoint,
|
||||
cm_OutsideStation,
|
||||
cm_Shunt,
|
||||
cm_Command //komenda pobierana z komórki
|
||||
} TCommandType;
|
||||
|
||||
#endif
|
||||
347
Console.cpp
Normal file
347
Console.cpp
Normal file
@@ -0,0 +1,347 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <vcl.h>
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Console.h"
|
||||
#include "Globals.h"
|
||||
#include "Logs.h"
|
||||
#include "PoKeys55.h"
|
||||
#include "LPT.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
//Ra: klasa statyczna gromadząca sygnały sterujące oraz informacje zwrotne
|
||||
//Ra: stan wejścia zmieniany klawiaturą albo dedykowanym urządzeniem
|
||||
//Ra: stan wyjścia zmieniany przez symulację (mierniki, kontrolki)
|
||||
|
||||
/*******************************
|
||||
Do klawisza klawiatury przypisana jest maska bitowa oraz numer wejścia.
|
||||
Naciśnięcie klawisza powoduje wywołanie procedury ustawienia bitu o podanej
|
||||
masce na podanym wejściu. Zwonienie klawisza analogicznie wywołuje zerowanie
|
||||
bitu wg maski. Zasadniczo w masce ustawiony jest jeden bit, ale w razie
|
||||
potrzeby może być ich więcej.
|
||||
|
||||
Oddzielne wejścia są wprowadzone po to, by można było używać więcej niż 32
|
||||
bity do sterowania. Podział na wejścia jest również ze względów organizacyjnych,
|
||||
np. sterowanie światłami może mieć oddzielny numer wejścia niż przełączanie
|
||||
radia, ponieważ nie ma potrzeby ich uzależniać (tzn. badać wspólną maskę bitową).
|
||||
|
||||
Do każdego wejścia podpięty jest skrypt binarny, charakterystyczny dla danej
|
||||
konstrukcji pojazdu. Sprawdza on zależności (w tym uszkodzenia) za pomocą
|
||||
operacji logicznych na maskach bitowych. Do każdego wejścia jest przypisana
|
||||
jedna, oddzielna maska 32 bit, ale w razie potrzeby istnieje też możliwość
|
||||
korzystania z masek innych wejść. Skrypt może też wysyłać maski na inne wejścia,
|
||||
ale należy unikać rekurencji.
|
||||
|
||||
Definiowanie wejść oraz przeznaczenia ich masek jest w gestii konstruktora
|
||||
skryptu. Każdy pojazd może mieć inny schemat wejść i masek, ale w miarę możliwości
|
||||
należy dążyć do unifikacji. Skrypty mogą również używać dodatkowych masek bitowych.
|
||||
Maski bitowe odpowiadają stanom przełączników, czujników, styczników itd.
|
||||
|
||||
Działanie jest następujące:
|
||||
- na klawiaturze konsoli naciskany jest przycisk
|
||||
- naciśnięcie przycisku zamieniane jest na maskę bitową oraz numer wejścia
|
||||
- wywoływany jest skrypt danego wejścia z ową maską
|
||||
- skrypt sprawdza zależności i np. modyfikuje własności fizyki albo inne maski
|
||||
- ewentualnie do wyzwalacza czasowego dodana jest maska i numer wejścia
|
||||
|
||||
/*******************************/
|
||||
|
||||
/* //kod do przetrawienia:
|
||||
//aby się nie włączacz wygaszacz ekranu, co jakiś czas naciska się wirtualnie ScrollLock
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
|
||||
|
||||
private static void PressScrollLock()
|
||||
{//przyciska i zwalnia ScrollLock
|
||||
const byte vkScroll = 0x91;
|
||||
const byte keyeventfKeyup = 0x2;
|
||||
keybd_event(vkScroll, 0x45, 0, (UIntPtr)0);
|
||||
keybd_event(vkScroll, 0x45, keyeventfKeyup, (UIntPtr)0);
|
||||
};
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool SystemParametersInfo(int uAction,int uParam,int &lpvParam,int flags);
|
||||
|
||||
public static Int32 GetScreenSaverTimeout()
|
||||
{
|
||||
Int32 value=0;
|
||||
SystemParametersInfo(14,0,&value,0);
|
||||
return value;
|
||||
};
|
||||
*/
|
||||
|
||||
//Ra: do poprawienia
|
||||
void SetLedState(char Code,bool bOn)
|
||||
{//Ra: bajer do migania LED-ami w klawiaturze
|
||||
if (Win32Platform==VER_PLATFORM_WIN32_NT)
|
||||
{
|
||||
//WriteLog(AnsiString(int(GetAsyncKeyState(Code))));
|
||||
if (bool(GetAsyncKeyState(Code))!=bOn)
|
||||
{
|
||||
keybd_event(Code,MapVirtualKey(Code,0),KEYEVENTF_EXTENDEDKEY,0);
|
||||
keybd_event(Code,MapVirtualKey(Code,0),KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP,0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TKeyboardState KBState;
|
||||
GetKeyboardState(KBState);
|
||||
KBState[Code]=bOn?1:0;
|
||||
SetKeyboardState(KBState);
|
||||
};
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int Console::iBits=0; //zmienna statyczna - obiekt Console jest jednen wspólny
|
||||
int Console::iMode=0;
|
||||
int Console::iConfig=0;
|
||||
TPoKeys55 *Console::PoKeys55[2]={NULL,NULL};
|
||||
TLPT *Console::LPT=NULL;
|
||||
int Console::iSwitch[8]; //bistabilne w kabinie, załączane z [Shift], wyłączane bez
|
||||
int Console::iButton[8]; //monostabilne w kabinie, załączane podczas trzymania klawisza
|
||||
|
||||
__fastcall Console::Console()
|
||||
{
|
||||
PoKeys55[0]=PoKeys55[1]=NULL;
|
||||
for (int i=0;i<8;++i)
|
||||
{//zerowanie przełączników
|
||||
iSwitch[i]=0; //bity 0..127 - bez [Ctrl], 128..255 - z [Ctrl]
|
||||
iButton[i]=0; //bity 0..127 - bez [Shift], 128..255 - z [Shift]
|
||||
}
|
||||
};
|
||||
|
||||
__fastcall Console::~Console()
|
||||
{
|
||||
delete PoKeys55[0];
|
||||
delete PoKeys55[1];
|
||||
};
|
||||
|
||||
void __fastcall Console::ModeSet(int m,int h)
|
||||
{//ustawienie trybu pracy
|
||||
iMode=m;
|
||||
iConfig=h;
|
||||
};
|
||||
|
||||
int __fastcall Console::On()
|
||||
{//załączenie konsoli (np. nawiązanie komunikacji)
|
||||
iSwitch[0]=iSwitch[1]=iSwitch[2]=iSwitch[3]=0; //bity 0..127 - bez [Ctrl]
|
||||
iSwitch[4]=iSwitch[5]=iSwitch[6]=iSwitch[7]=0; //bity 128..255 - z [Ctrl]
|
||||
switch (iMode)
|
||||
{case 1: //kontrolki klawiatury
|
||||
case 2: //kontrolki klawiatury
|
||||
iConfig=0; //licznik użycia Scroll Lock
|
||||
break;
|
||||
case 3: //LPT
|
||||
LPT=new TLPT(); //otwarcie inpout32.dll
|
||||
if (LPT?LPT->Connect(iConfig):false)
|
||||
{//wysłać 0?
|
||||
BitsUpdate(-1); //aktualizacjia stanów, bo przy wczytywaniu mogło być nieaktywne
|
||||
WriteLog("Feedback Mode 3: InpOut32.dll OK");
|
||||
}
|
||||
else
|
||||
{//połączenie nie wyszło, ma być NULL
|
||||
delete LPT;
|
||||
LPT=NULL;
|
||||
}
|
||||
break;
|
||||
case 4: //PoKeys
|
||||
PoKeys55[0]=new TPoKeys55();
|
||||
if (PoKeys55[0]?PoKeys55[0]->Connect():false)
|
||||
{WriteLog("Found "+PoKeys55[0]->Version());
|
||||
BitsUpdate(-1); //aktualizacjia stanów, bo przy wczytywaniu mogło być nieaktywne
|
||||
}
|
||||
else
|
||||
{//połączenie nie wyszło, ma być NULL
|
||||
delete PoKeys55[0];
|
||||
PoKeys55[0]=NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
void __fastcall Console::Off()
|
||||
{//wyłączenie informacji zwrotnych (reset pulpitu)
|
||||
BitsClear(-1);
|
||||
if ((iMode==1)||(iMode==2))
|
||||
if (iConfig&1) //licznik użycia Scroll Lock
|
||||
{//bez sensu to jest, ale mi się samo włącza
|
||||
SetLedState(VK_SCROLL,true); //przyciśnięty
|
||||
SetLedState(VK_SCROLL,false); //zwolniony
|
||||
}
|
||||
delete PoKeys55[0]; PoKeys55[0]=NULL;
|
||||
delete PoKeys55[1]; PoKeys55[1]=NULL;
|
||||
delete LPT; LPT=NULL;
|
||||
};
|
||||
|
||||
void __fastcall Console::BitsSet(int mask,int entry)
|
||||
{//ustawienie bitów o podanej masce (mask) na wejściu (entry)
|
||||
if ((iBits&mask)!=mask) //jeżeli zmiana
|
||||
{int old=iBits; //poprzednie stany
|
||||
iBits|=mask;
|
||||
BitsUpdate(old^iBits); //1 dla bitów zmienionych
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall Console::BitsClear(int mask,int entry)
|
||||
{//zerowanie bitów o podanej masce (mask) na wejściu (entry)
|
||||
if (iBits&mask) //jeżeli zmiana
|
||||
{int old=iBits; //poprzednie stany
|
||||
iBits&=~mask;
|
||||
BitsUpdate(old^iBits); //1 dla bitów zmienionych
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall Console::BitsUpdate(int mask)
|
||||
{//aktualizacja stanu interfejsu informacji zwrotnej; (mask) - zakres zmienianych bitów
|
||||
switch (iMode)
|
||||
{case 1: //sterowanie światełkami klawiatury: CA/SHP+opory
|
||||
if (mask&3) //gdy SHP albo CA
|
||||
SetLedState(VK_CAPITAL,iBits&3);
|
||||
if (mask&4) //gdy jazda na oporach
|
||||
{//Scroll Lock ma jakoś dziwnie... zmiana stanu na przeciwny
|
||||
SetLedState(VK_SCROLL,true); //przyciśnięty
|
||||
SetLedState(VK_SCROLL,false); //zwolniony
|
||||
++iConfig; //licznik użycia Scroll Lock
|
||||
}
|
||||
break;
|
||||
case 2: //sterowanie światełkami klawiatury: CA+SHP
|
||||
if (mask&2) //gdy CA
|
||||
SetLedState(VK_CAPITAL,iBits&2);
|
||||
if (mask&1) //gdy SHP
|
||||
{//Scroll Lock ma jakoś dziwnie... zmiana stanu na przeciwny
|
||||
SetLedState(VK_SCROLL,true); //przyciśnięty
|
||||
SetLedState(VK_SCROLL,false); //zwolniony
|
||||
++iConfig; //licznik użycia Scroll Lock
|
||||
}
|
||||
break;
|
||||
case 3: //LPT Marcela z modyfikacją (jazda na oporach zamiast brzęczyka)
|
||||
if (LPT)
|
||||
LPT->Out(iBits);
|
||||
break;
|
||||
case 4: //PoKeys55 wg Marcela - wersja druga z końca 2012
|
||||
if (PoKeys55[0])
|
||||
{//pewnie trzeba będzie to dodatkowo buforować i oczekiwać na potwierdzenie
|
||||
if (mask&0x0001) //b0 gdy SHP
|
||||
PoKeys55[0]->Write(0x40,23-1,iBits&0x0001?1:0);
|
||||
if (mask&0x0002) //b1 gdy zmieniony CA
|
||||
PoKeys55[0]->Write(0x40,24-1,iBits&0x0002?1:0);
|
||||
if (mask&0x0004) //b2 gdy jazda na oporach
|
||||
PoKeys55[0]->Write(0x40,32-1,iBits&0x0004?1:0);
|
||||
if (mask&0x0008) //b3 Lampka WS (wyłącznika szybkiego)
|
||||
PoKeys55[0]->Write(0x40,25-1,iBits&0x0008?1:0);
|
||||
if (mask&0x0010) //b4 Lampka przekaźnika nadmiarowego silników trakcyjnych
|
||||
PoKeys55[0]->Write(0x40,27-1,iBits&0x0010?1:0);
|
||||
if (mask&0x0020) //b5 Lampka styczników liniowych
|
||||
PoKeys55[0]->Write(0x40,29-1,iBits&0x0020?1:0);
|
||||
if (mask&0x0040) //b6 Lampka poślizgu
|
||||
PoKeys55[0]->Write(0x40,30-1,iBits&0x0040?1:0);
|
||||
if (mask&0x0080) //b7 Lampka "przetwornicy"
|
||||
PoKeys55[0]->Write(0x40,28-1,iBits&0x0080?1:0);
|
||||
if (mask&0x0100) //b8 Kontrolka przekaźnika nadmiarowego sprężarki
|
||||
PoKeys55[0]->Write(0x40,33-1,iBits&0x0100?1:0);
|
||||
if (mask&0x0200) //b9 Kontrolka sygnalizacji wentylatorów i oporów
|
||||
PoKeys55[0]->Write(0x40,26-1,iBits&0x0200?1:0);
|
||||
if (mask&0x0400) //b10 Kontrolka wysokiego rozruchu
|
||||
PoKeys55[0]->Write(0x40,31-1,iBits&0x0400?1:0);
|
||||
if (mask&0x0800) //b11 Kontrolka ogrzewania pociągu
|
||||
PoKeys55[0]->Write(0x40,34-1,iBits&0x0800?1:0);
|
||||
if (mask&0x1000) //b12 Ciśnienie w cylindrach do odbijania w haslerze
|
||||
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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
bool __fastcall Console::Pressed(int x)
|
||||
{//na razie tak - czyta się tylko klawiatura
|
||||
return Global::bActive&&(GetKeyState(x)<0);
|
||||
};
|
||||
|
||||
void __fastcall 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>
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall Console::Update()
|
||||
{//funkcja powinna być wywoływana regularnie, np. raz w każdej ramce ekranowej
|
||||
if (iMode==4)
|
||||
if (PoKeys55[0])
|
||||
if (PoKeys55[0]->Update((Global::iPause&8)>0))
|
||||
{//wykrycie przestawionych przełączników?
|
||||
Global::iPause&=~8;
|
||||
}
|
||||
else
|
||||
{//błąd komunikacji - zapauzować symulację?
|
||||
if (!(Global::iPause&8)) //jeśli jeszcze nie oflagowana
|
||||
Global::iTextMode=VK_F1; //pokazanie czasu/pauzy
|
||||
Global::iPause|=8; //tak???
|
||||
PoKeys55[0]->Connect(); //próba ponownego podłączenia
|
||||
}
|
||||
};
|
||||
|
||||
float __fastcall Console::AnalogGet(int x)
|
||||
{//pobranie wartości analogowej
|
||||
if (iMode==4)
|
||||
if (PoKeys55[0])
|
||||
return PoKeys55[0]->fAnalog[x];
|
||||
return -1.0;
|
||||
};
|
||||
|
||||
unsigned char __fastcall Console::DigitalGet(int x)
|
||||
{//pobranie wartości cyfrowej
|
||||
if (iMode==4)
|
||||
if (PoKeys55[0])
|
||||
return PoKeys55[0]->iInputs[x];
|
||||
return 0;
|
||||
};
|
||||
|
||||
void __fastcall Console::OnKeyDown(int k)
|
||||
{//naciśnięcie klawisza z powoduje wyłączenie, a
|
||||
if (k&0x10000) //jeśli [Shift]
|
||||
{//ustawienie bitu w tabeli przełączników bistabilnych
|
||||
if (k&0x20000) //jeśli [Ctrl], to zestaw dodatkowy
|
||||
iSwitch[4+(char(k)>>5)]|=1<<(k&31); //załącz bistabliny dodatkowy
|
||||
else
|
||||
{//z [Shift] włączenie bitu bistabilnego i dodatkowego monostabilnego
|
||||
iSwitch[char(k)>>5]|=1<<(k&31); //załącz bistabliny podstawowy
|
||||
iButton[4+(char(k)>>5)]|=(1<<(k&31)); //załącz monostabilny dodatkowy
|
||||
}
|
||||
}
|
||||
else
|
||||
{//zerowanie bitu w tabeli przełączników bistabilnych
|
||||
if (k&0x20000) //jeśli [Ctrl], to zestaw dodatkowy
|
||||
iSwitch[4+(char(k)>>5)]&=~(1<<(k&31)); //wyłącz bistabilny dodatkowy
|
||||
else
|
||||
{iSwitch[char(k)>>5]&=~(1<<(k&31)); //wyłącz bistabilny podstawowy
|
||||
iButton[char(k)>>5]|=1<<(k&31); //załącz monostabilny podstawowy
|
||||
}
|
||||
}
|
||||
};
|
||||
void __fastcall Console::OnKeyUp(int k)
|
||||
{//puszczenie klawisza w zasadzie nie ma znaczenia dla iSwitch, ale zeruje iButton
|
||||
if ((k&0x20000)==0) //monostabilne tylko bez [Ctrl]
|
||||
if (k&0x10000) //jeśli [Shift]
|
||||
iButton[4+(char(k)>>5)]&=~(1<<(k&31)); //wyłącz monostabilny dodatkowy
|
||||
else
|
||||
iButton[char(k)>>5]&=~(1<<(k&31)); //wyłącz monostabilny podstawowy
|
||||
};
|
||||
int __fastcall Console::KeyDownConvert(int k)
|
||||
{
|
||||
return int(ktTable[k&0x3FF].iDown);
|
||||
};
|
||||
int __fastcall Console::KeyUpConvert(int k)
|
||||
{
|
||||
return int(ktTable[k&0x3FF].iUp);
|
||||
};
|
||||
|
||||
55
Console.h
Normal file
55
Console.h
Normal file
@@ -0,0 +1,55 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef ConsoleH
|
||||
#define ConsoleH
|
||||
//---------------------------------------------------------------------------
|
||||
class TConsoleDevice; //urządzenie podłączalne za pomocą DLL
|
||||
class TPoKeys55;
|
||||
class TLPT;
|
||||
|
||||
//klasy konwersji znaków wprowadzanych z klawiatury
|
||||
class TKeyTrans
|
||||
{//przekodowanie kodu naciśnięcia i zwolnienia klawisza
|
||||
public:
|
||||
short int iDown,iUp;
|
||||
};
|
||||
|
||||
class Console
|
||||
{//Ra: klasa statyczna gromadząca sygnały sterujące oraz informacje zwrotne
|
||||
//Ra: stan wejścia zmieniany klawiaturą albo dedykowanym urządzeniem
|
||||
//Ra: stan wyjścia zmieniany przez symulację (mierniki, kontrolki)
|
||||
private:
|
||||
static int iMode; //tryb pracy
|
||||
static int iConfig; //dodatkowa informacja o sprzęcie (np. numer LPT)
|
||||
static int iBits; //podstawowy zestaw lampek
|
||||
static TPoKeys55 *PoKeys55[2]; //może ich być kilka
|
||||
static TLPT *LPT;
|
||||
static void __fastcall BitsUpdate(int mask);
|
||||
//zmienne dla trybu "jednokabinowego", potrzebne do współpracy z pulpitem (PoKeys)
|
||||
//używając klawiatury, każdy pojazd powinien mieć własny stan przełączników
|
||||
//bazowym sterowaniem jest wirtualny strumień klawiatury
|
||||
//przy zmianie kabiny z PoKeys, do kabiny są wysyłane stany tych przycisków
|
||||
static int iSwitch[8]; //bistabilne w kabinie, załączane z [Shift], wyłączane bez
|
||||
static int iButton[8]; //monostabilne w kabinie, załączane podczas trzymania klawisza
|
||||
static TKeyTrans ktTable[4*256]; //tabela wczesnej konwersji klawiatury
|
||||
public:
|
||||
__fastcall Console();
|
||||
__fastcall ~Console();
|
||||
static void __fastcall ModeSet(int m,int h=0);
|
||||
static void __fastcall BitsSet(int mask,int entry=0);
|
||||
static void __fastcall BitsClear(int mask,int entry=0);
|
||||
static int __fastcall On();
|
||||
static void __fastcall Off();
|
||||
static bool __fastcall Pressed(int x);
|
||||
static void __fastcall ValueSet(int x,double y);
|
||||
static void __fastcall Update();
|
||||
static float __fastcall AnalogGet(int x);
|
||||
static unsigned char __fastcall DigitalGet(int x);
|
||||
static void __fastcall OnKeyDown(int k);
|
||||
static void __fastcall OnKeyUp(int k);
|
||||
static int __fastcall KeyDownConvert(int k);
|
||||
static int __fastcall KeyUpConvert(int k);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
46
Console/LPT.cpp
Normal file
46
Console/LPT.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "LPT.h"
|
||||
#include <windows.h>
|
||||
|
||||
//LPT na USB:
|
||||
//USB\VID_067B&PID_2305&REV_0200
|
||||
//{9d7debbc-c85d-11d1-9eb4-006008c3a19a}
|
||||
//USB\VID_067B&PID_2305\5&1E41AFF0&0&2
|
||||
//IEEE-1284 Controller
|
||||
|
||||
HINSTANCE hDLL;
|
||||
typedef USHORT (__stdcall *InPortType)(USHORT BasePort);
|
||||
typedef void (__stdcall *OutPortType)(USHORT BasePort, USHORT value);
|
||||
InPortType InPort;
|
||||
OutPortType OutPort;
|
||||
|
||||
bool __fastcall TLPT::Connect(int port)
|
||||
{
|
||||
//ladowanie dll-ki
|
||||
hDLL=LoadLibrary("inpout32.dll");
|
||||
if (hDLL)
|
||||
{
|
||||
InPort=(InPortType)GetProcAddress(hDLL,"Inp32");
|
||||
OutPort=(OutPortType)GetProcAddress(hDLL,"Out32");
|
||||
}
|
||||
else
|
||||
return false; //MessageBox(NULL,"ERROR","B³¹d przy ³adowaniu pliku",MB_OK);
|
||||
address=port; //&0xFFFFFC; //ostatnie 2 bity maj¹ byæ zerowe -> a niech sobie OUT-uj¹, gdzie chc¹
|
||||
switch (address) //nie dotyczy 0x3BC
|
||||
{case 0x0378:
|
||||
case 0x0278:
|
||||
OutPort(address+0x402,0); //SPP, czyli jednokierunkowe wyjœcie
|
||||
break;
|
||||
case 0xBC00:
|
||||
case 0xBD00:
|
||||
OutPort(address+0x006,0); //0xBC06? czysta improwizacja
|
||||
}
|
||||
return bool(OutPort);
|
||||
};
|
||||
|
||||
void __fastcall TLPT::Out(int x)
|
||||
{//wys³anie bajtu do portu
|
||||
OutPort(address,x);
|
||||
};
|
||||
|
||||
15
Console/LPT.h
Normal file
15
Console/LPT.h
Normal file
@@ -0,0 +1,15 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef LPTH
|
||||
#define LPTH
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class TLPT
|
||||
{
|
||||
private:
|
||||
int address;
|
||||
public:
|
||||
bool __fastcall Connect(int port);
|
||||
void __fastcall Out(int x);
|
||||
};
|
||||
#endif
|
||||
316
Console/PoKeys55.cpp
Normal file
316
Console/PoKeys55.cpp
Normal file
@@ -0,0 +1,316 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#include <vcl.h>
|
||||
#pragma hdrstop
|
||||
|
||||
#include <setupapi.h>
|
||||
#include "PoKeys55.h"
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
//HIDscaner: http://forum.simflight.com/topic/68257-latest-lua-package-for-fsuipc-and-wideclient/
|
||||
//#define MY_DEVICE_ID "Vid_04d8&Pid_003F"
|
||||
//#define MY_DEVICE_ID "Vid_1dc3&Pid_1001&Rev_1000&MI_01"
|
||||
//HID\Vid_1dc3&Pid_1001&Rev_1000&MI_01 - MI_01 to jest interfejs komunikacyjny (00-joystick, 02-klawiatura)
|
||||
|
||||
HANDLE WriteHandle=INVALID_HANDLE_VALUE;
|
||||
HANDLE ReadHandle =INVALID_HANDLE_VALUE;
|
||||
//GUID InterfaceClassGuid={0x4d1e55b2,0xf16f,0x11cf,0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30};
|
||||
//{4d1e55b2-f16f-11cf-88cb-001111000030}
|
||||
|
||||
__fastcall TPoKeys55::TPoKeys55()
|
||||
{
|
||||
cRequest=0;
|
||||
iPWMbits=1;
|
||||
iFaza=0;
|
||||
iLastCommand=0;
|
||||
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?
|
||||
iRepeats=0;
|
||||
bNoError=true;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
__fastcall TPoKeys55::~TPoKeys55()
|
||||
{
|
||||
Close();
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TPoKeys55::Close()
|
||||
{//roz³¹czenie komunikacji
|
||||
if (WriteHandle!=INVALID_HANDLE_VALUE)
|
||||
CloseHandle(WriteHandle);
|
||||
WriteHandle=INVALID_HANDLE_VALUE;
|
||||
if (ReadHandle!=INVALID_HANDLE_VALUE)
|
||||
CloseHandle(ReadHandle);
|
||||
ReadHandle=INVALID_HANDLE_VALUE;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TPoKeys55::Connect()
|
||||
{//Ra: to jest do wyczyszcznia z niepotrzebnych zmiennych i komunikatów
|
||||
Close();
|
||||
GUID InterfaceClassGuid={0x4d1e55b2,0xf16f,0x11cf,0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}; //wszystkie HID tak maj¹
|
||||
HDEVINFO DeviceInfoTable;
|
||||
PSP_DEVICE_INTERFACE_DATA InterfaceDataStructure=new SP_DEVICE_INTERFACE_DATA;
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure=new SP_DEVICE_INTERFACE_DETAIL_DATA;
|
||||
SP_DEVINFO_DATA DevInfoData;
|
||||
DWORD InterfaceIndex=0;
|
||||
//DWORD StatusLastError=0;
|
||||
DWORD dwRegType;
|
||||
DWORD dwRegSize;
|
||||
DWORD StructureSize=0;
|
||||
PBYTE PropertyValueBuffer;
|
||||
bool MatchFound;
|
||||
DWORD ErrorStatus;
|
||||
HDEVINFO hDevInfo;
|
||||
String DeviceIDFromRegistry;
|
||||
String DeviceIDToFind="Vid_1dc3&Pid_1001&Rev_1000&MI_01";
|
||||
//First populate a list of plugged in devices (by specifying "DIGCF_PRESENT"), which are of the specified class GUID.
|
||||
DeviceInfoTable=SetupDiGetClassDevs(&InterfaceClassGuid,NULL,NULL,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);
|
||||
//Now look through the list we just populated. We are trying to see if any of them match our device.
|
||||
while (true)
|
||||
{
|
||||
InterfaceDataStructure->cbSize=sizeof(SP_DEVICE_INTERFACE_DATA);
|
||||
if (SetupDiEnumDeviceInterfaces(DeviceInfoTable, NULL, &InterfaceClassGuid, InterfaceIndex, InterfaceDataStructure))
|
||||
{
|
||||
ErrorStatus=GetLastError();
|
||||
if (ERROR_NO_MORE_ITEMS==ErrorStatus) //Did we reach the end of the list of matching devices in the DeviceInfoTable?
|
||||
{//Cound not find the device. Must not have been attached.
|
||||
SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need.
|
||||
//ShowMessage("Erreur: Sortie1");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else //Else some other kind of unknown error ocurred...
|
||||
{
|
||||
ErrorStatus=GetLastError();
|
||||
SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need.
|
||||
//ShowMessage("Erreur: Sortie2");
|
||||
return false;
|
||||
}
|
||||
//Now retrieve the hardware ID from the registry. The hardware ID contains the VID and PID, which we will then
|
||||
//check to see if it is the correct device or not.
|
||||
//Initialize an appropriate SP_DEVINFO_DATA structure. We need this structure for SetupDiGetDeviceRegistryProperty().
|
||||
DevInfoData.cbSize=sizeof(SP_DEVINFO_DATA);
|
||||
SetupDiEnumDeviceInfo(DeviceInfoTable,InterfaceIndex,&DevInfoData);
|
||||
//First query for the size of the hardware ID, so we can know how big a buffer to allocate for the data.
|
||||
SetupDiGetDeviceRegistryProperty(DeviceInfoTable,&DevInfoData,SPDRP_HARDWAREID,&dwRegType,NULL,0,&dwRegSize);
|
||||
//Allocate a buffer for the hardware ID.
|
||||
//PropertyValueBuffer=(BYTE*)malloc(dwRegSize);
|
||||
PropertyValueBuffer=new char[dwRegSize];
|
||||
if (PropertyValueBuffer==NULL) //if null,error,couldn't allocate enough memory
|
||||
{//Can't really recover from this situation,just exit instead.
|
||||
//ShowMessage("Allocation PropertyValueBuffer impossible");
|
||||
SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need.
|
||||
return false;
|
||||
}
|
||||
//Retrieve the hardware IDs for the current device we are looking at. PropertyValueBuffer gets filled with a
|
||||
//REG_MULTI_SZ (array of null terminated strings). To find a device,we only care about the very first string in the
|
||||
//buffer,which will be the "device ID". The device ID is a string which contains the VID and PID,in the example
|
||||
//format "Vid_04d8&Pid_003f".
|
||||
SetupDiGetDeviceRegistryProperty(DeviceInfoTable,&DevInfoData,SPDRP_HARDWAREID,&dwRegType,PropertyValueBuffer,dwRegSize,NULL);
|
||||
//Now check if the first string in the hardware ID matches the device ID of my USB device.
|
||||
//ListBox1->Items->Add((char*)PropertyValueBuffer);
|
||||
DeviceIDFromRegistry=StrPas((char*)PropertyValueBuffer);
|
||||
//free(PropertyValueBuffer); //No longer need the PropertyValueBuffer,free the memory to prevent potential memory leaks
|
||||
delete PropertyValueBuffer; //No longer need the PropertyValueBuffer,free the memory to prevent potential memory leaks
|
||||
//Convert both strings to lower case. This makes the code more robust/portable accross OS Versions
|
||||
DeviceIDFromRegistry=DeviceIDFromRegistry.LowerCase();
|
||||
DeviceIDToFind=DeviceIDToFind.LowerCase();
|
||||
//Now check if the hardware ID we are looking at contains the correct VID/PID
|
||||
MatchFound=(DeviceIDFromRegistry.AnsiPos(DeviceIDToFind)>0);
|
||||
if (MatchFound==true)
|
||||
{
|
||||
//Device must have been found. Open read and write handles. In order to do this,we will need the actual device path first.
|
||||
//We can get the path by calling SetupDiGetDeviceInterfaceDetail(),however,we have to call this function twice: The first
|
||||
//time to get the size of the required structure/buffer to hold the detailed interface data,then a second time to actually
|
||||
//get the structure (after we have allocated enough memory for the structure.)
|
||||
DetailedInterfaceDataStructure->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
//First call populates "StructureSize" with the correct value
|
||||
SetupDiGetDeviceInterfaceDetail(DeviceInfoTable,InterfaceDataStructure,NULL,NULL,&StructureSize,NULL);
|
||||
DetailedInterfaceDataStructure=(PSP_DEVICE_INTERFACE_DETAIL_DATA)(malloc(StructureSize)); //Allocate enough memory
|
||||
if (DetailedInterfaceDataStructure==NULL) //if null,error,couldn't allocate enough memory
|
||||
{//Can't really recover from this situation,just exit instead.
|
||||
SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need.
|
||||
return false;
|
||||
}
|
||||
DetailedInterfaceDataStructure->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
||||
//Now call SetupDiGetDeviceInterfaceDetail() a second time to receive the goods.
|
||||
SetupDiGetDeviceInterfaceDetail(DeviceInfoTable,InterfaceDataStructure,DetailedInterfaceDataStructure,StructureSize,NULL,NULL);
|
||||
//We now have the proper device path,and we can finally open read and write handles to the device.
|
||||
//We store the handles in the global variables "WriteHandle" and "ReadHandle",which we will use later to actually communicate.
|
||||
WriteHandle=CreateFile((DetailedInterfaceDataStructure->DevicePath),GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,0);
|
||||
ErrorStatus=GetLastError();
|
||||
//if (ErrorStatus==ERROR_SUCCESS)
|
||||
// ToggleLedBtn->Enabled=true;//Make button no longer greyed out
|
||||
ReadHandle=CreateFile((DetailedInterfaceDataStructure->DevicePath),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,0);
|
||||
ErrorStatus=GetLastError();
|
||||
if (ErrorStatus==ERROR_SUCCESS)
|
||||
{
|
||||
//GetPushbuttonState->Enabled=true;//Make button no longer greyed out
|
||||
//StateLabel->Enabled=true;//Make label no longer greyed out
|
||||
}
|
||||
SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need.
|
||||
iRepeats=0; //nowe szanse na pod³¹czenie
|
||||
return true;
|
||||
}
|
||||
InterfaceIndex++;
|
||||
//Keep looping until we either find a device with matching VID and PID,or until we run out of items.
|
||||
}//end of while(true)
|
||||
//ShowMessage("Sortie");
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TPoKeys55::Write(unsigned char c,unsigned char b3,unsigned char b4,unsigned char b5)
|
||||
{
|
||||
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=c; //operacja: 0x31: blokowy odczyt wejϾ
|
||||
OutputBuffer[3]=b3; //np. numer pinu (o 1 mniej ni¿ numer na p³ytce)
|
||||
OutputBuffer[4]=b4;
|
||||
OutputBuffer[5]=b5;
|
||||
OutputBuffer[6]=0;
|
||||
OutputBuffer[7]=++cRequest; //numer ¿¹dania
|
||||
OutputBuffer[8]=0;
|
||||
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 __fastcall TPoKeys55::Read()
|
||||
{
|
||||
DWORD BytesRead=0;
|
||||
InputBuffer[0]=0; //The first byte is the "Report ID" and does not get transmitted over the USB bus. Always set=0.
|
||||
//Now get the response packet from the firmware.
|
||||
//The following call to ReadFIle() retrieves 64 bytes of data from the USB device.
|
||||
ReadFile(ReadHandle,&InputBuffer,65,&BytesRead,0); //Blocking function,unless an "overlapped" structure is used
|
||||
//InputPacketBuffer[0] is the report ID, which we don't care about.
|
||||
//InputPacketBuffer[1] is an echo back of the command.
|
||||
//InputPacketBuffer[2] contains the I/O port pin value for the pushbutton.
|
||||
return (BytesRead==65)?InputBuffer[7]==cRequest:false;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
bool __fastcall TPoKeys55::ReadLoop(int i)
|
||||
{//próbuje odczytaæ (i) razy
|
||||
do
|
||||
{if (Read()) return true;
|
||||
Sleep(1); //trochê poczekaæ, a¿ odpowie
|
||||
}
|
||||
while (--i);
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
AnsiString __fastcall TPoKeys55::Version()
|
||||
{//zwraca numer wersji, funkcja nieoptymalna czasowo (czeka na odpowiedŸ)
|
||||
if (!WriteHandle) return "";
|
||||
Write(0x00,0); //0x00 - Read serial number, version
|
||||
if (ReadLoop(10))
|
||||
{//3: serial MSB; 4: serial LSB; 5: software version (v(1+[4-7]).([0-3])); 6: revision number
|
||||
AnsiString s="PoKeys55 #"+AnsiString((InputBuffer[3]<<8)+InputBuffer[4]);
|
||||
s+=" v"+AnsiString(1+(InputBuffer[5]>>4))+"."+AnsiString(InputBuffer[5]&15)+"."+AnsiString(InputBuffer[6]);
|
||||
/* //Ra: pozyskiwanie daty mo¿na sobie darowaæ, jest poniek¹d bez sensu
|
||||
Write(0x04,0); //0x04 - Read build date: drugi argument zmieniaæ od 0 do 2, uzyskuj¹c kolejno po 4 znaki
|
||||
if (ReadLoop(5))
|
||||
{//2: 0x04; 3-6: char 1-4, 5-8, 9-11; (83-65-112-32-32-49-32-50-48-49-49-0=="Sep 1 2011")
|
||||
s+=" ("+AnsiString((char*)InputBuffer+3,4);
|
||||
Write(0x04,1); //0x04 - Read build date: drugi argument zmieniaæ od 0 do 2, uzyskuj¹c kolejno po 4 znaki
|
||||
if (ReadLoop(5))
|
||||
{s+=AnsiString((char*)InputBuffer+3,4);
|
||||
Write(0x04,2); //0x04 - Read build date: drugi argument zmieniaæ od 0 do 2, uzyskuj¹c kolejno po 4 znaki
|
||||
if (ReadLoop(5))
|
||||
s+=AnsiString((char*)InputBuffer+3,3);
|
||||
}
|
||||
s+=")";
|
||||
}
|
||||
*/
|
||||
return s;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
bool __fastcall TPoKeys55::PWM(int x,float y)
|
||||
{//ustawienie wskazanego PWM (@12Mhz: 12000=1ms=1000Hz)
|
||||
//iPWM[7]=1024; //1024==85333.3333333333ns=11718.75Hz
|
||||
iPWM[x]=int(0.5f+0x0FFF*y)&0x0FFF; //0x0FFF=4095
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __fastcall TPoKeys55::Update(bool pause)
|
||||
{//funkcja powinna byæ wywo³ywana regularnie, np. raz w ka¿dej ramce ekranowej
|
||||
if (pause)
|
||||
{//specjalna procedura, jeœli utracone po³¹czenie spowodowa³o pauzê
|
||||
iLastCommand=0; //po³¹czenie zosta³o na nowo otwarte
|
||||
//iFaza=0; //jeden b³¹d i podtrzymanie pauzy jest kontynuowane
|
||||
}
|
||||
switch (iFaza)
|
||||
{case 0: //uaktualnienie PWM raz na jakiœ czas
|
||||
OutputBuffer[9]=0x3F; //maska u¿ytych PWM
|
||||
*((int*)(OutputBuffer+10))=iPWM[0]; //PWM1 (pin 22)
|
||||
*((int*)(OutputBuffer+14))=iPWM[1]; //PWM2 (pin 21)
|
||||
*((int*)(OutputBuffer+18))=iPWM[2]; //PWM3 (pin 20)
|
||||
*((int*)(OutputBuffer+22))=iPWM[3]; //PWM4 (pin 19)
|
||||
*((int*)(OutputBuffer+26))=iPWM[4]; //PWM5 (pin 18)
|
||||
*((int*)(OutputBuffer+30))=iPWM[5]; //PWM6 (pin 17)
|
||||
*((int*)(OutputBuffer+34))=iPWM[7]; //PWM period
|
||||
if (Write(0xCB,1)) //wys³anie ustawieñ (1-ustaw, 0-odczyt)
|
||||
iRepeats=0; //informacja, ¿e posz³o dobrze
|
||||
++iFaza; //ta faza zosta³a zakoñczona
|
||||
//iRepeats=0;
|
||||
break;
|
||||
case 1: //odczyt wejϾ analogowych - komenda i przetwarzanie
|
||||
if (iLastCommand!=0x3A) //asynchroniczne ustawienie kontrolki mo¿e namieszaæ
|
||||
Write(0x3A,0); //0x3A - Analog inputs reading – all analog inputs in one command
|
||||
else if (Read())
|
||||
{//jest odebrana ramka i zgodnoœæ numeru ¿¹dania
|
||||
fAnalog[0]=((InputBuffer[21]<<8)+InputBuffer[22])/4095.0f; //pin 47
|
||||
fAnalog[1]=((InputBuffer[19]<<8)+InputBuffer[20])/4095.0f; //pin 46
|
||||
fAnalog[2]=((InputBuffer[17]<<8)+InputBuffer[18])/4095.0f; //pin 45
|
||||
fAnalog[3]=((InputBuffer[15]<<8)+InputBuffer[16])/4095.0f; //pin 44
|
||||
fAnalog[4]=((InputBuffer[13]<<8)+InputBuffer[14])/4095.0f; //pin 43
|
||||
fAnalog[5]=((InputBuffer[11]<<8)+InputBuffer[12])/4095.0f; //pin 42
|
||||
fAnalog[6]=((InputBuffer[ 9]<<8)+InputBuffer[10])/4095.0f; //pin 41
|
||||
++iFaza; //skoro odczytano, mo¿na przejœæ do kolejnej fazy
|
||||
iRepeats=0; //zerowanie licznika prób
|
||||
}
|
||||
else ++iRepeats; //licznik nieudanych prób
|
||||
break;
|
||||
case 2: //odczyt wejϾ cyfrowych - komenda i przetwarzanie
|
||||
if (iLastCommand!=0x31) //asynchroniczne ustawienie kontrolki mo¿e namieszaæ
|
||||
Write(0x31,0); //0x31: blokowy odczyt wejϾ
|
||||
else if (Read())
|
||||
{//jest odebrana ramka i zgodnoœæ numeru ¿¹dania
|
||||
iInputs[0]=*((int*)(InputBuffer+3)); //odczyt 32 bitów
|
||||
iFaza=3; //skoro odczytano, mo¿na kolejny cykl
|
||||
iRepeats=0; //zerowanie licznika prób
|
||||
}
|
||||
else ++iRepeats; //licznik nieudanych prób
|
||||
break;
|
||||
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
|
||||
//powinno jeszcze przyjϾ potwierdzenie o kodzie 0x41
|
||||
break;
|
||||
default:
|
||||
iFaza=0; //na wypadek, gdyby zb³¹dzi³o po jakichœ zmianach w kodzie
|
||||
//iRepeats=0;
|
||||
}
|
||||
if (!iRepeats)
|
||||
bNoError=true; //jest OK
|
||||
else if (iRepeats>=10) //youBy 2014-07: przy 5 powtórzeniach sieje mi pauz¹ po 2 razy na sekundê, a przy 10 jest ok
|
||||
{//przekroczenie liczby prób wymusza kolejn¹ fazê
|
||||
++iFaza;
|
||||
iRepeats=1; //w nowej fazie nowe szanse, ale nie od 0!
|
||||
bNoError=false; //zg³osiæ b³¹d
|
||||
}
|
||||
return (bNoError); //true oznacza prawid³owe dzia³anie
|
||||
//czy w przypadku b³êdu komunikacji z PoKeys w³¹czaæ pauzê?
|
||||
//dopiero poprawne pod³¹czenie zeruje licznik prób
|
||||
};
|
||||
|
||||
31
Console/PoKeys55.h
Normal file
31
Console/PoKeys55.h
Normal file
@@ -0,0 +1,31 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef PoKeys55H
|
||||
#define PoKeys55H
|
||||
//---------------------------------------------------------------------------
|
||||
class TPoKeys55
|
||||
{//komunikacja z PoKeys bez okreœlania przeznaczenia pinów
|
||||
unsigned char cRequest; //numer ¿¹dania do sprawdzania odpowiedzi
|
||||
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;
|
||||
int iLastCommand;
|
||||
int iFaza;
|
||||
int iRepeats; //liczba powtórzeñ
|
||||
bool bNoError; //zerowany po przepe³nieniu licznika powtórzeñ, ustawiany po udanej operacji
|
||||
public:
|
||||
float fAnalog[7]; //wejœcia analogowe, stan <0.0,1.0>
|
||||
int iInputs[8];
|
||||
__fastcall TPoKeys55();
|
||||
__fastcall ~TPoKeys55();
|
||||
bool __fastcall Connect();
|
||||
bool __fastcall Close();
|
||||
bool __fastcall Write(unsigned char c,unsigned char b3,unsigned char b4=0,unsigned char b5=0);
|
||||
bool __fastcall Read();
|
||||
bool __fastcall ReadLoop(int i);
|
||||
AnsiString __fastcall Version();
|
||||
bool __fastcall PWM(int x,float y);
|
||||
bool __fastcall Update(bool pause);
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
141
Curve.cpp
Normal file
141
Curve.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Curve.h"
|
||||
|
||||
|
||||
__fastcall TCurve::TCurve()
|
||||
{
|
||||
Values= NULL;
|
||||
iNumValues= 0;
|
||||
iNumCols= 0;
|
||||
}
|
||||
|
||||
__fastcall TCurve::~TCurve()
|
||||
{
|
||||
for (int i=0; i<iNumValues; i++)
|
||||
SafeDelete(Values[i]);
|
||||
SafeDelete(Values);
|
||||
}
|
||||
|
||||
bool __fastcall TCurve::Init(int n, int c)
|
||||
{
|
||||
for (int i=0; i<iNumValues; i++)
|
||||
SafeDelete(Values[i]);
|
||||
SafeDelete(Values);
|
||||
|
||||
iNumValues= n;
|
||||
iNumCols= c;
|
||||
Values= new float*[iNumValues];
|
||||
for (int i=0; i<iNumValues; i++)
|
||||
Values[i]= new float[iNumCols];
|
||||
|
||||
for (int i=0; i<iNumValues; i++)
|
||||
for (int j=0; j<iNumCols; j++)
|
||||
Values[i][j]= 0;
|
||||
}
|
||||
|
||||
float __fastcall TCurve::GetValue(int c, float p)
|
||||
{
|
||||
int a= floor(p);
|
||||
int b= ceil(p);
|
||||
if (a<0)
|
||||
return Values[0][c];
|
||||
if (b>=iNumValues)
|
||||
return Values[iNumValues-1][c];
|
||||
p-= floor(p);
|
||||
return Values[a][c]*(1.0f-p)+Values[b][c]*(p);
|
||||
}
|
||||
|
||||
bool __fastcall TCurve::SetValue(int c, float p, float v)
|
||||
{
|
||||
int a= floor(p);
|
||||
int b= ceil(p);
|
||||
if (a<0)
|
||||
return false;
|
||||
if (b>=iNumValues)
|
||||
return false;
|
||||
p-= floor(p);
|
||||
if (p<0.5)
|
||||
Values[a][c]= v;
|
||||
else
|
||||
Values[b][c]= v;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __fastcall TCurve::Load(TQueryParserComp *Parser)
|
||||
{
|
||||
DecimalSeparator= '.';
|
||||
AnsiString Token;
|
||||
|
||||
int n= Parser->GetNextSymbol().ToInt();
|
||||
int c= Parser->GetNextSymbol().ToInt();
|
||||
Init(n,c);
|
||||
|
||||
n=0;
|
||||
int i;
|
||||
while (!Parser->EOF && n<iNumValues)
|
||||
{
|
||||
for (i=0; i<iNumCols; i++)
|
||||
Values[n][i]= Parser->GetNextSymbol().ToDouble();
|
||||
n++;
|
||||
}
|
||||
DecimalSeparator= ',';
|
||||
}
|
||||
|
||||
bool __fastcall TCurve::LoadFromFile(AnsiString asName)
|
||||
{
|
||||
DecimalSeparator= '.';
|
||||
TFileStream *fs;
|
||||
fs= new TFileStream(asName, fmOpenRead | fmShareCompat );
|
||||
AnsiString str= "xxx";
|
||||
int size= fs->Size;
|
||||
str.SetLength(size);
|
||||
fs->Read(str.c_str(),size);
|
||||
str+= "";
|
||||
delete fs;
|
||||
TQueryParserComp *Parser;
|
||||
Parser= new TQueryParserComp(NULL);
|
||||
Parser->TextToParse= str;
|
||||
Parser->First();
|
||||
Load(Parser);
|
||||
|
||||
delete Parser;
|
||||
DecimalSeparator= ',';
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
bool __fastcall TCurve::SaveToFile(AnsiString asName)
|
||||
{
|
||||
|
||||
DecimalSeparator= '.';
|
||||
FILE *stream=NULL;
|
||||
stream = fopen(asName.c_str(), "w");
|
||||
|
||||
AnsiString str;
|
||||
str= AnsiString(iNumValues);
|
||||
fprintf(stream, str.c_str());
|
||||
fprintf(stream, "\n");
|
||||
for (int i=0; i<iNumValues; i++)
|
||||
{
|
||||
str= "";
|
||||
if (i % 10==0)
|
||||
str+= "\n";
|
||||
for (int j=0; j<iNumCols; j++)
|
||||
str+= FloatToStrF(Values[i][j],ffFixed,6,2)+AnsiString(" ");
|
||||
str+= AnsiString("\n");
|
||||
fprintf(stream, str.c_str());
|
||||
}
|
||||
|
||||
fclose(stream);
|
||||
DecimalSeparator= ',';
|
||||
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
29
Curve.h
Normal file
29
Curve.h
Normal file
@@ -0,0 +1,29 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef CurveH
|
||||
#define CurveH
|
||||
|
||||
#include "QueryParserComp.hpp"
|
||||
#include "Usefull.h"
|
||||
|
||||
class TCurve
|
||||
{
|
||||
public:
|
||||
__fastcall TCurve();
|
||||
__fastcall ~TCurve();
|
||||
bool __fastcall Init(int n, int c);
|
||||
float __fastcall GetValue(int c, float p);
|
||||
bool __fastcall SetValue(int c, float p, float v);
|
||||
bool __fastcall Load(TQueryParserComp *Parser);
|
||||
bool __fastcall LoadFromFile(AnsiString asName);
|
||||
bool __fastcall SaveToFile(AnsiString asName);
|
||||
|
||||
int iNumValues;
|
||||
int iNumCols;
|
||||
|
||||
private:
|
||||
float **Values;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
418
Data.h
Normal file
418
Data.h
Normal file
@@ -0,0 +1,418 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef DataH
|
||||
#define DataH
|
||||
//---------------------------------------------------------------------------
|
||||
// Modu³ z danymi
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
struct TDist
|
||||
{
|
||||
int x,y;
|
||||
};
|
||||
const TDist SectorOrder[]=
|
||||
{//tabela wspó³rzêdnych sektorów, posortowana wg odleg³oœci
|
||||
{ 0, 0}, // 0.00
|
||||
{ 1, 0}, // 1.00
|
||||
{ 0, 1}, // 1.00
|
||||
{ 1, 1}, // 1.41
|
||||
{ 2, 0}, // 2.00
|
||||
{ 0, 2}, // 2.00
|
||||
{ 2, 1}, // 2.24
|
||||
{ 1, 2}, // 2.24
|
||||
{ 2, 2}, // 2.83 - 9 (566m)
|
||||
{ 3, 0}, // 3.00
|
||||
{ 0, 3}, // 3.00
|
||||
{ 3, 1}, // 3.16
|
||||
{ 1, 3}, // 3.16
|
||||
{ 3, 2}, // 3.61
|
||||
{ 2, 3}, // 3.61
|
||||
{ 4, 0}, // 4.00 - 16 (800m)
|
||||
{ 0, 4}, // 4.00
|
||||
{ 4, 1}, // 4.12
|
||||
{ 1, 4}, // 4.12
|
||||
{ 3, 3}, // 4.24 - 20
|
||||
{ 4, 2}, // 4.47
|
||||
{ 2, 4}, // 4.47
|
||||
{ 4, 3}, // 5.00
|
||||
{ 3, 4}, // 5.00
|
||||
{ 5, 0}, // 5.00 - 25
|
||||
{ 0, 5}, // 5.00
|
||||
{ 5, 1}, // 5.10
|
||||
{ 1, 5}, // 5.10 - 28
|
||||
{ 5, 2}, // 5.39
|
||||
{ 2, 5}, // 5.39
|
||||
{ 4, 4}, // 5.66
|
||||
{ 5, 3}, // 5.83
|
||||
{ 3, 5}, // 5.83
|
||||
{ 6, 0}, // 6.00
|
||||
{ 0, 6}, // 6.00
|
||||
{ 6, 1}, // 6.08 - 36
|
||||
{ 1, 6}, // 6.08
|
||||
{ 6, 2}, // 6.32
|
||||
{ 2, 6}, // 6.32
|
||||
{ 5, 4}, // 6.40
|
||||
{ 4, 5}, // 6.40
|
||||
{ 6, 3}, // 6.71
|
||||
{ 3, 6}, // 6.71
|
||||
{ 7, 0}, // 7.00
|
||||
{ 0, 7}, // 7.00
|
||||
{ 5, 5}, // 7.07
|
||||
{ 7, 1}, // 7.07
|
||||
{ 1, 7}, // 7.07
|
||||
{ 6, 4}, // 7.21
|
||||
{ 4, 6}, // 7.21
|
||||
{ 7, 2}, // 7.28
|
||||
{ 2, 7}, // 7.28
|
||||
{ 7, 3}, // 7.62
|
||||
{ 3, 7}, // 7.62
|
||||
{ 6, 5}, // 7.81
|
||||
{ 5, 6}, // 7.81
|
||||
{ 8, 0}, // 8.00
|
||||
{ 0, 8}, // 8.00
|
||||
{ 7, 4}, // 8.06
|
||||
{ 4, 7}, // 8.06
|
||||
{ 8, 1}, // 8.06
|
||||
{ 1, 8}, // 8.06
|
||||
{ 8, 2}, // 8.25
|
||||
{ 2, 8}, // 8.25
|
||||
{ 6, 6}, // 8.49
|
||||
{ 8, 3}, // 8.54
|
||||
{ 3, 8}, // 8.54
|
||||
{ 7, 5}, // 8.60
|
||||
{ 5, 7}, // 8.60
|
||||
{ 8, 4}, // 8.94
|
||||
{ 4, 8}, // 8.94
|
||||
{ 9, 0}, // 9.00
|
||||
{ 0, 9}, // 9.00
|
||||
{ 9, 1}, // 9.06
|
||||
{ 1, 9}, // 9.06
|
||||
{ 7, 6}, // 9.22
|
||||
{ 6, 7}, // 9.22
|
||||
{ 9, 2}, // 9.22
|
||||
{ 2, 9}, // 9.22
|
||||
{ 8, 5}, // 9.43
|
||||
{ 5, 8}, // 9.43
|
||||
{ 9, 3}, // 9.49
|
||||
{ 3, 9}, // 9.49
|
||||
{ 9, 4}, // 9.85
|
||||
{ 4, 9}, // 9.85
|
||||
{ 7, 7}, // 9.90
|
||||
{ 8, 6}, //10.00
|
||||
{ 6, 8}, //10.00
|
||||
{10, 0}, //10.00
|
||||
{ 0,10}, //10.00
|
||||
{10, 1}, //10.05
|
||||
{ 1,10}, //10.05
|
||||
{10, 2}, //10.20
|
||||
{ 2,10}, //10.20
|
||||
{ 9, 5}, //10.30
|
||||
{ 5, 9}, //10.30
|
||||
{10, 3}, //10.44
|
||||
{ 3,10}, //10.44
|
||||
{ 8, 7}, //10.63
|
||||
{ 7, 8}, //10.63
|
||||
{10, 4}, //10.77
|
||||
{ 4,10}, //10.77
|
||||
{ 9, 6}, //10.82
|
||||
{ 6, 9}, //10.82
|
||||
{11, 0}, //11.00
|
||||
{ 0,11}, //11.00
|
||||
{11, 1}, //11.05
|
||||
{ 1,11}, //11.05
|
||||
{10, 5}, //11.18
|
||||
{ 5,10}, //11.18
|
||||
{11, 2}, //11.18
|
||||
{ 2,11}, //11.18
|
||||
{ 8, 8}, //11.31
|
||||
{ 9, 7}, //11.40
|
||||
{ 7, 9}, //11.40
|
||||
{11, 3}, //11.40
|
||||
{ 3,11}, //11.40
|
||||
{10, 6}, //11.66
|
||||
{ 6,10}, //11.66
|
||||
{11, 4}, //11.70
|
||||
{ 4,11}, //11.70
|
||||
{12, 0}, //12.00
|
||||
{ 0,12}, //12.00
|
||||
{ 9, 8}, //12.04
|
||||
{ 8, 9}, //12.04
|
||||
{12, 1}, //12.04
|
||||
{ 1,12}, //12.04
|
||||
{11, 5}, //12.08
|
||||
{ 5,11}, //12.08
|
||||
{12, 2}, //12.17
|
||||
{ 2,12}, //12.17
|
||||
{10, 7}, //12.21
|
||||
{ 7,10}, //12.21
|
||||
{12, 3}, //12.37
|
||||
{ 3,12}, //12.37
|
||||
{11, 6}, //12.53
|
||||
{ 6,11}, //12.53
|
||||
{12, 4}, //12.65
|
||||
{ 4,12}, //12.65
|
||||
{ 9, 9}, //12.73
|
||||
{10, 8}, //12.81
|
||||
{ 8,10}, //12.81
|
||||
{12, 5}, //13.00
|
||||
{ 5,12}, //13.00
|
||||
{13, 0}, //13.00
|
||||
{ 0,13}, //13.00
|
||||
{11, 7}, //13.04
|
||||
{ 7,11}, //13.04
|
||||
{13, 1}, //13.04
|
||||
{ 1,13}, //13.04
|
||||
{13, 2}, //13.15
|
||||
{ 2,13}, //13.15
|
||||
{13, 3}, //13.34
|
||||
{ 3,13}, //13.34
|
||||
{12, 6}, //13.42
|
||||
{ 6,12}, //13.42
|
||||
{10, 9}, //13.45
|
||||
{ 9,10}, //13.45
|
||||
{11, 8}, //13.60
|
||||
{ 8,11}, //13.60
|
||||
{13, 4}, //13.60
|
||||
{ 4,13}, //13.60
|
||||
{12, 7}, //13.89
|
||||
{ 7,12}, //13.89
|
||||
{13, 5}, //13.93
|
||||
{ 5,13}, //13.93
|
||||
{14, 0}, //14.00
|
||||
{ 0,14}, //14.00
|
||||
{14, 1}, //14.04
|
||||
{ 1,14}, //14.04
|
||||
{10,10}, //14.14
|
||||
{14, 2}, //14.14
|
||||
{ 2,14}, //14.14
|
||||
{11, 9}, //14.21
|
||||
{ 9,11}, //14.21
|
||||
{13, 6}, //14.32
|
||||
{ 6,13}, //14.32
|
||||
{14, 3}, //14.32
|
||||
{ 3,14}, //14.32
|
||||
{12, 8}, //14.42
|
||||
{ 8,12}, //14.42
|
||||
{14, 4}, //14.56
|
||||
{ 4,14}, //14.56
|
||||
{13, 7}, //14.76
|
||||
{ 7,13}, //14.76
|
||||
{11,10}, //14.87
|
||||
{10,11}, //14.87
|
||||
{14, 5}, //14.87
|
||||
{ 5,14}, //14.87
|
||||
{12, 9}, //15.00
|
||||
{ 9,12}, //15.00
|
||||
{15, 0}, //15.00
|
||||
{ 0,15}, //15.00
|
||||
{15, 1}, //15.03
|
||||
{ 1,15}, //15.03
|
||||
{15, 2}, //15.13
|
||||
{ 2,15}, //15.13
|
||||
{14, 6}, //15.23
|
||||
{ 6,14}, //15.23
|
||||
{13, 8}, //15.26
|
||||
{ 8,13}, //15.26
|
||||
{15, 3}, //15.30
|
||||
{ 3,15}, //15.30
|
||||
{15, 4}, //15.52
|
||||
{ 4,15}, //15.52
|
||||
{11,11}, //15.56
|
||||
{12,10}, //15.62
|
||||
{10,12}, //15.62
|
||||
{14, 7}, //15.65
|
||||
{ 7,14}, //15.65
|
||||
{13, 9}, //15.81
|
||||
{ 9,13}, //15.81
|
||||
{15, 5}, //15.81
|
||||
{ 5,15}, //15.81
|
||||
{16, 0}, //16.00
|
||||
{ 0,16}, //16.00
|
||||
{16, 1}, //16.03
|
||||
{ 1,16}, //16.03
|
||||
{14, 8}, //16.12
|
||||
{ 8,14}, //16.12
|
||||
{16, 2}, //16.12
|
||||
{ 2,16}, //16.12
|
||||
{15, 6}, //16.16
|
||||
{ 6,15}, //16.16
|
||||
{12,11}, //16.28
|
||||
{11,12}, //16.28
|
||||
{16, 3}, //16.28
|
||||
{ 3,16}, //16.28
|
||||
{13,10}, //16.40
|
||||
{10,13}, //16.40
|
||||
{16, 4}, //16.49
|
||||
{ 4,16}, //16.49
|
||||
{15, 7}, //16.55
|
||||
{ 7,15}, //16.55
|
||||
{14, 9}, //16.64
|
||||
{ 9,14}, //16.64
|
||||
{16, 5}, //16.76
|
||||
{ 5,16}, //16.76
|
||||
{12,12}, //16.97
|
||||
{15, 8}, //17.00
|
||||
{ 8,15}, //17.00
|
||||
{17, 0}, //17.00
|
||||
{ 0,17}, //17.00
|
||||
{13,11}, //17.03
|
||||
{11,13}, //17.03
|
||||
{17, 1}, //17.03
|
||||
{ 1,17}, //17.03
|
||||
{16, 6}, //17.09
|
||||
{ 6,16}, //17.09
|
||||
{17, 2}, //17.12
|
||||
{ 2,17}, //17.12
|
||||
{14,10}, //17.20
|
||||
{10,14}, //17.20
|
||||
{17, 3}, //17.26
|
||||
{ 3,17}, //17.26
|
||||
{16, 7}, //17.46
|
||||
{ 7,16}, //17.46
|
||||
{17, 4}, //17.46
|
||||
{ 4,17}, //17.46
|
||||
{15, 9}, //17.49
|
||||
{ 9,15}, //17.49
|
||||
{13,12}, //17.69
|
||||
{12,13}, //17.69
|
||||
{17, 5}, //17.72
|
||||
{ 5,17}, //17.72
|
||||
{14,11}, //17.80
|
||||
{11,14}, //17.80
|
||||
{16, 8}, //17.89
|
||||
{ 8,16}, //17.89
|
||||
{18, 0}, //18.00
|
||||
{ 0,18}, //18.00
|
||||
{15,10}, //18.03
|
||||
{10,15}, //18.03
|
||||
{17, 6}, //18.03
|
||||
{ 6,17}, //18.03
|
||||
{18, 1}, //18.03
|
||||
{ 1,18}, //18.03
|
||||
{18, 2}, //18.11
|
||||
{ 2,18}, //18.11
|
||||
{18, 3}, //18.25
|
||||
{ 3,18}, //18.25
|
||||
{16, 9}, //18.36
|
||||
{ 9,16}, //18.36
|
||||
{13,13}, //18.38
|
||||
{17, 7}, //18.38
|
||||
{ 7,17}, //18.38
|
||||
{14,12}, //18.44
|
||||
{12,14}, //18.44
|
||||
{18, 4}, //18.44
|
||||
{ 4,18}, //18.44
|
||||
{15,11}, //18.60
|
||||
{11,15}, //18.60
|
||||
{18, 5}, //18.68
|
||||
{ 5,18}, //18.68
|
||||
{17, 8}, //18.79
|
||||
{ 8,17}, //18.79
|
||||
{16,10}, //18.87
|
||||
{10,16}, //18.87
|
||||
{18, 6}, //18.97
|
||||
{ 6,18}, //18.97
|
||||
{19, 0}, //19.00
|
||||
{ 0,19}, //19.00
|
||||
{19, 1}, //19.03
|
||||
{ 1,19}, //19.03
|
||||
{14,13}, //19.10
|
||||
{13,14}, //19.10
|
||||
{19, 2}, //19.10
|
||||
{ 2,19}, //19.10
|
||||
{15,12}, //19.21
|
||||
{12,15}, //19.21
|
||||
{17, 9}, //19.24
|
||||
{ 9,17}, //19.24
|
||||
{19, 3}, //19.24
|
||||
{ 3,19}, //19.24
|
||||
{18, 7}, //19.31
|
||||
{ 7,18}, //19.31
|
||||
{16,11}, //19.42
|
||||
{11,16}, //19.42
|
||||
{19, 4}, //19.42
|
||||
{ 4,19}, //19.42
|
||||
{19, 5}, //19.65
|
||||
{ 5,19}, //19.65
|
||||
{18, 8}, //19.70
|
||||
{ 8,18}, //19.70
|
||||
{17,10}, //19.72
|
||||
{10,17}, //19.72
|
||||
{14,14}, //19.80
|
||||
{15,13}, //19.85
|
||||
{13,15}, //19.85
|
||||
{19, 6}, //19.92
|
||||
{ 6,19}, //19.92
|
||||
{16,12}, //20.00
|
||||
{12,16}, //20.00
|
||||
{18, 9}, //20.12
|
||||
{ 9,18}, //20.12
|
||||
{17,11}, //20.25
|
||||
{11,17}, //20.25
|
||||
{19, 7}, //20.25
|
||||
{ 7,19}, //20.25
|
||||
{15,14}, //20.52
|
||||
{14,15}, //20.52
|
||||
{18,10}, //20.59
|
||||
{10,18}, //20.59
|
||||
{16,13}, //20.62
|
||||
{13,16}, //20.62
|
||||
{19, 8}, //20.62
|
||||
{ 8,19}, //20.62
|
||||
{17,12}, //20.81
|
||||
{12,17}, //20.81
|
||||
{19, 9}, //21.02
|
||||
{ 9,19}, //21.02
|
||||
{18,11}, //21.10
|
||||
{11,18}, //21.10
|
||||
{15,15}, //21.21
|
||||
{16,14}, //21.26
|
||||
{14,16}, //21.26
|
||||
{17,13}, //21.40
|
||||
{13,17}, //21.40
|
||||
{19,10}, //21.47
|
||||
{10,19}, //21.47
|
||||
{18,12}, //21.63
|
||||
{12,18}, //21.63
|
||||
{16,15}, //21.93
|
||||
{15,16}, //21.93
|
||||
{19,11}, //21.95
|
||||
{11,19}, //21.95
|
||||
{17,14}, //22.02
|
||||
{14,17}, //22.02
|
||||
{18,13}, //22.20
|
||||
{13,18}, //22.20
|
||||
{19,12}, //22.47
|
||||
{12,19}, //22.47
|
||||
{16,16}, //22.63
|
||||
{17,15}, //22.67
|
||||
{15,17}, //22.67
|
||||
{18,14}, //22.80
|
||||
{14,18}, //22.80
|
||||
{19,13}, //23.02
|
||||
{13,19}, //23.02
|
||||
{17,16}, //23.35
|
||||
{16,17}, //23.35
|
||||
{18,15}, //23.43
|
||||
{15,18}, //23.43
|
||||
{19,14}, //23.60
|
||||
{14,19}, //23.60
|
||||
{17,17}, //24.04
|
||||
{18,16}, //24.08
|
||||
{16,18}, //24.08
|
||||
{19,15}, //24.21
|
||||
{15,19}, //24.21
|
||||
{18,17}, //24.76
|
||||
{17,18}, //24.76
|
||||
{19,16}, //24.84
|
||||
{16,19}, //24.84
|
||||
{18,18}, //25.46
|
||||
{19,17}, //25.50
|
||||
{17,19}, //25.50
|
||||
{19,18}, //26.17
|
||||
{18,19}, //26.17
|
||||
{19,19} //26.87 - 400 (5374m)
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
BIN
DirectX/DSOUND.LIB
Normal file
BIN
DirectX/DSOUND.LIB
Normal file
Binary file not shown.
4210
Driver.cpp
Normal file
4210
Driver.cpp
Normal file
File diff suppressed because it is too large
Load Diff
320
Driver.h
Normal file
320
Driver.h
Normal file
@@ -0,0 +1,320 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef DriverH
|
||||
#define DriverH
|
||||
|
||||
#include "Classes.h"
|
||||
#include "dumb3d.h"
|
||||
#include <fstream>
|
||||
using namespace Math3D;
|
||||
|
||||
enum TOrders
|
||||
{//rozkazy dla AI
|
||||
Wait_for_orders=0, //czekanie na dostarczenie następnych rozkazów
|
||||
//operacje tymczasowe
|
||||
Prepare_engine=1, //włączenie silnika
|
||||
Release_engine=2, //wyłączenie silnika
|
||||
Change_direction=4, //zmiana kierunku (bez skanowania sygnalizacji)
|
||||
Connect=8, //podłączanie wagonów (z częściowym skanowaniem sygnalizacji)
|
||||
Disconnect=0x10, //odłączanie wagonów (bez skanowania sygnalizacji)
|
||||
//jazda
|
||||
Shunt=0x20, //tryb manewrowy
|
||||
Obey_train=0x40, //tryb pociągowy
|
||||
Jump_to_first_order=0x60 //zapęlenie do pierwszej pozycji (po co?)
|
||||
};
|
||||
|
||||
enum TMovementStatus
|
||||
{//flagi bitowe ruchu (iDrivigFlags)
|
||||
moveStopCloser=1, //podjechać blisko W4 (nie podjeżdżać na początku ani po zmianie czoła)
|
||||
moveStopPoint=2, //stawać na W4 (wyłączone podczas zmiany czoła)
|
||||
moveActive=4, //pojazd jest załączony i skanuje
|
||||
movePress=8, //dociskanie przy odłączeniu (zamiast zmiennej Prepare2press)
|
||||
moveConnect=0x10, //jest blisko innego pojazdu i można próbować podłączyć
|
||||
movePrimary=0x20, //ma priorytet w składzie (master)
|
||||
moveLate=0x40, //flaga spóźnienia, włączy bardziej
|
||||
moveStopHere=0x80, //nie podjeżdżać do semafora, jeśli droga nie jest wolna
|
||||
moveStartHorn=0x100, //podawaj sygnał po podaniu wolnej drogi
|
||||
moveStartHornNow=0x200, //podaj sygnał po odhamowaniu
|
||||
moveStartHornDone=0x400, //podano sygnał po podaniu wolnej drogi
|
||||
moveOerlikons=0x800, //skład wyłącznie z zaworami? Oerlikona
|
||||
moveIncSpeed=0x1000, //załączenie jazdy (np. dla EZT)
|
||||
moveTrackEnd=0x2000, //dalsza jazda do przodu trwale ograniczona (W5, koniec toru)
|
||||
moveSwitchFound=0x4000, //na drodze skanowania do przodu jest rozjazd
|
||||
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
|
||||
};
|
||||
|
||||
enum TStopReason
|
||||
{//powód zatrzymania, dodawany do SetVelocity 0 - w zasadzie do usunięcia
|
||||
stopNone, //nie ma powodu - powinien jechać
|
||||
stopSleep, //nie został odpalony, to nie pojedzie
|
||||
stopSem, //semafor zamknięty
|
||||
stopTime, //czekanie na godzinę odjazdu
|
||||
stopEnd, //brak dalszej części toru
|
||||
stopDir, //trzeba stanąć, by zmienić kierunek jazdy
|
||||
stopJoin, //stoi w celu połączenia wagonów
|
||||
stopBlock, //przeszkoda na drodze ruchu
|
||||
stopComm, //otrzymano taką komendę (niewiadomego pochodzenia)
|
||||
stopOut, //komenda wyjazdu poza stację (raczej nie powinna zatrzymywać!)
|
||||
stopRadio, //komunikat przekazany radiem (Radiostop)
|
||||
stopExt, //komenda z zewnątrz
|
||||
stopError //z powodu błędu w obliczeniu drogi hamowania
|
||||
};
|
||||
|
||||
enum TAction
|
||||
{//przechowanie aktualnego stanu AI od poprzedniego przebłysku świadomości
|
||||
actUnknown, //stan nieznany (domyślny na początku)
|
||||
actPantUp, //podnieś pantograf (info dla użytkownika)
|
||||
actConv, //załącz przetwornicę (info dla użytkownika)
|
||||
actCompr, //załącz sprężarkę (info dla użytkownika)
|
||||
actSleep, //śpi (wygaszony)
|
||||
actDrive, //jazda
|
||||
actGo, //ruszanie z miejsca
|
||||
actSlow, //przyhamowanie przed ograniczeniem
|
||||
sctStop, //hamowanie w celu precyzyjnego zatrzymania
|
||||
actIdle, //luzowanie składu przed odjazdem
|
||||
actRelease, //luzowanie składu po zmniejszeniu prędkości
|
||||
actConnect, //dojazd w celu podczepienia
|
||||
actWait, //czekanie na przystanku
|
||||
actReady, //zgłoszona gotowość do odjazdu od kierownika
|
||||
actEmergency, //hamowanie awaryjne
|
||||
actGoUphill, //ruszanie pod górę
|
||||
actTest, //hamowanie kontrolne (podczas jazdy)
|
||||
actTrial //próba hamulca (na postoju)
|
||||
};
|
||||
|
||||
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 fAcc;
|
||||
int iFlags;
|
||||
//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
|
||||
vector3 vPos; //współrzędne XYZ do liczenia odległości
|
||||
struct
|
||||
{
|
||||
TTrack *trTrack; //wskaźnik na tor o zmiennej prędkości (zwrotnica, obrotnica)
|
||||
TEvent *evEvent; //połączenie z eventem albo komórką pamięci
|
||||
};
|
||||
void __fastcall CommandCheck();
|
||||
public:
|
||||
void __fastcall Clear();
|
||||
bool __fastcall Update(vector3 *p,vector3 *dir,double &len);
|
||||
bool __fastcall Set(TEvent *e,double d);
|
||||
void __fastcall Set(TTrack *t,double d,int f);
|
||||
AnsiString __fastcall TableText();
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const bool Aggressive=true;
|
||||
static const bool Easyman=false;
|
||||
static const bool AIdriver=true;
|
||||
static const bool Humandriver=false;
|
||||
static const int maxorders=32; //ilość rozkazów w tabelce
|
||||
static const int maxdriverfails=4; //ile błędów może zrobić AI zanim zmieni nastawienie
|
||||
extern bool WriteLogFlag; //logowanie parametrów fizycznych
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class TController
|
||||
{
|
||||
private: //obsługa tabelki prędkości (musi mieć możliwość odhaczania stacji w rozkładzie)
|
||||
TSpeedPos *sSpeedTable; //najbliższe zmiany prędkości
|
||||
int iSpeedTableSize; //wielkość tabelki
|
||||
int iFirst; //aktualna pozycja w tabeli (modulo iSpeedTableSize)
|
||||
int iLast; //ostatnia wypełniona pozycja w tabeli <iFirst (modulo iSpeedTableSize)
|
||||
int iTableDirection; //kierunek zapełnienia tabelki względem pojazdu z AI
|
||||
double fLastVel; //prędkość na poprzednio sprawdzonym torze
|
||||
TTrack *tLast; //ostatni analizowany tor
|
||||
TEvent *eSignSkip; //można pominąć ten SBL po zatrzymaniu
|
||||
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
|
||||
double fAccGravity; //przyspieszenie składowej stycznej grawitacji
|
||||
public:
|
||||
TEvent *eSignNext; //sygnał zmieniający prędkość, do pokazania na [F2]
|
||||
AnsiString asNextStop; //nazwa następnego punktu zatrzymania wg rozkładu
|
||||
int iStationStart; //numer pierwszej stacji pokazywanej na podglądzie rozkładu
|
||||
private: //parametry sterowania pojazdem (stan, hamowanie)
|
||||
double fShuntVelocity; //maksymalna prędkość manewrowania, zależy m.in. od składu
|
||||
int iVehicles; //ilość pojazdów w składzie
|
||||
int iEngineActive; //ABu: Czy silnik byl juz zalaczony; Ra: postęp w załączaniu
|
||||
//vector3 vMechLoc; //pozycja pojazdu do liczenia odległości od semafora (?)
|
||||
bool Psyche;
|
||||
int iDrivigFlags; //flagi bitowe ruchu
|
||||
double fDriverBraking; //po pomnożeniu przez v^2 [km/h] daje ~drogę hamowania [m]
|
||||
double fDriverDist; //dopuszczalna odległość podjechania do przeszkody
|
||||
double fVelMax; //maksymalna prędkość składu (sprawdzany każdy pojazd)
|
||||
double fBrakeDist; //przybliżona droga hamowania
|
||||
double fAccThreshold; //próg opóźnienia dla zadziałania hamulca
|
||||
public:
|
||||
double fLastStopExpDist; //odległość wygasania ostateniego przystanku
|
||||
double ReactionTime; //czas reakcji Ra: czego i na co? świadomości AI
|
||||
double fBrakeTime; //wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
|
||||
private:
|
||||
double fReady; //poziom odhamowania wagonów
|
||||
bool Ready; //ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow
|
||||
double LastUpdatedTime; //czas od ostatniego logu
|
||||
double ElapsedTime; //czas od poczatku logu
|
||||
double deltalog; //przyrost czasu
|
||||
double LastReactionTime;
|
||||
double fActionTime; //czas używany przy regulacji prędkości i zamykaniu drzwi
|
||||
TAction eAction; //aktualny stan
|
||||
bool HelpMeFlag; //wystawiane True jesli cos niedobrego sie dzieje
|
||||
public:
|
||||
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
|
||||
private:
|
||||
TDynamicObject *pVehicle; //pojazd w którym siedzi sterujący
|
||||
TDynamicObject *pVehicles[2]; //skrajne pojazdy w składzie (niekoniecznie bezpośrednio sterowane)
|
||||
TMoverParameters *mvControlling; //jakim pojazdem steruje (może silnikowym w EZT)
|
||||
TMoverParameters *mvOccupied; //jakim pojazdem hamuje
|
||||
Mtable::TTrainParameters *TrainParams; //rozkład jazdy zawsze jest, nawet jeśli pusty
|
||||
//int TrainNumber; //numer rozkladowy tego pociagu
|
||||
//AnsiString OrderCommand; //komenda pobierana z pojazdu
|
||||
//double OrderValue; //argument komendy
|
||||
int iRadioChannel; //numer aktualnego kanału radiowego
|
||||
TTextSound *tsGuardSignal; //komunikat od kierownika
|
||||
int iGuardRadio; //numer kanału radiowego kierownika (0, gdy nie używa radia)
|
||||
public:
|
||||
double AccPreferred; //preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji)
|
||||
double AccDesired; //przyspieszenie, jakie ma utrzymywać (<0:nie przyspieszaj,<-0.1:hamuj)
|
||||
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:
|
||||
double VelforDriver; //prędkość, używana przy zmianie kierunku (ograniczenie przy nieznajmości szlaku?)
|
||||
double VelSignal; //predkość zadawana przez semafor (funkcją SetVelocity())
|
||||
double VelLimit; //predkość zadawana przez event jednokierunkowego ograniczenia prędkości (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 punktu, <0:podana wartość
|
||||
public:
|
||||
double ActualProximityDist; //odległość brana pod uwagę przy wyliczaniu prędkości i przyspieszenia
|
||||
private:
|
||||
vector3 vCommandLocation; //polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego odnosi sie komenda
|
||||
TOrders OrderList[maxorders]; //lista rozkazów
|
||||
int OrderPos,OrderTop; //rozkaz aktualny oraz wolne miejsce do wstawiania nowych
|
||||
std::ofstream LogFile; //zapis parametrow fizycznych
|
||||
std::ofstream AILogFile; //log AI
|
||||
bool MaxVelFlag;
|
||||
bool MinVelFlag;
|
||||
int iDirection; //kierunek jazdy względem sprzęgów pojazdu, w którym siedzi AI (1=przód,-1=tył)
|
||||
int iDirectionOrder; //żadany kierunek jazdy (służy do zmiany kierunku)
|
||||
int iVehicleCount; //ilość pojazdów do odłączenia albo zabrania ze składu (-1=wszystkie)
|
||||
int iCoupler; //maska sprzęgu, jaką należy użyć przy łączeniu (po osiągnięciu trybu Connect), 0 gdy jazda bez łączenia
|
||||
int iDriverFailCount; //licznik błędów AI
|
||||
bool Need_TryAgain; //true, jeśli druga pozycja w elektryku nie załapała
|
||||
bool Need_BrakeRelease;
|
||||
public:
|
||||
double fMinProximityDist; //minimalna oległość do przeszkody, jaką należy zachować
|
||||
double fOverhead1; //informacja o napięciu w sieci trakcyjnej (0=brak drutu, zatrzymaj!)
|
||||
double fOverhead2; //informacja o sposobie jazdy (-1=normalnie, 0=bez prądu, >0=z opuszczonym i ograniczeniem prędkości)
|
||||
int iOverheadZero; //suma bitowa jezdy bezprądowej, bity ustawiane przez pojazdy z podniesionymi pantografami
|
||||
int iOverheadDown; //suma bitowa opuszczenia pantografów, bity ustawiane przez pojazdy z podniesionymi pantografami
|
||||
double fVoltage; //uśrednione napięcie sieci: przy spadku poniżej wartości minimalnej opóźnić rozruch o losowy czas
|
||||
private:
|
||||
double fMaxProximityDist; //akceptowalna odległość stanięcia przed przeszkodą
|
||||
TStopReason eStopReason; //powód zatrzymania przy ustawieniu zerowej prędkości
|
||||
AnsiString VehicleName;
|
||||
double fVelPlus; //dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
|
||||
double fVelMinus; //margines obniżenia prędkości, powodujący załączenie napędu
|
||||
double fWarningDuration; //ile czasu jeszcze trąbić
|
||||
double fStopTime; //czas postoju przed dalszą jazdą (np. na przystanku)
|
||||
double WaitingTime; //zliczany czas oczekiwania do samoistnego ruszenia
|
||||
double WaitingExpireTime; //maksymlany czas oczekiwania do samoistnego ruszenia
|
||||
//TEvent* eSignLast; //ostatnio znaleziony sygnał, o ile nie minięty
|
||||
private: //---//---//---//---// koniec zmiennych, poniżej metody //---//---//---//---//
|
||||
void __fastcall SetDriverPsyche();
|
||||
bool __fastcall PrepareEngine();
|
||||
bool __fastcall ReleaseEngine();
|
||||
bool __fastcall IncBrake();
|
||||
bool __fastcall DecBrake();
|
||||
bool __fastcall IncSpeed();
|
||||
bool __fastcall DecSpeed(bool force=false);
|
||||
void __fastcall SpeedSet();
|
||||
void __fastcall Doors(bool what);
|
||||
void __fastcall RecognizeCommand(); //odczytuje komende przekazana lokomotywie
|
||||
void __fastcall Activation(); //umieszczenie obsady w odpowiednim członie
|
||||
void __fastcall ControllingSet(); //znajduje człon do sterowania
|
||||
void __fastcall AutoRewident(); //ustawia hamulce w składzie
|
||||
public:
|
||||
Mtable::TTrainParameters* __fastcall Timetable() {return TrainParams;};
|
||||
void __fastcall PutCommand(AnsiString NewCommand,double NewValue1,double NewValue2,const _mover::TLocation &NewLocation,TStopReason reason=stopComm);
|
||||
bool __fastcall PutCommand(AnsiString NewCommand,double NewValue1,double NewValue2,const vector3 *NewLocation,TStopReason reason=stopComm);
|
||||
bool __fastcall UpdateSituation(double dt); //uruchamiac przynajmniej raz na sekundę
|
||||
//procedury dotyczace rozkazow dla maszynisty
|
||||
void __fastcall SetVelocity(double NewVel,double NewVelNext,TStopReason r=stopNone); //uaktualnia informacje o prędkości
|
||||
bool __fastcall SetProximityVelocity(double NewDist,double NewVelNext); //uaktualnia informacje o prędkości przy nastepnym semaforze
|
||||
public:
|
||||
void __fastcall JumpToNextOrder();
|
||||
void __fastcall JumpToFirstOrder();
|
||||
void __fastcall OrderPush(TOrders NewOrder);
|
||||
void __fastcall OrderNext(TOrders NewOrder);
|
||||
TOrders __fastcall OrderCurrentGet();
|
||||
TOrders __fastcall OrderNextGet();
|
||||
bool __fastcall CheckVehicles(TOrders user=Wait_for_orders);
|
||||
private:
|
||||
void __fastcall CloseLog();
|
||||
void __fastcall OrderCheck();
|
||||
public:
|
||||
void __fastcall OrdersInit(double fVel);
|
||||
void __fastcall OrdersClear();
|
||||
void __fastcall OrdersDump();
|
||||
__fastcall TController
|
||||
(bool AI,
|
||||
TDynamicObject *NewControll,
|
||||
bool InitPsyche,
|
||||
bool primary=true //czy ma aktywnie prowadzić?
|
||||
);
|
||||
AnsiString __fastcall OrderCurrent();
|
||||
void __fastcall WaitingSet(double Seconds);
|
||||
private:
|
||||
AnsiString __fastcall Order2Str(TOrders Order);
|
||||
void __fastcall DirectionForward(bool forward);
|
||||
int __fastcall OrderDirectionChange(int newdir,TMoverParameters *Vehicle);
|
||||
void __fastcall Lights(int head,int rear);
|
||||
double __fastcall Distance(vector3 &p1,vector3 &n,vector3 &p2);
|
||||
private: //Ra: metody obsługujące skanowanie toru
|
||||
TEvent* __fastcall CheckTrackEvent(double fDirection,TTrack *Track);
|
||||
bool __fastcall TableCheckEvent(TEvent *e);
|
||||
bool __fastcall TableAddNew();
|
||||
bool __fastcall TableNotFound(TEvent *e);
|
||||
void __fastcall TableClear();
|
||||
TEvent* __fastcall TableCheckTrackEvent(double fDirection,TTrack *Track);
|
||||
void __fastcall TableTraceRoute(double fDistance,TDynamicObject *pVehicle=NULL);
|
||||
void __fastcall TableCheck(double fDistance);
|
||||
TCommandType __fastcall TableUpdate(double &fVelDes,double &fDist,double &fNext,double &fAcc);
|
||||
void __fastcall TablePurger();
|
||||
private: //Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu
|
||||
bool __fastcall BackwardTrackBusy(TTrack *Track);
|
||||
TEvent* __fastcall CheckTrackEventBackward(double fDirection,TTrack *Track);
|
||||
TTrack* __fastcall BackwardTraceRoute(double &fDistance,double &fDirection,TTrack *Track,TEvent*&Event);
|
||||
void __fastcall SetProximityVelocity(double dist,double vel,const vector3 *pos);
|
||||
TCommandType __fastcall BackwardScan();
|
||||
public:
|
||||
void __fastcall PhysicsLog();
|
||||
AnsiString __fastcall StopReasonText();
|
||||
__fastcall ~TController();
|
||||
AnsiString __fastcall NextStop();
|
||||
void __fastcall TakeControl(bool yes);
|
||||
AnsiString __fastcall Relation();
|
||||
AnsiString __fastcall TrainName();
|
||||
int __fastcall StationCount();
|
||||
int __fastcall StationIndex();
|
||||
bool __fastcall IsStop();
|
||||
bool __fastcall Primary() {return this?bool(iDrivigFlags&movePrimary):false;};
|
||||
int inline __fastcall DrivigFlags() {return iDrivigFlags;};
|
||||
void __fastcall MoveTo(TDynamicObject *to);
|
||||
void __fastcall DirectionInitial();
|
||||
AnsiString __fastcall TableText(int i);
|
||||
int __fastcall CrossRoute(TTrack *tr);
|
||||
void __fastcall RouteSwitch(int d);
|
||||
AnsiString __fastcall OwnerName();
|
||||
};
|
||||
|
||||
#endif
|
||||
4358
DynObj.cpp
Normal file
4358
DynObj.cpp
Normal file
File diff suppressed because it is too large
Load Diff
440
DynObj.h
Normal file
440
DynObj.h
Normal file
@@ -0,0 +1,440 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef DynObjH
|
||||
#define DynObjH
|
||||
|
||||
#include "Classes.h"
|
||||
#include "TrkFoll.h"
|
||||
#include "QueryParserComp.hpp"
|
||||
#include "Mover.h"
|
||||
#include "TractionPower.h"
|
||||
//McZapkie:
|
||||
#include "MdlMngr.h"
|
||||
#include "RealSound.h"
|
||||
#include "AdvSound.h"
|
||||
#include "Button.h"
|
||||
#include "AirCoupler.h"
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
const ANIM_TYPES=7; //Ra: ilość typów animacji
|
||||
const ANIM_WHEELS =0; //koła
|
||||
const ANIM_DOORS =1; //drzwi
|
||||
const ANIM_LEVERS =2; //elementy obracane (wycieraczki, koła skrętne, przestawiacze, klocki ham.)
|
||||
const ANIM_BUFFERS=3; //elementy przesuwane (zderzaki)
|
||||
const ANIM_BOOGIES=4; //wózki (są skręcane w dwóch osiach)
|
||||
const ANIM_PANTS =5; //pantografy
|
||||
const ANIM_STEAMS =6; //napęd parowozu
|
||||
|
||||
class TAnim;
|
||||
typedef void (__closure *TUpdate)(TAnim *pAnim); //typ funkcji aktualizującej położenie submodeli
|
||||
|
||||
//McZapkie-250202
|
||||
const MaxAxles=16; //ABu 280105: zmienione z 8 na 16
|
||||
//const MaxAnimatedAxles=16; //i to tez.
|
||||
//const MaxAnimatedDoors=16; //NBMX wrzesien 2003
|
||||
/*
|
||||
Ra: Utworzyć klasę wyposażenia opcjonalnego, z której będą dziedziczyć klasy drzwi,
|
||||
pantografów, napędu parowozu i innych ruchomych części pojazdów. Klasy powinny być
|
||||
pseudo-wirtualne, bo wirtualne mogą obniżać wydajnosść.
|
||||
Przy wczytywaniu MMD utworzyć tabelę wskaźnikow na te dodatki. Przy wyświetlaniu
|
||||
pojazdu wykonywać Update() na kolejnych obiektach wyposażenia.
|
||||
Rozważyć użycie oddzielnych modeli dla niektórych pojazdów (np. lokomotywy), co
|
||||
zaoszczędziło by czas ustawiania animacji na modelu wspólnym dla kilku pojazdów,
|
||||
szczególnie dla pojazdów w danej chwili nieruchomych (przy dużym zagęszczeniu
|
||||
modeli na stacjach na ogół przewaga jest tych nieruchomych).
|
||||
*/
|
||||
class TAnimValveGear
|
||||
{//współczynniki do animacji parowozu (wartości przykładowe dla Pt47)
|
||||
int iValues; //ilość liczb (wersja):
|
||||
float fKorbowodR; //długość korby (pół skoku tłoka) [m]: 0.35
|
||||
float fKorbowodL; //długość korbowodu [m]: 3.8
|
||||
float fDrazekR; //promień mimośrodu (drążka) [m]: 0.18
|
||||
float fDrazekL; //dł. drążka mimośrodowego [m]: 2.55889
|
||||
float fJarzmoV; //wysokość w pionie osi jarzma od osi koła [m]: 0.751
|
||||
float fJarzmoH; //odległość w poziomie osi jarzma od osi koła [m]: 2.550
|
||||
float fJarzmoR; //promień jarzma do styku z drążkiem [m]: 0.450
|
||||
float fJarzmoA; //kąt mimośrodu względem kąta koła [°]: -96.77416667
|
||||
float fWdzidloL; //długość wodzidła [m]: 2.0
|
||||
float fWahaczH; //długość wahacza (góra) [m]: 0.14
|
||||
float fSuwakH; //wysokość osi suwaka ponad osią koła [m]: 0.62
|
||||
float fWahaczL; //długość wahacza (dół) [m]: 0.84
|
||||
float fLacznikL; //długość łącznika wahacza [m]: 0.75072
|
||||
float fRamieL; //odległość ramienia krzyżulca od osi koła [m]: 0.192
|
||||
float fSuwakL; //odległość środka tłoka/suwaka od osi koła [m]: 5.650
|
||||
//dołożyć parametry drążka nastawnicy
|
||||
//albo nawet zrobić dynamiczną tablicę float[] i w nią pakować wszelkie współczynniki, potem używać indeksów
|
||||
//współczynniki mogą być wspólne dla 2-4 tłoków, albo każdy tłok może mieć odrębne
|
||||
};
|
||||
|
||||
class TAnimPant
|
||||
{//współczynniki do animacji pantografu
|
||||
public:
|
||||
vector3 vPos; //Ra: współrzędne punktu zerowego pantografu (X dodatnie dla przedniego)
|
||||
double fLenL1; //długość dolnego ramienia 1, odczytana z modelu
|
||||
double fLenU1; //długość górnego ramienia 1, odczytana z modelu
|
||||
double fLenL2; //długość dolnego ramienia 2, odczytana z modelu
|
||||
double fLenU2; //długość górnego ramienia 2, odczytana z modelu
|
||||
double fHoriz; //przesunięcie ślizgu w długości pojazdu względem osi obrotu dolnego ramienia
|
||||
double fHeight; //wysokość ślizgu ponad oś obrotu, odejmowana od wysokości drutu
|
||||
double fWidth; //połowa szerokości roboczej ślizgu, do wykrycia ześlizgnięcia się drutu
|
||||
double fAngleL0; //Ra: początkowy kąt dolnego ramienia (odejmowany przy animacji)
|
||||
double fAngleU0; //Ra: początkowy kąt górnego ramienia (odejmowany przy animacji)
|
||||
double PantTraction; //Winger 170204: wysokość drutu ponad punktem na wysokości vPos.y p.g.s.
|
||||
double PantWys; //Ra: aktualna wysokość uniesienia ślizgu do porównania z wysokością drutu
|
||||
double fAngleL; //Winger 160204: aktualny kąt ramienia dolnego
|
||||
double fAngleU; //Ra: aktualny kąt ramienia górnego
|
||||
double NoVoltTime; //czas od utraty kontaktu z drutem
|
||||
TTraction *hvPowerWire; //aktualnie podczepione druty, na razie tu
|
||||
float fWidthExtra; //dodatkowy rozmiar poziomy poza część roboczą (fWidth)
|
||||
float fHeightExtra[5]; //łamana symulująca kształt nabieżnika
|
||||
//double fHorizontal; //Ra 2015-01: położenie drutu względem osi pantografu
|
||||
void __fastcall AKP_4E();
|
||||
};
|
||||
|
||||
class TAnim
|
||||
{//klasa animowanej części pojazdu (koła, drzwi, pantografy, burty, napęd parowozu, siłowniki itd.)
|
||||
public:
|
||||
union
|
||||
{
|
||||
TSubModel *smAnimated; //animowany submodel (jeśli tylko jeden, np. oś)
|
||||
TSubModel **smElement; //jeśli animowanych elementów jest więcej (pantograf, napęd parowozu)
|
||||
int iShift; //przesunięcie przed przydzieleniem wskaźnika
|
||||
};
|
||||
union
|
||||
{//parametry animacji
|
||||
TAnimValveGear *pValveGear; //współczynniki do animacji parowozu
|
||||
double *dWheelAngle; //wskaźnik na kąt obrotu osi
|
||||
float *fParam; //różne parametry dla animacji
|
||||
TAnimPant *fParamPants; //różne parametry dla animacji
|
||||
};
|
||||
union
|
||||
{//wskaźnik na obiekt odniesienia
|
||||
double *fDoubleBase; //jakiś double w fizyce
|
||||
float *fFloatBase; //jakiś float w fizyce
|
||||
int *iIntBase; //jakiś int w fizyce
|
||||
};
|
||||
//void _fastcall Update(); //wskaźnik do funkcji aktualizacji animacji
|
||||
int iFlags; //flagi animacji
|
||||
float fMaxDist; //do jakiej odległości wykonywana jest animacja
|
||||
float fSpeed; //parametr szybkości animacji
|
||||
int iNumber; //numer kolejny obiektu
|
||||
public:
|
||||
__fastcall TAnim();
|
||||
__fastcall ~TAnim();
|
||||
TUpdate yUpdate; //metoda TDynamicObject aktualizująca animację
|
||||
int __fastcall TypeSet(int i,int fl=0); //ustawienie typu
|
||||
void __fastcall Parovoz(); //wykonanie obliczeń animacji
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class TDynamicObject
|
||||
{//klasa pojazdu
|
||||
private: //położenie pojazdu w świecie oraz parametry ruchu
|
||||
vector3 vPosition; //Ra: pozycja pojazdu liczona zaraz po przesunięciu
|
||||
vector3 vCoulpler[2]; //współrzędne sprzęgów do liczenia zderzeń czołowych
|
||||
vector3 vUp,vFront,vLeft; //wektory jednostkowe ustawienia pojazdu
|
||||
int iDirection; //kierunek pojazdu względem czoła składu (1=zgodny,0=przeciwny)
|
||||
TTrackShape ts; //parametry toru przekazywane do fizyki
|
||||
TTrackParam tp; //parametry toru przekazywane do fizyki
|
||||
TTrackFollower Axle0; //oś z przodu (od sprzęgu 0)
|
||||
TTrackFollower Axle1; //oś z tyłu (od sprzęgu 1)
|
||||
int iAxleFirst; //numer pierwszej osi w kierunku ruchu (oś wiążąca pojazd z torem i wyzwalająca eventy)
|
||||
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,int &CouplNr);
|
||||
public: //parametry położenia pojazdu dostępne publicznie
|
||||
AnsiString asTrack; //nazwa toru początkowego; wywalić?
|
||||
AnsiString asDestination; //dokąd pojazd ma być kierowany "(stacja):(tor)"
|
||||
matrix4x4 mMatrix; //macierz przekształcenia do renderowania modeli
|
||||
TMoverParameters *MoverParameters; //parametry fizyki ruchu oraz przeliczanie
|
||||
//TMoverParameters *pControlled; //wskaźnik do sterowanego członu silnikowego
|
||||
TDynamicObject *NextConnected; //pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||
TDynamicObject *PrevConnected; //pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||
int NextConnectedNo; //numer sprzęgu podłączonego z tyłu
|
||||
int PrevConnectedNo; //numer sprzęgu podłączonego z przodu
|
||||
double fScanDist; //odległość skanowania torów na obecność innych pojazdów
|
||||
|
||||
public: //modele składowe pojazdu
|
||||
TModel3d *mdModel; //model pudła
|
||||
TModel3d *mdLoad; //model zmiennego ładunku
|
||||
TModel3d *mdPrzedsionek; //model przedsionków dla EZT - może użyć mdLoad zamiast?
|
||||
TModel3d *mdKabina; //model kabiny dla użytkownika; McZapkie-030303: to z train.h
|
||||
TModel3d *mdLowPolyInt; //ABu 010305: wnetrze lowpoly
|
||||
float fShade; //zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?)
|
||||
|
||||
private: //zmienne i metody do animacji submodeli; Ra: sprzatam animacje w pojeździe
|
||||
public: //tymczasowo udostępnione do wyszukiwania drutu
|
||||
int iAnimType[ANIM_TYPES]; //0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki
|
||||
private:
|
||||
int iAnimations; //liczba obiektów animujących
|
||||
TAnim *pAnimations; //obiekty animujące (zawierają wskaźnik do funkcji wykonującej animację)
|
||||
TSubModel **pAnimated; //lista animowanych submodeli (może być ich więcej niż obiektów animujących)
|
||||
double dWheelAngle[3]; //kąty obrotu kół: 0=przednie toczne, 1=napędzające i wiązary, 2=tylne toczne
|
||||
void UpdateNone(TAnim *pAnim) {}; //animacja pusta (funkcje ustawiania submodeli, gdy blisko kamery)
|
||||
void UpdateAxle(TAnim *pAnim); //animacja osi
|
||||
void UpdateBoogie(TAnim *pAnim); //animacja wózka
|
||||
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 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ść)
|
||||
void UpdateLeverEnum(TAnim *pAnim); //animacja gałki zależna od int (lista kątów)
|
||||
private: //Ra: ciąg dalszy animacji, dopiero do ogarnięcia
|
||||
//ABuWozki 060504
|
||||
vector3 bogieRot[2]; //Obroty wozkow w/m korpusu
|
||||
TSubModel *smBogie[2]; //Wyszukiwanie max 2 wozkow
|
||||
TSubModel *smWahacze[4]; //wahacze (np. nogi, dźwignia w drezynie)
|
||||
TSubModel *smBrakeMode; //Ra 15-01: nastawa hamulca też
|
||||
TSubModel *smLoadMode; //Ra 15-01: nastawa próżny/ładowny
|
||||
double fWahaczeAmp;
|
||||
//Winger 160204 - pantografy
|
||||
double pantspeedfactor;
|
||||
//animacje typu przesuw
|
||||
TSubModel *smBuforLewy[2];
|
||||
TSubModel *smBuforPrawy[2];
|
||||
TAnimValveGear *pValveGear;
|
||||
vector3 vFloor; //podłoga dla ładunku
|
||||
public:
|
||||
TAnim *pants; //indeks obiektu animującego dla pantografu 0
|
||||
double NoVoltTime; //czas od utraty zasilania
|
||||
double dDoorMoveL; //NBMX
|
||||
double dDoorMoveR; //NBMX
|
||||
TSubModel *smBrakeSet; //nastawa hamulca (wajcha)
|
||||
TSubModel *smLoadSet; //nastawa ładunku (wajcha)
|
||||
TSubModel *smWiper; //wycieraczka (poniekąd też wajcha)
|
||||
//Ra: koneic animacji do ogarnięcia
|
||||
|
||||
private:
|
||||
void ABuLittleUpdate(double ObjSqrDist);
|
||||
bool btnOn; //ABu: czy byly uzywane buttony, jesli tak, to po renderingu wylacz
|
||||
//bo ten sam model moze byc jeszcze wykorzystany przez inny obiekt!
|
||||
double __fastcall ComputeRadius(vector3 p1,vector3 p2,vector3 p3,vector3 p4);
|
||||
|
||||
TButton btCoupler1; //sprzegi
|
||||
TButton btCoupler2;
|
||||
TAirCoupler btCPneumatic1; //sprzegi powietrzne //yB - zmienione z Button na AirCoupler - krzyzyki
|
||||
TAirCoupler btCPneumatic2;
|
||||
TAirCoupler btCPneumatic1r; //ABu: to zeby nie bylo problemow przy laczeniu wagonow,
|
||||
TAirCoupler btCPneumatic2r; // jesli beda polaczone sprzegami 1<->1 lub 0<->0
|
||||
TAirCoupler btPneumatic1; //ABu: sprzegi powietrzne zolte
|
||||
TAirCoupler btPneumatic2;
|
||||
TAirCoupler btPneumatic1r; //ABu: analogicznie jak 4 linijki wyzej
|
||||
TAirCoupler btPneumatic2r;
|
||||
|
||||
TButton btCCtrl1; //sprzegi sterowania
|
||||
TButton btCCtrl2;
|
||||
TButton btCPass1; //mostki przejsciowe
|
||||
TButton btCPass2;
|
||||
char cp1, sp1, cp2, sp2; //ustawienia węży
|
||||
|
||||
TButton btEndSignals11; //sygnalu konca pociagu
|
||||
TButton btEndSignals13;
|
||||
TButton btEndSignals21;
|
||||
TButton btEndSignals23;
|
||||
TButton btEndSignals1; //zeby bylo kompatybilne ze starymi modelami...
|
||||
TButton btEndSignals2;
|
||||
TButton btEndSignalsTab1; //sygnaly konca pociagu (blachy)
|
||||
TButton btEndSignalsTab2;
|
||||
TButton btHeadSignals11; //oswietlenie czolowe - przod
|
||||
TButton btHeadSignals12;
|
||||
TButton btHeadSignals13;
|
||||
TButton btHeadSignals21; //oswietlenie czolowe - tyl
|
||||
TButton btHeadSignals22;
|
||||
TButton btHeadSignals23;
|
||||
TSubModel *smMechanik0; //Ra: mechanik wbudowany w model jako submodel?
|
||||
TSubModel *smMechanik1; //mechanik od strony sprzęgu 1
|
||||
double enginevolume; //MC: pomocnicze zeby gladziej silnik buczal
|
||||
|
||||
int iAxles; //McZapkie: to potem mozna skasowac i zastapic iNumAxles
|
||||
double dRailLength;
|
||||
double dRailPosition[MaxAxles]; //licznik pozycji osi w/m szyny
|
||||
double dWheelsPosition[MaxAxles]; //pozycja osi w/m srodka pojazdu
|
||||
TRealSound rsStukot[MaxAxles]; //dzwieki poszczegolnych osi //McZapkie-270202
|
||||
TRealSound rsSilnik; //McZapkie-010302 - silnik
|
||||
TRealSound rsWentylator; //McZapkie-030302
|
||||
TRealSound rsPisk; //McZapkie-260302
|
||||
TRealSound rsDerailment; //McZapkie-051202
|
||||
TRealSound rsPrzekladnia;
|
||||
TAdvancedSound sHorn1;
|
||||
TAdvancedSound sHorn2;
|
||||
TAdvancedSound sCompressor; //NBMX wrzesien 2003
|
||||
TAdvancedSound sConverter;
|
||||
TAdvancedSound sSmallCompressor;
|
||||
TAdvancedSound sDepartureSignal;
|
||||
TAdvancedSound sTurbo;
|
||||
|
||||
//Winger 010304
|
||||
// TRealSound rsPanTup; //PSound sPantUp;
|
||||
TRealSound sPantUp;
|
||||
TRealSound sPantDown;
|
||||
TRealSound rsDoorOpen; //Ra: przeniesione z kabiny
|
||||
TRealSound rsDoorClose;
|
||||
|
||||
double eng_vol_act;
|
||||
double eng_frq_act;
|
||||
double eng_dfrq;
|
||||
double eng_turbo;
|
||||
void __fastcall ABuBogies();
|
||||
void __fastcall ABuModelRoll();
|
||||
vector3 modelShake;
|
||||
|
||||
bool renderme; //yB - czy renderowac
|
||||
//TRealSound sBrakeAcc; //dźwięk przyspieszacza
|
||||
PSound sBrakeAcc;
|
||||
bool bBrakeAcc;
|
||||
TRealSound rsUnbrake; //yB - odglos luzowania
|
||||
float ModCamRot;
|
||||
int iInventory; //flagi bitowe posiadanych submodeli (np. świateł)
|
||||
void __fastcall TurnOff();
|
||||
public:
|
||||
int iHornWarning; //numer syreny do użycia po otrzymaniu sygnału do jazdy
|
||||
bool bEnabled; //Ra: wyjechał na portal i ma być usunięty
|
||||
protected:
|
||||
|
||||
//TTrackFollower Axle2; //dwie osie z czterech (te są protected)
|
||||
//TTrackFollower Axle3; //Ra: wyłączyłem, bo kąty są liczone w Segment.cpp
|
||||
int iNumAxles; //ilość osi
|
||||
int CouplCounter;
|
||||
AnsiString asModel;
|
||||
public:
|
||||
void ABuScanObjects(int ScanDir,double ScanDist);
|
||||
protected:
|
||||
TDynamicObject* __fastcall ABuFindObject(TTrack *Track,int ScanDir,Byte &CouplFound,double &dist);
|
||||
void __fastcall ABuCheckMyTrack();
|
||||
|
||||
public:
|
||||
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);
|
||||
double __fastcall NextDistance(double d=-1.0);
|
||||
void __fastcall SetdMoveLen(double dMoveLen) {MoverParameters->dMoveLen=dMoveLen;}
|
||||
void __fastcall ResetdMoveLen() {MoverParameters->dMoveLen=0;}
|
||||
double __fastcall GetdMoveLen() {return MoverParameters->dMoveLen;}
|
||||
|
||||
int __fastcall GetPneumatic(bool front, bool red);
|
||||
void __fastcall SetPneumatic(bool front, bool red);
|
||||
AnsiString asName;
|
||||
AnsiString __fastcall GetName()
|
||||
{
|
||||
return this?asName:AnsiString("");
|
||||
};
|
||||
|
||||
TRealSound rsDiesielInc; //youBy
|
||||
TRealSound rscurve; //youBy
|
||||
// std::ofstream PneuLogFile; //zapis parametrow pneumatycznych
|
||||
//youBy - dym
|
||||
//TSmoke Smog;
|
||||
//float EmR;
|
||||
//vector3 smokeoffset;
|
||||
|
||||
TDynamicObject* __fastcall ABuScanNearestObject(TTrack *Track, double ScanDir, double ScanDist, int &CouplNr);
|
||||
TDynamicObject* __fastcall GetFirstDynamic(int cpl_type);
|
||||
//TDynamicObject* __fastcall GetFirstCabDynamic(int cpl_type);
|
||||
void ABuSetModelShake(vector3 mShake);
|
||||
|
||||
|
||||
//McZapkie-010302
|
||||
TController *Mechanik;
|
||||
TController *ctOwner; //wskażnik na obiekt zarządzający składem
|
||||
bool MechInside;
|
||||
//McZapkie-270202
|
||||
bool Controller;
|
||||
bool bDisplayCab; //czy wyswietlac kabine w train.cpp
|
||||
int iCabs; //maski bitowe modeli kabin
|
||||
TTrack *MyTrack; //McZapkie-030303: tor na ktorym stoi, ABu
|
||||
AnsiString asBaseDir;
|
||||
GLuint ReplacableSkinID[5]; //McZapkie:zmienialne nadwozie
|
||||
int iAlpha; //maska przezroczystości tekstur
|
||||
int iMultiTex; //<0 tekstury wskazane wpisem, >0 tekstury z przecinkami, =0 jedna
|
||||
int iOverheadMask; //maska przydzielana przez AI pojazdom posiadającym pantograf, aby wymuszały jazdę bezprądową
|
||||
TTractionParam tmpTraction;
|
||||
double fAdjustment; //korekcja - docelowo przenieść do TrkFoll.cpp wraz z odległością od poprzedniego
|
||||
__fastcall TDynamicObject();
|
||||
__fastcall ~TDynamicObject();
|
||||
double __fastcall TDynamicObject::Init
|
||||
(//zwraca długość pojazdu albo 0, jeśli błąd
|
||||
AnsiString Name, AnsiString BaseDir, AnsiString asReplacableSkin, AnsiString Type_Name,
|
||||
TTrack *Track, double fDist, AnsiString DriverType, double fVel, AnsiString TrainName,
|
||||
float Load, AnsiString LoadType,bool Reversed, AnsiString
|
||||
);
|
||||
void __fastcall AttachPrev(TDynamicObject *Object, int iType= 1);
|
||||
bool __fastcall UpdateForce(double dt, double dt1, bool FullVer);
|
||||
void __fastcall LoadUpdate();
|
||||
bool __fastcall Update(double dt, double dt1);
|
||||
bool __fastcall FastUpdate(double dt);
|
||||
void __fastcall Move(double fDistance);
|
||||
void __fastcall FastMove(double fDistance);
|
||||
void __fastcall Render();
|
||||
void __fastcall RenderAlpha();
|
||||
void __fastcall RenderSounds();
|
||||
inline vector3 __fastcall GetPosition() {return vPosition;};
|
||||
inline vector3 __fastcall HeadPosition() {return vCoulpler[iDirection^1];}; //pobranie współrzędnych czoła
|
||||
inline vector3 __fastcall RearPosition() {return vCoulpler[iDirection];}; //pobranie współrzędnych tyłu
|
||||
inline vector3 __fastcall AxlePositionGet() {return iAxleFirst?Axle1.pPosition:Axle0.pPosition;};
|
||||
inline vector3 __fastcall VectorFront() {return vFront;};
|
||||
inline vector3 __fastcall VectorUp() {return vUp;};
|
||||
inline vector3 __fastcall VectorLeft() {return vLeft;};
|
||||
inline double* __fastcall Matrix() {return mMatrix.getArray();};
|
||||
inline double __fastcall GetVelocity() { return MoverParameters->Vel; };
|
||||
inline double __fastcall GetLength() { return MoverParameters->Dim.L; };
|
||||
inline double __fastcall GetWidth() { return MoverParameters->Dim.W; };
|
||||
inline TTrack* __fastcall GetTrack() { return (iAxleFirst?Axle1.GetTrack():Axle0.GetTrack()); };
|
||||
//void __fastcall UpdatePos();
|
||||
|
||||
|
||||
//McZapkie-260202
|
||||
void __fastcall LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName, AnsiString ReplacableSkin);
|
||||
|
||||
inline double __fastcall ABuGetDirection() //ABu.
|
||||
{
|
||||
return (Axle1.GetTrack()==MyTrack?Axle1.GetDirection():Axle0.GetDirection());
|
||||
};
|
||||
// inline double __fastcall ABuGetTranslation() //ABu.
|
||||
// {//zwraca przesunięcie wózka względem Point1 toru
|
||||
// return (Axle1.GetTrack()==MyTrack?Axle1.GetTranslation():Axle0.GetTranslation());
|
||||
// };
|
||||
inline double __fastcall RaDirectionGet()
|
||||
{//zwraca kierunek pojazdu na torze z aktywną osą
|
||||
return iAxleFirst?Axle1.GetDirection():Axle0.GetDirection();
|
||||
};
|
||||
inline double __fastcall RaTranslationGet()
|
||||
{//zwraca przesunięcie wózka względem Point1 toru z aktywną osią
|
||||
return iAxleFirst?Axle1.GetTranslation():Axle0.GetTranslation();
|
||||
};
|
||||
inline TTrack* __fastcall RaTrackGet()
|
||||
{//zwraca tor z aktywną osią
|
||||
return iAxleFirst?Axle1.GetTrack():Axle0.GetTrack();
|
||||
};
|
||||
void CouplersDettach(double MinDist,int MyScanDir);
|
||||
void __fastcall RadioStop();
|
||||
void __fastcall RaLightsSet(int head,int rear);
|
||||
//void __fastcall RaAxleEvent(TEvent *e);
|
||||
TDynamicObject* __fastcall FirstFind(int &coupler_nr);
|
||||
float __fastcall GetEPP(); //wyliczanie sredniego cisnienia w PG
|
||||
int __fastcall DirectionSet(int d); //ustawienie kierunku w składzie
|
||||
int __fastcall DirectionGet() {return iDirection+iDirection-1;}; //odczyt kierunku w składzie
|
||||
int DettachStatus(int dir);
|
||||
int Dettach(int dir);
|
||||
TDynamicObject* __fastcall Neightbour(int &dir);
|
||||
void __fastcall CoupleDist();
|
||||
TDynamicObject* __fastcall ControlledFind();
|
||||
void __fastcall ParamSet(int what,int into);
|
||||
int __fastcall RouteWish(TTrack *tr); //zapytanie do AI, po którym segmencie skrzyżowania jechać
|
||||
void __fastcall DestinationSet(AnsiString to);
|
||||
AnsiString __fastcall TextureTest(AnsiString &name);
|
||||
void __fastcall OverheadTrack(float o);
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
137
EU07.bpr
Normal file
137
EU07.bpr
Normal file
@@ -0,0 +1,137 @@
|
||||
<?xml version='1.0' encoding='utf-8' ?>
|
||||
<!-- C++Builder XML Project -->
|
||||
<PROJECT>
|
||||
<MACROS>
|
||||
<VERSION value="BCB.05.03"/>
|
||||
<PROJECT value="D:\EU07\EU07.exe"/>
|
||||
<OBJFILES value="QueryParserComp.obj McZapkie\mtable.obj McZapkie\_mover.obj
|
||||
McZapkie\hamulce.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"/>
|
||||
<RESFILES value="EU07.res"/>
|
||||
<IDLFILES value=""/>
|
||||
<IDLGENFILES value=""/>
|
||||
<DEFFILE value=""/>
|
||||
<RESDEPEN value="$(RESFILES)"/>
|
||||
<LIBFILES value="opengl\glut32.lib DirectX\Dsound.lib"/>
|
||||
<LIBRARIES value="dclocx50.bpi bcbsmp50.bpi VCLX50.lib bcbsmp50.lib Vcl50.lib"/>
|
||||
<SPARELIBS value="Vcl50.lib bcbsmp50.lib VCLX50.lib bcbsmp50.bpi dclocx50.bpi"/>
|
||||
<PACKAGES value="Vcl50.bpi Vclx50.bpi"/>
|
||||
<PATHCPP value=".;opengl;Console"/>
|
||||
<PATHPAS value=".;McZapkie"/>
|
||||
<PATHRC value=".;"/>
|
||||
<PATHASM value=".;"/>
|
||||
<DEBUGLIBPATH value="$(BCB)\lib\debug"/>
|
||||
<RELEASELIBPATH value="$(BCB)\lib\release"/>
|
||||
<LINKER value="tlink32"/>
|
||||
<USERDEFINES value="GLEW_STATIC;_DEBUG"/>
|
||||
<SYSDEFINES value="NO_STRICT;_RTLDLL"/>
|
||||
<MAINSOURCE value="EU07.cpp"/>
|
||||
<INCLUDEPATH value="Console;opengl;McZapkie;$(BCB)\include;$(BCB)\include\vcl"/>
|
||||
<LIBPATH value="Console;opengl;McZapkie;$(BCB)\lib\obj;$(BCB)\lib"/>
|
||||
<WARNINGS value="-w-par"/>
|
||||
</MACROS>
|
||||
<OPTIONS>
|
||||
<IDLCFLAGS value="-IConsole -Iopengl -IMcZapkie -I$(BCB)\include -I$(BCB)\include\vcl
|
||||
-src_suffix cpp -DGLEW_STATIC -D_DEBUG -boa"/>
|
||||
<CFLAG1 value="-O2 -H=$(BCB)\lib\vcl50.csm -Hc -Vx -Ve -X- -r- -a1 -6 -b- -k -y -v -vi-
|
||||
-c -tW -tWM"/>
|
||||
<PFLAGS value="-$Y+ -$W -$O- -v -JPHNE -M"/>
|
||||
<RFLAGS value=""/>
|
||||
<AFLAGS value="/mx /w2 /zi"/>
|
||||
<LFLAGS value="-D"" -aa -Tpe -x -Gn -v"/>
|
||||
</OPTIONS>
|
||||
<LINKER>
|
||||
<ALLOBJ value="c0w32.obj Memmgr.Lib sysinit.obj $(OBJFILES)"/>
|
||||
<ALLRES value="$(RESFILES)"/>
|
||||
<ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cp32mti.lib"/>
|
||||
</LINKER>
|
||||
<IDEOPTIONS>
|
||||
[Version Info]
|
||||
IncludeVerInfo=1
|
||||
AutoIncBuild=0
|
||||
MajorVer=15
|
||||
MinorVer=3
|
||||
Release=1166
|
||||
Build=469
|
||||
Debug=1
|
||||
PreRelease=0
|
||||
Special=0
|
||||
Private=0
|
||||
DLL=0
|
||||
Locale=1045
|
||||
CodePage=1250
|
||||
|
||||
[Version Info Keys]
|
||||
CompanyName=EU07 Team
|
||||
FileDescription=MaSzyna EU07-424
|
||||
FileVersion=15.3.1166.469
|
||||
InternalName=9th by Ra + SPKS + MP
|
||||
LegalCopyright=
|
||||
LegalTrademarks=
|
||||
OriginalFilename=eu07.exe
|
||||
ProductName=MaSzyna EU07-424
|
||||
ProductVersion=15.3
|
||||
Comments=
|
||||
|
||||
[HistoryLists\hlIncludePath]
|
||||
Count=1
|
||||
Item0=Console;opengl;McZapkie;$(BCB)\include;$(BCB)\include\vcl
|
||||
|
||||
[HistoryLists\hlLibraryPath]
|
||||
Count=1
|
||||
Item0=Console;opengl;McZapkie;$(BCB)\lib\obj;$(BCB)\lib
|
||||
|
||||
[HistoryLists\hlDebugSourcePath]
|
||||
Count=2
|
||||
Item0=McZapkie\
|
||||
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
|
||||
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\
|
||||
|
||||
[Debugging]
|
||||
DebugSourceDirs=McZapkie\
|
||||
|
||||
[Parameters]
|
||||
RunParams=
|
||||
HostApplication=
|
||||
RemoteHost=
|
||||
RemotePath=
|
||||
RemoteDebug=0
|
||||
|
||||
[Compiler]
|
||||
ShowInfoMsgs=0
|
||||
LinkDebugVcl=0
|
||||
LinkCGLIB=0
|
||||
|
||||
[CORBA]
|
||||
AddServerUnit=1
|
||||
AddClientUnit=1
|
||||
PrecompiledHeaders=1
|
||||
|
||||
[Language]
|
||||
ActiveLang=
|
||||
ProjectLang=
|
||||
RootDir=
|
||||
</IDEOPTIONS>
|
||||
</PROJECT>
|
||||
725
EU07.cpp
Normal file
725
EU07.cpp
Normal file
@@ -0,0 +1,725 @@
|
||||
//---------------------------------------------------------------------------
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
||||
|
||||
*/
|
||||
|
||||
#include "opengl/glew.h"
|
||||
#include "opengl/glut.h"
|
||||
#include "opengl/ARB_Multisample.h"
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#include "Globals.h"
|
||||
#include "Console.h"
|
||||
#include "QueryParserComp.hpp"
|
||||
#include "Mover.h"
|
||||
#include "Logs.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include <dsound.h> //_clear87() itp.
|
||||
|
||||
USERES("EU07.res");
|
||||
USEUNIT("dumb3d.cpp");
|
||||
USEUNIT("Camera.cpp");
|
||||
USEUNIT("Texture.cpp");
|
||||
USEUNIT("World.cpp");
|
||||
USELIB("opengl\glut32.lib");
|
||||
USEUNIT("Model3d.cpp");
|
||||
USEUNIT("MdlMngr.cpp");
|
||||
USEUNIT("Train.cpp");
|
||||
USEUNIT("wavread.cpp");
|
||||
USEUNIT("Timer.cpp");
|
||||
USEUNIT("Event.cpp");
|
||||
USEUNIT("MemCell.cpp");
|
||||
USEUNIT("Logs.cpp");
|
||||
USELIB("DirectX\Dsound.lib");
|
||||
USEUNIT("Spring.cpp");
|
||||
USEUNIT("Button.cpp");
|
||||
USEUNIT("Globals.cpp");
|
||||
USEUNIT("Gauge.cpp");
|
||||
USEUNIT("AnimModel.cpp");
|
||||
USEUNIT("Ground.cpp");
|
||||
USEUNIT("TrkFoll.cpp");
|
||||
USEUNIT("Segment.cpp");
|
||||
USEUNIT("Sound.cpp");
|
||||
USEUNIT("AdvSound.cpp");
|
||||
USEUNIT("Track.cpp");
|
||||
USEUNIT("DynObj.cpp");
|
||||
USEUNIT("RealSound.cpp");
|
||||
USEUNIT("EvLaunch.cpp");
|
||||
USEUNIT("QueryParserComp.pas");
|
||||
USEUNIT("FadeSound.cpp");
|
||||
USEUNIT("Traction.cpp");
|
||||
USEUNIT("TractionPower.cpp");
|
||||
USEUNIT("parser.cpp");
|
||||
USEUNIT("sky.cpp");
|
||||
USEUNIT("AirCoupler.cpp");
|
||||
USEUNIT("opengl\glew.c");
|
||||
USEUNIT("ResourceManager.cpp");
|
||||
USEUNIT("VBO.cpp");
|
||||
USEUNIT("McZapkie\mtable.pas");
|
||||
USEUNIT("TextureDDS.cpp");
|
||||
USEUNIT("opengl\ARB_Multisample.cpp");
|
||||
USEUNIT("Float3d.cpp");
|
||||
USEUNIT("Classes.cpp");
|
||||
USEUNIT("Driver.cpp");
|
||||
USEUNIT("Names.cpp");
|
||||
USEUNIT("Console.cpp");
|
||||
USEUNIT("Mover.cpp");
|
||||
USEUNIT("McZapkie\_mover.pas");
|
||||
USEUNIT("McZapkie\hamulce.pas");
|
||||
USEUNIT("Console\PoKeys55.cpp");
|
||||
USEUNIT("Forth.cpp");
|
||||
USEUNIT("Console\LPT.cpp");
|
||||
//---------------------------------------------------------------------------
|
||||
#include "World.h"
|
||||
|
||||
HDC hDC=NULL; // Private GDI Device Context
|
||||
HGLRC hRC=NULL; // Permanent Rendering Context
|
||||
HWND hWnd=NULL; // Holds Our Window Handle
|
||||
|
||||
TWorld World;
|
||||
|
||||
|
||||
//bool active=TRUE; //window active flag set to TRUE by default
|
||||
bool fullscreen=TRUE; //fullscreen flag set to fullscreen mode by default
|
||||
int WindowWidth= 800;
|
||||
int WindowHeight= 600;
|
||||
int Bpp= 32;
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
|
||||
|
||||
//#include "dbgForm.h"
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
|
||||
{
|
||||
_clear87();
|
||||
_control87(MCW_EM,MCW_EM);
|
||||
glewInit();
|
||||
//hunter-271211: przeniesione
|
||||
//AllocConsole();
|
||||
//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN);
|
||||
|
||||
// ShaXbee-121209: Wlaczenie obslugi tablic wierzcholkow
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
Global::pWorld=&World; //Ra: wskaŸnik potrzebny do usuwania pojazdów
|
||||
return World.Init(hWnd,hDC); //true jeœli wszystko pójdzie dobrze
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
GLvoid ReSizeGLScene(GLsizei width,GLsizei height) // resize and initialize the GL Window
|
||||
{
|
||||
WindowWidth=width;
|
||||
WindowHeight=height;
|
||||
if (height==0) // prevent a divide by zero by
|
||||
height=1; // making height equal one
|
||||
glViewport(0,0,width,height); // Reset The Current Viewport
|
||||
glMatrixMode(GL_PROJECTION); // select the Projection Matrix
|
||||
glLoadIdentity(); // reset the Projection Matrix
|
||||
//calculate the aspect ratio of the window
|
||||
gluPerspective(45.0f,(GLdouble)width/(GLdouble)height,0.2f,2500.0f);
|
||||
glMatrixMode(GL_MODELVIEW); // select the Modelview Matrix
|
||||
glLoadIdentity(); // reset the Modelview Matrix
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
GLvoid KillGLWindow(GLvoid) // properly kill the window
|
||||
{
|
||||
if (hRC) // Do We Have A Rendering Context?
|
||||
{
|
||||
if (!wglMakeCurrent(NULL,NULL)) // are we able to release the DC and RC contexts?
|
||||
{
|
||||
ErrorLog("Fail: window releasing");
|
||||
MessageBox(NULL,"Release of DC and RC failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
if (!wglDeleteContext(hRC)) // are we able to delete the RC?
|
||||
{
|
||||
ErrorLog("Fail: rendering context releasing");
|
||||
MessageBox(NULL,"Release rendering context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
hRC=NULL; // set RC to NULL
|
||||
}
|
||||
|
||||
if (hDC && !ReleaseDC(hWnd,hDC)) // are we able to release the DC?
|
||||
{
|
||||
ErrorLog("Fail: device context releasing");
|
||||
MessageBox(NULL,"Release device context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
|
||||
hDC=NULL; // set DC to NULL
|
||||
}
|
||||
|
||||
if (hWnd && !DestroyWindow(hWnd)) // are we able to destroy the window?
|
||||
{
|
||||
ErrorLog("Fail: window destroying");
|
||||
MessageBox(NULL,"Could not release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
|
||||
hWnd=NULL; // set hWnd to NULL
|
||||
}
|
||||
|
||||
if (fullscreen) // Are We In Fullscreen Mode?
|
||||
{
|
||||
ChangeDisplaySettings(NULL,0); // if so switch back to the desktop
|
||||
ShowCursor(TRUE); // show mouse pointer
|
||||
}
|
||||
// KillFont();
|
||||
}
|
||||
|
||||
/* This code creates our OpenGL Window. Parameters are: *
|
||||
* title - title to appear at the top of the window *
|
||||
* width - width of the GL Window or fullscreen mode *
|
||||
* height - height of the GL Window or fullscreen mode *
|
||||
* bits - number of bits to use for color (8/16/24/32) *
|
||||
* fullscreenflag - use fullscreen mode (TRUE) or windowed mode (FALSE) */
|
||||
|
||||
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
|
||||
{
|
||||
GLuint PixelFormat; // holds the results after searching for a match
|
||||
HINSTANCE hInstance; // holds the instance of the application
|
||||
WNDCLASS wc; // windows class structure
|
||||
DWORD dwExStyle; // window extended style
|
||||
DWORD dwStyle; // window style
|
||||
RECT WindowRect; // grabs rectangle upper left / lower right values
|
||||
WindowRect.left=(long)0; // set left value to 0
|
||||
WindowRect.right=(long)width; // set right value to requested width
|
||||
WindowRect.top=(long)0; // set top value to 0
|
||||
WindowRect.bottom=(long)height; // set bottom value to requested height
|
||||
|
||||
fullscreen=fullscreenflag; // set the global fullscreen flag
|
||||
|
||||
hInstance =GetModuleHandle(NULL); // grab an instance for our window
|
||||
wc.style =CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // redraw on size, and own DC for window.
|
||||
wc.lpfnWndProc =(WNDPROC) WndProc; // wndproc handles messages
|
||||
wc.cbClsExtra =0; // no extra window data
|
||||
wc.cbWndExtra =0; // no extra window data
|
||||
wc.hInstance =hInstance; // set the instance
|
||||
wc.hIcon =LoadIcon(NULL, IDI_WINLOGO); // load the default icon
|
||||
wc.hCursor =LoadCursor(NULL, IDC_ARROW); // load the arrow pointer
|
||||
wc.hbrBackground=NULL; // no background required for GL
|
||||
wc.lpszMenuName =NULL; // we don't want a menu
|
||||
wc.lpszClassName="EU07"; //nazwa okna do komunikacji zdalnej // Set The Class Name
|
||||
|
||||
if (!arbMultisampleSupported) //tylko dla pierwszego okna
|
||||
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
|
||||
{
|
||||
ErrorLog("Fail: window class registeration");
|
||||
MessageBox(NULL,"Failed to register the window class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
return FALSE; // Return FALSE
|
||||
}
|
||||
|
||||
if (fullscreen) // Attempt Fullscreen Mode?
|
||||
{
|
||||
DEVMODE dmScreenSettings; // device mode
|
||||
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // makes sure memory's cleared
|
||||
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // size of the devmode structure
|
||||
|
||||
//tolaris-240403: poprawka na odswiezanie monitora
|
||||
// locate primary monitor...
|
||||
if (Global::bAdjustScreenFreq)
|
||||
{
|
||||
POINT point; point.x=0; point.y=0;
|
||||
MONITORINFOEX monitorinfo; monitorinfo.cbSize=sizeof(MONITORINFOEX);
|
||||
::GetMonitorInfo( ::MonitorFromPoint(point,MONITOR_DEFAULTTOPRIMARY),&monitorinfo);
|
||||
// ..and query for highest supported refresh rate
|
||||
unsigned int refreshrate=0;
|
||||
int i=0;
|
||||
while (::EnumDisplaySettings(monitorinfo.szDevice,i,&dmScreenSettings))
|
||||
{
|
||||
if (i>0)
|
||||
if (dmScreenSettings.dmPelsWidth==(unsigned int)width)
|
||||
if (dmScreenSettings.dmPelsHeight==(unsigned int)height)
|
||||
if (dmScreenSettings.dmBitsPerPel==(unsigned int)bits)
|
||||
if (dmScreenSettings.dmDisplayFrequency>refreshrate)
|
||||
refreshrate=dmScreenSettings.dmDisplayFrequency;
|
||||
++i;
|
||||
}
|
||||
// fill refresh rate info for screen mode change
|
||||
dmScreenSettings.dmDisplayFrequency=refreshrate;
|
||||
dmScreenSettings.dmFields=DM_DISPLAYFREQUENCY;
|
||||
}
|
||||
dmScreenSettings.dmPelsWidth =width; // selected screen width
|
||||
dmScreenSettings.dmPelsHeight=height; // selected screen height
|
||||
dmScreenSettings.dmBitsPerPel=bits; // selected bits per pixel
|
||||
dmScreenSettings.dmFields=dmScreenSettings.dmFields|DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
|
||||
|
||||
// Try to set selected mode and get results. NOTE: CDS_FULLSCREEN gets rid of start bar.
|
||||
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
|
||||
{
|
||||
// If the mode fails, offer two options. Quit or use windowed mode.
|
||||
ErrorLog("Fail: full screen");
|
||||
if (MessageBox(NULL,"The requested fullscreen mode is not supported by\nyour video card. Use windowed mode instead?","EU07",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
|
||||
{
|
||||
fullscreen=FALSE; // Windowed Mode Selected. Fullscreen = FALSE
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pop Up A Message Box Letting User Know The Program Is Closing.
|
||||
Error("Program will now close.");
|
||||
return FALSE; // Return FALSE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fullscreen) // Are We Still In Fullscreen Mode?
|
||||
{
|
||||
dwExStyle=WS_EX_APPWINDOW; // Window Extended Style
|
||||
dwStyle=WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // Windows Style
|
||||
ShowCursor(FALSE); // Hide Mouse Pointer
|
||||
}
|
||||
else
|
||||
{
|
||||
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
|
||||
dwStyle=WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // Windows Style
|
||||
}
|
||||
|
||||
AdjustWindowRectEx(&WindowRect,dwStyle,FALSE,dwExStyle); // Adjust Window To True Requested Size
|
||||
|
||||
// Create The Window
|
||||
if (NULL==(hWnd=CreateWindowEx(dwExStyle, // Extended Style For The Window
|
||||
"EU07", // Class Name
|
||||
title, // Window Title
|
||||
dwStyle | // Defined Window Style
|
||||
WS_CLIPSIBLINGS | // Required Window Style
|
||||
WS_CLIPCHILDREN, // Required Window Style
|
||||
0, 0, // Window Position
|
||||
WindowRect.right-WindowRect.left, // Calculate Window Width
|
||||
WindowRect.bottom-WindowRect.top, // Calculate Window Height
|
||||
NULL, // No Parent Window
|
||||
NULL, // No Menu
|
||||
hInstance, // Instance
|
||||
NULL))) // Dont Pass Anything To WM_CREATE
|
||||
{
|
||||
KillGLWindow(); // Reset The Display
|
||||
ErrorLog("Fail: window creation");
|
||||
MessageBox(NULL,"Window creation error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
return FALSE; // Return FALSE
|
||||
}
|
||||
|
||||
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
|
||||
{
|
||||
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
|
||||
1, // Version Number
|
||||
PFD_DRAW_TO_WINDOW | // Format Must Support Window
|
||||
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
|
||||
PFD_DOUBLEBUFFER, // Must Support Double Buffering
|
||||
PFD_TYPE_RGBA, // Request An RGBA Format
|
||||
bits, // Select Our Color Depth
|
||||
0, 0, 0, 0, 0, 0, // Color Bits Ignored
|
||||
0, // No Alpha Buffer
|
||||
0, // Shift Bit Ignored
|
||||
0, // No Accumulation Buffer
|
||||
0, 0, 0, 0, // Accumulation Bits Ignored
|
||||
24, // 32Bit Z-Buffer (Depth Buffer)
|
||||
0, // No Stencil Buffer
|
||||
0, // No Auxiliary Buffer
|
||||
PFD_MAIN_PLANE, // Main Drawing Layer
|
||||
0, // Reserved
|
||||
0, 0, 0 // Layer Masks Ignored
|
||||
};
|
||||
|
||||
if (NULL==(hDC=GetDC(hWnd))) // Did We Get A Device Context?
|
||||
{
|
||||
KillGLWindow(); // Reset The Display
|
||||
ErrorLog("Fail: device context");
|
||||
MessageBox(NULL,"Can't create a GL device context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
return FALSE; // Return FALSE
|
||||
}
|
||||
|
||||
/*
|
||||
Our first pass, Multisampling hasn't been created yet, so we create a window normally
|
||||
If it is supported, then we're on our second pass
|
||||
that means we want to use our pixel format for sampling
|
||||
so set PixelFormat to arbMultiSampleformat instead
|
||||
*/
|
||||
if (!arbMultisampleSupported)
|
||||
{
|
||||
if (NULL==(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?
|
||||
{
|
||||
KillGLWindow(); // Reset The Display
|
||||
ErrorLog("Fail: pixelformat");
|
||||
MessageBox(NULL,"Can't find a suitable pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
return FALSE; // Return FALSE
|
||||
}
|
||||
}
|
||||
else
|
||||
PixelFormat=arbMultisampleFormat;
|
||||
|
||||
if (!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format?
|
||||
{
|
||||
KillGLWindow(); // Reset The Display
|
||||
ErrorLog("Fail: pixelformat");
|
||||
MessageBox(NULL,"Can't set the pixelformat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
return FALSE; // Return FALSE
|
||||
}
|
||||
|
||||
if (NULL==(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context?
|
||||
{
|
||||
KillGLWindow(); // Reset The Display
|
||||
ErrorLog("Fail: OpenGL rendering context creation");
|
||||
MessageBox(NULL,"Can't create a GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
return FALSE; // Return FALSE
|
||||
}
|
||||
|
||||
if (!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context
|
||||
{
|
||||
KillGLWindow(); // Reset The Display
|
||||
ErrorLog("Fail: OpenGL rendering context activation");
|
||||
MessageBox(NULL,"Can't activate the GL rendering context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
return FALSE; // Return FALSE
|
||||
}
|
||||
|
||||
/*
|
||||
Now that our window is created, we want to queary what samples are available
|
||||
we call our InitMultiSample window
|
||||
if we return a valid context, we want to destroy our current window
|
||||
and create a new one using the multisample interface.
|
||||
*/
|
||||
if (Global::iMultisampling)
|
||||
if (!arbMultisampleSupported)
|
||||
if ((Global::iMultisampling=InitMultisample(hInstance,hWnd,pfd,1<<Global::iMultisampling))!=0)
|
||||
{
|
||||
//WriteConsoleOnly("Opening second window for multisampling of "+AnsiString(Global::iMultisampling)+" samples.");
|
||||
KillGLWindow(); // reset the display
|
||||
return CreateGLWindow(title,width,height,bits,fullscreenflag); //rekurencja
|
||||
}
|
||||
|
||||
ShowWindow(hWnd,SW_SHOW); // show the window
|
||||
SetForegroundWindow(hWnd); // slightly higher priority
|
||||
SetFocus(hWnd); // sets keyboard focus to the window
|
||||
ReSizeGLScene(width, height); // set up our perspective GL screen
|
||||
|
||||
if (!InitGL()) // initialize our newly created GL Window
|
||||
{
|
||||
KillGLWindow(); // reset the display
|
||||
ErrorLog("Fail: OpenGL initialization");
|
||||
MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||
return FALSE; // return FALSE
|
||||
}
|
||||
return TRUE; //success
|
||||
}
|
||||
|
||||
static int mx=0, my=0;
|
||||
static POINT mouse;
|
||||
|
||||
static int test= 0;
|
||||
/**/
|
||||
// ************ Globals ************
|
||||
//
|
||||
#define MYDISPLAY 1
|
||||
|
||||
|
||||
PCOPYDATASTRUCT pDane;
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hWnd, //handle for this window
|
||||
UINT uMsg, //message for this window
|
||||
WPARAM wParam, //additional message information
|
||||
LPARAM lParam) //additional message information
|
||||
{
|
||||
TRect rect;
|
||||
switch (uMsg) //check for windows messages
|
||||
{
|
||||
case WM_PASTE: //[Ctrl]+[V] potrzebujemy do innych celów
|
||||
return 0;
|
||||
case WM_COPYDATA: //obs³uga danych przes³anych przez program steruj¹cy
|
||||
pDane=(PCOPYDATASTRUCT)lParam;
|
||||
if (pDane->dwData=='EU07') //sygnatura danych
|
||||
World.OnCommandGet((DaneRozkaz*)(pDane->lpData));
|
||||
break;
|
||||
case WM_ACTIVATE: //watch for window activate message
|
||||
//case WM_ACTIVATEAPP:
|
||||
{//Ra: uzale¿nienie aktywnoœci od bycia na wierzchu
|
||||
Global::bActive=(LOWORD(wParam)!=WA_INACTIVE);
|
||||
if (Global::bInactivePause) //jeœli ma byæ pauzowanie okna w tle
|
||||
if (Global::bActive)
|
||||
Global::iPause&=~4; //odpauzowanie, gdy jest na pierwszym planie
|
||||
else
|
||||
Global::iPause|=4; //w³¹czenie pauzy, gdy nieaktywy
|
||||
if (Global::bActive)
|
||||
SetCursorPos(mx,my);
|
||||
ShowCursor(!Global::bActive);
|
||||
/*
|
||||
if (!HIWORD(wParam)) //check minimization state
|
||||
active=TRUE; //program is active
|
||||
else
|
||||
active=FALSE; //program is no longer active
|
||||
*/
|
||||
return 0; // return to the message loop
|
||||
}
|
||||
case WM_SYSCOMMAND: //intercept system commands
|
||||
{
|
||||
switch (wParam) //check system calls
|
||||
{
|
||||
case 61696: //F10
|
||||
World.OnKeyDown(VK_F10);
|
||||
return 0;
|
||||
case SC_SCREENSAVE: //screensaver trying to start?
|
||||
case SC_MONITORPOWER: //monitor trying to enter powersave?
|
||||
return 0; //prevent from happening
|
||||
}
|
||||
break; //exit
|
||||
}
|
||||
case WM_CLOSE: // did we receive a close message?
|
||||
{
|
||||
PostQuitMessage(0); //send a quit message [Alt]+[F4]
|
||||
return 0; //jump back
|
||||
}
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
//mx= 100;//Global::iWindowWidth/2;
|
||||
//my= 100;//Global::iWindowHeight/2;
|
||||
//SetCursorPos(Global::iWindowWidth/2,Global::iWindowHeight/2);
|
||||
//m_x= LOWORD(lParam);
|
||||
//m_y= HIWORD(lParam);
|
||||
GetCursorPos(&mouse);
|
||||
if (Global::bActive && ((mouse.x!=mx) || (mouse.y!=my)))
|
||||
{
|
||||
World.OnMouseMove(double(mouse.x-mx)*0.005,double(mouse.y-my)*0.01);
|
||||
SetCursorPos(mx,my);
|
||||
}
|
||||
return 0; // jump back
|
||||
}
|
||||
case WM_KEYUP :
|
||||
if (Global::bActive)
|
||||
{
|
||||
World.OnKeyUp(wParam);
|
||||
return 0;
|
||||
}
|
||||
case WM_KEYDOWN :
|
||||
if (Global::bActive)
|
||||
{
|
||||
if (wParam!=17) //bo naciœniêcia [Ctrl] nie ma po co przekazywaæ
|
||||
if (wParam!=145) //[Scroll Lock] te¿ nie
|
||||
World.OnKeyDown(wParam);
|
||||
switch (wParam)
|
||||
{
|
||||
case VK_ESCAPE: //[Esc] pauzuje tylko bez Debugmode
|
||||
if (DebugModeFlag) break;
|
||||
case 19: //[Pause]
|
||||
if (Global::iPause&1) //jeœli pauza startowa
|
||||
Global::iPause&=~1; //odpauzowanie, gdy po wczytaniu mia³o nie startowaæ
|
||||
else if (!(Global::iMultiplayer&2)) //w multiplayerze pauza nie ma sensu
|
||||
if (!Console::Pressed(VK_CONTROL)) //z [Ctrl] to radiostop jest
|
||||
//Ra: poni¿sze nie ma sensu, bo brak komunikacji natychmiast zapauzuje ponownie
|
||||
//if (Global::iPause&8) //jeœli pauza zwi¹zana z brakiem komunikacji z PoKeys
|
||||
// Global::iPause&=~10; //odpauzowanie pauzy PoKeys (chyba nic nie da) i ewentualnie klawiszowej równie¿
|
||||
//else
|
||||
Global::iPause^=2; //zmiana stanu zapauzowania
|
||||
if (Global::iPause) //jak pauza
|
||||
Global::iTextMode=VK_F1; //to wyœwietliæ zegar i informacjê
|
||||
break;
|
||||
case VK_F7:
|
||||
if (DebugModeFlag)
|
||||
{//siatki wyœwietlane tyko w trybie testowym
|
||||
Global::bWireFrame=!Global::bWireFrame;
|
||||
++Global::iReCompile; //odœwie¿yæ siatki
|
||||
//Ra: jeszcze usun¹æ siatki ze skompilowanych obiektów!
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0; // jump back
|
||||
case WM_CHAR:
|
||||
{
|
||||
/*
|
||||
switch ((TCHAR) wParam)
|
||||
{
|
||||
// case 'q':
|
||||
// done= true;
|
||||
// KillGLWindow();
|
||||
// PostQuitMessage(0);
|
||||
// DestroyWindow( hWnd );
|
||||
// break;
|
||||
};
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
case WM_SIZE: //resize the OpenGL window
|
||||
{
|
||||
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height
|
||||
if (GetWindowRect(hWnd,&rect))
|
||||
{//Ra: zmiana rozmiaru okna bez przesuwania myszy
|
||||
//mx=WindowWidth/2+rect.left; // horizontal position
|
||||
//my=WindowHeight/2+rect.top; // vertical position
|
||||
//SetCursorPos(mx,my);
|
||||
}
|
||||
return 0; //jump back
|
||||
}
|
||||
case WM_MOVE: //przesuwanie okna?
|
||||
{
|
||||
mx=WindowWidth/2+LOWORD(lParam); // horizontal position
|
||||
my=WindowHeight/2+HIWORD(lParam); // vertical position
|
||||
//SetCursorPos(mx,my);
|
||||
break;
|
||||
}
|
||||
case WM_PAINT:
|
||||
{//odrysowanie okna
|
||||
break;
|
||||
}
|
||||
//case WM_ERASEBKGND: //Process this message to keep Windows from erasing background.
|
||||
case MM_JOY1BUTTONDOWN:
|
||||
{
|
||||
//WriteLog("Joystick button "+AnsiString(wParam));
|
||||
break;
|
||||
}
|
||||
case WM_CREATE:
|
||||
/* Capture the joystick. If this fails, beep and display
|
||||
* error, then quit.
|
||||
*/
|
||||
if (joySetCapture(hWnd,JOYSTICKID1,0,FALSE))
|
||||
{
|
||||
//MessageBeep(MB_ICONEXCLAMATION);
|
||||
//MessageBox(hWnd,"Couldn't capture the joystick",NULL,MB_OK|MB_ICONEXCLAMATION);
|
||||
//return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// pass all unhandled messages to DefWindowProc
|
||||
return DefWindowProc(hWnd,uMsg,wParam,lParam);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
int WINAPI WinMain( HINSTANCE hInstance, //instance
|
||||
HINSTANCE hPrevInstance, //previous instance
|
||||
LPSTR lpCmdLine, //command line parameters
|
||||
int nCmdShow) //window show state
|
||||
{
|
||||
MSG msg; //windows message structure
|
||||
BOOL done=FALSE; //bool variable to exit loop
|
||||
fullscreen=true;
|
||||
DecimalSeparator= '.';
|
||||
/* //Ra: tutaj to nie dzia³a - zwraca NULL
|
||||
//najpierw ustalmy wersjê OpenGL
|
||||
AnsiString glver=((char*)glGetString(GL_VERSION));
|
||||
while (glver.LastDelimiter(".")>glver.Pos("."))
|
||||
glver=glver.SubString(1,glver.LastDelimiter(".")-1); //obciêcie od drugiej kropki
|
||||
try {Global::fOpenGL=glver.ToDouble();} catch (...) {Global::fOpenGL=0.0;}
|
||||
Global::bOpenGL_1_5=(Global::fOpenGL>=1.5);
|
||||
*/
|
||||
DeleteFile("errors.txt"); //usuniêcie starego
|
||||
Global::LoadIniFile("eu07.ini"); //teraz dopiero mo¿na przejrzeæ plik z ustawieniami
|
||||
Global::InitKeys("keys.ini"); //wczytanie mapowania klawiszy - jest na sta³e
|
||||
|
||||
//hunter-271211: ukrywanie konsoli
|
||||
if (Global::iWriteLogEnabled&2)
|
||||
{
|
||||
AllocConsole();
|
||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_GREEN);
|
||||
}
|
||||
AnsiString str=lpCmdLine; //parametry uruchomienia
|
||||
if (!str.IsEmpty())
|
||||
{//analizowanie parametrów
|
||||
TQueryParserComp *Parser;
|
||||
Parser=new TQueryParserComp(NULL);
|
||||
Parser->TextToParse=lpCmdLine;
|
||||
Parser->First();
|
||||
while (!Parser->EndOfFile)
|
||||
{
|
||||
str=Parser->GetNextSymbol().LowerCase();
|
||||
if (str==AnsiString("-s"))
|
||||
{//nazwa scenerii
|
||||
str=Parser->GetNextSymbol().LowerCase();
|
||||
strcpy(Global::szSceneryFile,str.c_str());
|
||||
}
|
||||
else if (str==AnsiString("-v"))
|
||||
{//nazwa wybranego pojazdu
|
||||
str=Parser->GetNextSymbol().LowerCase();
|
||||
Global::asHumanCtrlVehicle=str;
|
||||
}
|
||||
else if (str==AnsiString("-modifytga"))
|
||||
{//wykonanie modyfikacji wszystkich plików TGA
|
||||
Global::iModifyTGA=-1; //specjalny tryb wykonania totalnej modyfikacji
|
||||
}
|
||||
else if (str==AnsiString("-e3d"))
|
||||
{//wygenerowanie wszystkich plików E3D
|
||||
if (Global::iConvertModels>0)
|
||||
Global::iConvertModels=-Global::iConvertModels; //specjalny tryb
|
||||
else
|
||||
Global::iConvertModels=-7; //z optymalizacj¹, bananami i prawid³owym Opacity
|
||||
}
|
||||
else
|
||||
Error("Program usage: EU07 [-s sceneryfilepath] [-v vehiclename] [-modifytga] [-e3d]",!Global::iWriteLogEnabled);
|
||||
}
|
||||
delete Parser; //ABu 050205: tego wczesniej nie bylo
|
||||
}
|
||||
/* MC: usunalem tymczasowo bo sie gryzlo z nowym parserem - 8.6.2003
|
||||
AnsiString csp=AnsiString(Global::szSceneryFile);
|
||||
csp=csp.Delete(csp.Pos(AnsiString(strrchr(Global::szSceneryFile,'/')))+1,csp.Length());
|
||||
Global::asCurrentSceneryPath=csp;
|
||||
*/
|
||||
|
||||
fullscreen=Global::bFullScreen;
|
||||
WindowWidth=Global::iWindowWidth;
|
||||
WindowHeight=Global::iWindowHeight;
|
||||
Bpp=Global::iBpp;
|
||||
if (Bpp!=32) Bpp=16;
|
||||
//create our OpenGL window
|
||||
if (!CreateGLWindow(Global::asHumanCtrlVehicle.c_str(),WindowWidth,WindowHeight,Bpp,fullscreen))
|
||||
return 0; //quit if window was not created
|
||||
SetForegroundWindow(hWnd);
|
||||
//McZapkie: proba przeplukania klawiatury
|
||||
Console *pConsole=new Console(); //Ra: nie wiem, czy ma to sens, ale jakoœ zainicjowac trzeba
|
||||
while (Console::Pressed(VK_F10))
|
||||
Error("Keyboard buffer problem - press F10"); //na Windows 98 lubi siê to pojawiaæ
|
||||
int iOldSpeed, iOldDelay;
|
||||
SystemParametersInfo(SPI_GETKEYBOARDSPEED,0,&iOldSpeed,0);
|
||||
SystemParametersInfo(SPI_GETKEYBOARDDELAY,0,&iOldDelay,0);
|
||||
SystemParametersInfo(SPI_SETKEYBOARDSPEED,20,NULL,0);
|
||||
//SystemParametersInfo(SPI_SETKEYBOARDDELAY,10,NULL,0);
|
||||
if (!joyGetNumDevs())
|
||||
WriteLog("No joystick");
|
||||
if (Global::iModifyTGA<0)
|
||||
{//tylko modyfikacja TGA, bez uruchamiania symulacji
|
||||
Global::iMaxTextureSize=64; //¿eby nie zamulaæ pamiêci
|
||||
World.ModifyTGA(); //rekurencyjne przegl¹danie katalogów
|
||||
}
|
||||
else
|
||||
{if (Global::iConvertModels<0)
|
||||
{Global::iConvertModels=-Global::iConvertModels;
|
||||
World.CreateE3D("models\\"); //rekurencyjne przegl¹danie katalogów
|
||||
World.CreateE3D("dynamic\\",true);
|
||||
} //po zrobieniu E3D odpalamy normalnie sceneriê, by j¹ zobaczyæ
|
||||
//else
|
||||
//{//g³ówna pêtla programu
|
||||
Console::On(); //w³¹czenie konsoli
|
||||
while (!done) //loop that runs while done=FALSE
|
||||
{
|
||||
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) //is there a message waiting?
|
||||
{
|
||||
if (msg.message==WM_QUIT) //have we received a quit message?
|
||||
done=TRUE; //if so
|
||||
else //if not, deal with window messages
|
||||
{
|
||||
//if (msg.message==WM_CHAR)
|
||||
//World.OnKeyDown(msg.wParam);
|
||||
TranslateMessage(&msg); //translate the message
|
||||
DispatchMessage(&msg); //dispatch the message
|
||||
}
|
||||
}
|
||||
else //if there are no messages
|
||||
{
|
||||
//draw the scene, watch for quit messages
|
||||
//DrawGLScene()
|
||||
//if (!pause)
|
||||
//if (Global::bInactivePause?Global::bActive:true) //tak nie, bo spada z góry
|
||||
if (World.Update()) // Was There A Quit Received?
|
||||
SwapBuffers(hDC); // Swap Buffers (Double Buffering)
|
||||
else
|
||||
done=true; //[F10] or DrawGLScene signalled a quit
|
||||
}
|
||||
}
|
||||
Console::Off(); //wy³¹czenie konsoli (komunikacji zwrotnej)
|
||||
}
|
||||
SystemParametersInfo(SPI_SETKEYBOARDSPEED,iOldSpeed,NULL,0);
|
||||
SystemParametersInfo(SPI_SETKEYBOARDDELAY,iOldDelay,NULL,0);
|
||||
delete pConsole; //deaktywania sterownika
|
||||
//shutdown
|
||||
KillGLWindow(); //kill the window
|
||||
return (msg.wParam); //exit the program
|
||||
}
|
||||
|
||||
|
||||
184
EvLaunch.cpp
Normal file
184
EvLaunch.cpp
Normal file
@@ -0,0 +1,184 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak and others
|
||||
|
||||
*/
|
||||
|
||||
#include "system.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "mtable.hpp"
|
||||
#include "Timer.h"
|
||||
#include "Globals.h"
|
||||
#include "EvLaunch.h"
|
||||
#include "Event.h"
|
||||
|
||||
#include "Usefull.h"
|
||||
#include "MemCell.h"
|
||||
#include "parser.h"
|
||||
#include "Console.h"
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
__fastcall TEventLauncher::TEventLauncher()
|
||||
{//ustawienie pocz¹tkowych wartoœci dla wszystkich zmiennych
|
||||
iKey=0;
|
||||
DeltaTime=-1;
|
||||
UpdatedTime=0;
|
||||
fVal1=fVal2=0;
|
||||
szText=NULL;
|
||||
iHour=iMinute=-1; //takiego czasu nigdy nie bêdzie
|
||||
dRadius=0;
|
||||
Event1=Event2=NULL;
|
||||
MemCell=NULL;
|
||||
iCheckMask=0;
|
||||
}
|
||||
|
||||
__fastcall TEventLauncher::~TEventLauncher()
|
||||
{
|
||||
SafeDeleteArray(szText);
|
||||
}
|
||||
|
||||
void __fastcall TEventLauncher::Init()
|
||||
{
|
||||
}
|
||||
|
||||
bool __fastcall TEventLauncher::Load(cParser *parser)
|
||||
{//wczytanie wyzwalacza zdarzeñ
|
||||
AnsiString str;
|
||||
std::string token;
|
||||
parser->getTokens();
|
||||
*parser >> dRadius; //promieñ dzia³ania
|
||||
if (dRadius>0.0)
|
||||
dRadius*=dRadius; //do kwadratu, pod warunkiem, ¿e nie jest ujemne
|
||||
parser->getTokens(); //klawisz steruj¹cy
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
if (str!="none")
|
||||
{
|
||||
if (str.Length()==1)
|
||||
iKey=VkKeyScan(str[1]); //jeden znak jest konwertowany na kod klawisza
|
||||
else
|
||||
iKey=str.ToIntDef(0); //a jak wiêcej, to jakby numer klawisza jest
|
||||
}
|
||||
parser->getTokens();
|
||||
*parser >> DeltaTime;
|
||||
if (DeltaTime<0)
|
||||
DeltaTime=-DeltaTime; //dla ujemnego zmieniamy na dodatni
|
||||
else if (DeltaTime>0)
|
||||
{//wartoœæ dodatnia oznacza wyzwalanie o okreœlonej godzinie
|
||||
iMinute=int(DeltaTime)%100; //minuty s¹ najm³odszymi cyframi dziesietnymi
|
||||
iHour=int(DeltaTime-iMinute)/100; //godzina to setki
|
||||
DeltaTime=0; //bez powtórzeñ
|
||||
WriteLog("EventLauncher at "+IntToStr(iHour)+":"+IntToStr(iMinute)); //wyœwietlenie czasu
|
||||
}
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
asEvent1Name=AnsiString(token.c_str()); //pierwszy event
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
asEvent2Name=AnsiString(token.c_str()); //drugi event
|
||||
if ((asEvent2Name=="end")||(asEvent2Name=="condition"))
|
||||
{//drugiego eventu mo¿e nie byæ, bo s¹ z tym problemy, ale ciii...
|
||||
str=asEvent2Name; //rozpoznane s³owo idzie do dalszego przetwarzania
|
||||
asEvent2Name="none"; //a drugiego eventu nie ma
|
||||
}
|
||||
else
|
||||
{//gdy s¹ dwa eventy
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
}
|
||||
if (str==AnsiString("condition"))
|
||||
{//obs³uga wyzwalania warunkowego
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
asMemCellName=AnsiString(token.c_str());
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
SafeDeleteArray(szText);
|
||||
szText=new char[256];
|
||||
strcpy(szText,token.c_str());
|
||||
if (token.compare("*")!=0) //*=nie braæ command pod uwagê
|
||||
iCheckMask|=conditional_memstring;
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
if (token.compare("*")!=0) //*=nie braæ wartoœci 1. pod uwagê
|
||||
{
|
||||
iCheckMask|=conditional_memval1;
|
||||
str=AnsiString(token.c_str());
|
||||
fVal1=str.ToDouble();
|
||||
}
|
||||
else fVal1=0;
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
if (token.compare("*")!=0) //*=nie braæ wartoœci 2. pod uwagê
|
||||
{
|
||||
iCheckMask|=conditional_memval2;
|
||||
str=AnsiString(token.c_str());
|
||||
fVal2=str.ToDouble();
|
||||
}
|
||||
else fVal2=0;
|
||||
parser->getTokens(); //s³owo zamykaj¹ce
|
||||
*parser >> token;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
bool __fastcall TEventLauncher::Render()
|
||||
{//"renderowanie" wyzwalacza
|
||||
bool bCond=false;
|
||||
if (iKey!=0)
|
||||
{
|
||||
if (Global::bActive) //tylko jeœli okno jest aktywne
|
||||
bCond=(Console::Pressed(iKey)); //czy klawisz wciœniêty
|
||||
}
|
||||
if (DeltaTime>0)
|
||||
{
|
||||
if (UpdatedTime>DeltaTime)
|
||||
{
|
||||
UpdatedTime=0; //naliczanie od nowa
|
||||
bCond=true;
|
||||
}
|
||||
else
|
||||
UpdatedTime+=Timer::GetDeltaTime(); //aktualizacja naliczania czasu
|
||||
}
|
||||
else
|
||||
{//jeœli nie cykliczny, to sprawdziæ czas
|
||||
if (GlobalTime->hh==iHour)
|
||||
{if (GlobalTime->mm==iMinute)
|
||||
{//zgodnoϾ czasu uruchomienia
|
||||
if (UpdatedTime<10)
|
||||
{
|
||||
UpdatedTime=20; //czas do kolejnego wyzwolenia?
|
||||
bCond=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
UpdatedTime=1;
|
||||
}
|
||||
if (bCond) //jeœli spe³niony zosta³ warunek
|
||||
{
|
||||
if ((iCheckMask!=0)&&MemCell) //sprawdzanie warunku na komórce pamiêci
|
||||
bCond=MemCell->Compare(szText,fVal1,fVal2,iCheckMask);
|
||||
}
|
||||
return bCond; //sprawdzanie dRadius w Ground.cpp
|
||||
}
|
||||
|
||||
bool __fastcall TEventLauncher::IsGlobal()
|
||||
{//sprawdzenie, czy jest globalnym wyzwalaczem czasu
|
||||
if (DeltaTime==0)
|
||||
if (iHour>=0)
|
||||
if (iMinute>=0)
|
||||
if (dRadius<0.0) //bez ograniczenia zasiêgu
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
36
EvLaunch.h
Normal file
36
EvLaunch.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef EvLaunchH
|
||||
#define EvLaunchH
|
||||
|
||||
#include "Classes.h"
|
||||
|
||||
class TEventLauncher
|
||||
{
|
||||
private:
|
||||
int iKey;
|
||||
double DeltaTime;
|
||||
double UpdatedTime;
|
||||
double fVal1;
|
||||
double fVal2;
|
||||
char *szText;
|
||||
int iHour,iMinute; //minuta uruchomienia
|
||||
public:
|
||||
double dRadius;
|
||||
AnsiString asEvent1Name;
|
||||
AnsiString asEvent2Name;
|
||||
AnsiString asMemCellName;
|
||||
TEvent *Event1;
|
||||
TEvent *Event2;
|
||||
TMemCell *MemCell;
|
||||
int iCheckMask;
|
||||
__fastcall TEventLauncher();
|
||||
__fastcall ~TEventLauncher();
|
||||
void __fastcall Init();
|
||||
bool __fastcall Load(cParser *parser);
|
||||
bool __fastcall Render();
|
||||
bool __fastcall IsGlobal();
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
626
Event.cpp
Normal file
626
Event.cpp
Normal file
@@ -0,0 +1,626 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak and others
|
||||
|
||||
*/
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Event.h"
|
||||
#include "parser.h"
|
||||
#include "Timer.h"
|
||||
#include "Usefull.h"
|
||||
#include "MemCell.h"
|
||||
#include "Globals.h"
|
||||
#include "Ground.h"
|
||||
#pragma package(smart_init)
|
||||
|
||||
__fastcall TEvent::TEvent(AnsiString m)
|
||||
{
|
||||
//asName=""; //czy nazwa eventu jest niezbêdna w tym przypadku? chyba nie
|
||||
evNext=evNext2=NULL;
|
||||
bEnabled=false; //false dla eventów u¿ywanych do skanowania sygna³ów (nie dodawane do kolejki)
|
||||
asNodeName=m; //nazwa obiektu powi¹zanego
|
||||
iQueued=0; //nie zosta³ dodany do kolejki
|
||||
//bIsHistory=false;
|
||||
fDelay=0;
|
||||
fStartTime=0; //0 nie ma sensu
|
||||
Type=m.IsEmpty()?tp_Unknown:tp_GetValues; //utworzenie niejawnego odczytu komórki pamiêci w torze
|
||||
for (int i=0;i<13;i++)
|
||||
Params[i].asPointer=NULL;
|
||||
evJoined=NULL; //nie ma kolejnego z t¹ sam¹ nazw¹, usuwane s¹ wg listy Next2
|
||||
Activator=NULL;
|
||||
iFlags=0;
|
||||
//event niejawny jest tworzony przed faz¹ InitEvents, która podmienia nazwê komórki pamiêci na wskaŸnik
|
||||
//Current->Params[8].asGroundNode=m; //to siê ustawi w InitEvents
|
||||
//Current->Params[9].asMemCell=m->MemCell;
|
||||
fRandomDelay=0.0; //standardowo nie bêdzie dodatkowego losowego opóŸnienia
|
||||
};
|
||||
|
||||
__fastcall TEvent::~TEvent()
|
||||
{
|
||||
switch (Type)
|
||||
{//sprz¹tanie
|
||||
case tp_Multiple:
|
||||
//SafeDeleteArray(Params[9].asText); //nie usuwaæ - nazwa obiektu powi¹zanego zamieniana na wskaŸnik
|
||||
if (iFlags&conditional_memstring) //o ile jest ³añcuch do porównania w memcompare
|
||||
SafeDeleteArray(Params[10].asText);
|
||||
break;
|
||||
case tp_UpdateValues:
|
||||
case tp_AddValues:
|
||||
SafeDeleteArray(Params[0].asText);
|
||||
if (iFlags&conditional_memstring) //o ile jest ³añcuch do porównania w memcompare
|
||||
SafeDeleteArray(Params[10].asText);
|
||||
break;
|
||||
case tp_Animation: //nic
|
||||
//SafeDeleteArray(Params[9].asText); //nie usuwaæ - nazwa jest zamieniana na wskaŸnik do submodelu
|
||||
if (Params[0].asInt==4) //jeœli z pliku VMD
|
||||
delete[] Params[8].asPointer; //zwolniæ obszar
|
||||
case tp_GetValues: //nic
|
||||
break;
|
||||
}
|
||||
evJoined=NULL; //nie usuwaæ podczepionych tutaj
|
||||
};
|
||||
|
||||
void __fastcall TEvent::Init()
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
void __fastcall TEvent::Conditions(cParser* parser,AnsiString s)
|
||||
{//przetwarzanie warunków, wspólne dla Multiple i UpdateValues
|
||||
if (s=="condition")
|
||||
{//jesli nie "endevent"
|
||||
std::string token;
|
||||
AnsiString str;
|
||||
if (!asNodeName.IsEmpty())
|
||||
{//podczepienie ³añcucha, jeœli nie jest pusty
|
||||
Params[9].asText=new char[asNodeName.Length()+1]; //usuwane i zamieniane na wskaŸnik
|
||||
strcpy(Params[9].asText,asNodeName.c_str());
|
||||
}
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
if (str==AnsiString("trackoccupied"))
|
||||
iFlags|=conditional_trackoccupied;
|
||||
else if (str==AnsiString("trackfree"))
|
||||
iFlags|=conditional_trackfree;
|
||||
else if (str==AnsiString("propability"))
|
||||
{
|
||||
iFlags|=conditional_propability;
|
||||
parser->getTokens();
|
||||
*parser >> Params[10].asdouble;
|
||||
}
|
||||
else if (str==AnsiString("memcompare"))
|
||||
{
|
||||
iFlags|=conditional_memcompare;
|
||||
parser->getTokens(1,false); //case sensitive
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
if (str!="*") //"*" - nie brac command pod uwage
|
||||
{//zapamiêtanie ³añcucha do porównania
|
||||
Params[10].asText=new char[255];
|
||||
strcpy(Params[10].asText,str.c_str());
|
||||
iFlags|=conditional_memstring;
|
||||
}
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
if (str!="*") //"*" - nie brac val1 pod uwage
|
||||
{
|
||||
Params[11].asdouble=str.ToDouble();
|
||||
iFlags|=conditional_memval1;
|
||||
}
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
if (str!=AnsiString("*")) //"*" - nie brac val2 pod uwage
|
||||
{
|
||||
Params[12].asdouble=str.ToDouble();
|
||||
iFlags|=conditional_memval2;
|
||||
}
|
||||
}
|
||||
parser->getTokens(); *parser >> token;
|
||||
s=AnsiString(token.c_str()); //ewentualnie dalej losowe opóŸnienie
|
||||
}
|
||||
if (s=="randomdelay")
|
||||
{//losowe opóŸnienie
|
||||
std::string token;
|
||||
parser->getTokens();
|
||||
*parser >> fRandomDelay; //Ra 2014-03-11
|
||||
parser->getTokens(); *parser >> token; //endevent
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TEvent::Load(cParser* parser,vector3 *org)
|
||||
{
|
||||
int i;
|
||||
int ti;
|
||||
double tf;
|
||||
std::string token;
|
||||
AnsiString str;
|
||||
char *ptr;
|
||||
|
||||
bEnabled=true; //zmieniane na false dla eventów u¿ywanych do skanowania sygna³ów
|
||||
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
asName=AnsiString(token.c_str()).LowerCase(); //u¿ycie parametrów mo¿e dawaæ wielkie
|
||||
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
|
||||
if (str==AnsiString("exit"))
|
||||
Type=tp_Exit;
|
||||
else if (str==AnsiString("updatevalues"))
|
||||
Type=tp_UpdateValues;
|
||||
else if (str==AnsiString("getvalues"))
|
||||
Type=tp_GetValues;
|
||||
else if (str==AnsiString("putvalues"))
|
||||
Type=tp_PutValues;
|
||||
else if (str==AnsiString("disable"))
|
||||
Type=tp_Disable;
|
||||
else if (str==AnsiString("sound"))
|
||||
Type=tp_Sound;
|
||||
else if (str==AnsiString("velocity"))
|
||||
Type=tp_Velocity;
|
||||
else if (str==AnsiString("animation"))
|
||||
Type=tp_Animation;
|
||||
else if (str==AnsiString("lights"))
|
||||
Type=tp_Lights;
|
||||
else if (str==AnsiString("visible"))
|
||||
Type=tp_Visible; //zmiana wyœwietlania obiektu
|
||||
else if (str==AnsiString("switch"))
|
||||
Type=tp_Switch;
|
||||
else if (str==AnsiString("dynvel"))
|
||||
Type=tp_DynVel;
|
||||
else if (str==AnsiString("trackvel"))
|
||||
Type=tp_TrackVel;
|
||||
else if (str==AnsiString("multiple"))
|
||||
Type=tp_Multiple;
|
||||
else if (str==AnsiString("addvalues"))
|
||||
Type=tp_AddValues;
|
||||
else if (str==AnsiString("copyvalues"))
|
||||
Type=tp_CopyValues;
|
||||
else if (str==AnsiString("whois"))
|
||||
Type=tp_WhoIs;
|
||||
else if (str==AnsiString("logvalues"))
|
||||
Type=tp_LogValues;
|
||||
else if (str==AnsiString("voltage"))
|
||||
Type=tp_Voltage; //zmiana napiêcia w zasilaczu (TractionPowerSource)
|
||||
else if (str==AnsiString("message"))
|
||||
Type=tp_Message; //wyœwietlenie komunikatu
|
||||
else if (str==AnsiString("friction"))
|
||||
Type=tp_Friction; //zmiana tarcia na scenerii
|
||||
else
|
||||
Type=tp_Unknown;
|
||||
|
||||
parser->getTokens();
|
||||
*parser >> fDelay;
|
||||
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
|
||||
if (str!="none") asNodeName=str; //nazwa obiektu powi¹zanego
|
||||
|
||||
if (asName.SubString(1,5)=="none_")
|
||||
Type=tp_Ignored; //Ra: takie s¹ ignorowane
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case tp_AddValues:
|
||||
iFlags=update_memadd; //dodawanko
|
||||
case tp_UpdateValues:
|
||||
//if (Type==tp_UpdateValues) iFlags=0; //co modyfikowaæ
|
||||
parser->getTokens(1,false); //case sensitive
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
Params[0].asText=new char[str.Length()+1];
|
||||
strcpy(Params[0].asText,str.c_str());
|
||||
if (str!="*") //czy ma zostaæ bez zmian?
|
||||
iFlags|=update_memstring;
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
if (str!="*") //czy ma zostaæ bez zmian?
|
||||
{
|
||||
Params[1].asdouble=str.ToDouble();
|
||||
iFlags|=update_memval1;
|
||||
}
|
||||
else
|
||||
Params[1].asdouble=0;
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
if (str!="*") //czy ma zostaæ bez zmian?
|
||||
{
|
||||
Params[2].asdouble=str.ToDouble();
|
||||
iFlags|=update_memval2;
|
||||
}
|
||||
else
|
||||
Params[2].asdouble=0;
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
Conditions(parser,token.c_str()); //sprawdzanie warunków
|
||||
break;
|
||||
case tp_CopyValues:
|
||||
Params[9].asText=NULL;
|
||||
iFlags=update_memstring|update_memval1|update_memval2; //normalanie trzy
|
||||
i=0;
|
||||
parser->getTokens();
|
||||
*parser >> token; //nazwa drugiej komórki (Ÿród³owej)
|
||||
while (token.compare("endevent")!=0)
|
||||
{
|
||||
switch (++i)
|
||||
{//znaczenie kolejnych parametrów
|
||||
case 1: //nazwa drugiej komórki (Ÿród³owej)
|
||||
Params[9].asText=new char[token.length()+1]; //usuwane i zamieniane na wskaŸnik
|
||||
strcpy(Params[9].asText,token.c_str());
|
||||
break;
|
||||
case 2: //maska wartoœci
|
||||
iFlags=AnsiString(token.c_str()).ToIntDef(update_memstring|update_memval1|update_memval2);
|
||||
break;
|
||||
}
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
}
|
||||
break;
|
||||
case tp_WhoIs:
|
||||
iFlags=update_memstring|update_memval1|update_memval2; //normalanie trzy
|
||||
i=0;
|
||||
parser->getTokens();
|
||||
*parser >> token; //nazwa drugiej komórki (Ÿród³owej)
|
||||
while (token.compare("endevent")!=0)
|
||||
{
|
||||
switch (++i)
|
||||
{//znaczenie kolejnych parametrów
|
||||
case 1: //maska wartoœci
|
||||
iFlags=AnsiString(token.c_str()).ToIntDef(update_memstring|update_memval1|update_memval2);
|
||||
break;
|
||||
}
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
}
|
||||
break;
|
||||
case tp_GetValues:
|
||||
case tp_LogValues:
|
||||
parser->getTokens(); //"endevent"
|
||||
*parser >> token;
|
||||
break;
|
||||
case tp_PutValues:
|
||||
parser->getTokens(3);
|
||||
*parser >> Params[3].asdouble >> Params[4].asdouble >> Params[5].asdouble; //po³o¿enie X,Y,Z
|
||||
if (org)
|
||||
{//przesuniêcie
|
||||
//tmp->pCenter.RotateY(aRotate.y/180.0*M_PI); //Ra 2014-11: uwzglêdnienie rotacji
|
||||
Params[3].asdouble+=org->x; //wspó³rzêdne w scenerii
|
||||
Params[4].asdouble+=org->y;
|
||||
Params[5].asdouble+=org->z;
|
||||
}
|
||||
//Params[12].asInt=0;
|
||||
parser->getTokens(1,false); //komendy 'case sensitive'
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
if (str.SubString(1,19)=="PassengerStopPoint:")
|
||||
{if (str.Pos("#")) str=str.SubString(1,str.Pos("#")-1); //obciêcie unikatowoœci
|
||||
bEnabled=false; //nie do kolejki (dla SetVelocity te¿, ale jak jest do toru dowi¹zany)
|
||||
Params[6].asCommand=cm_PassengerStopPoint;
|
||||
}
|
||||
else if (str=="SetVelocity")
|
||||
{bEnabled=false;
|
||||
Params[6].asCommand=cm_SetVelocity;
|
||||
}
|
||||
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
|
||||
Params[6].asCommand=cm_OutsideStation;
|
||||
}
|
||||
else
|
||||
Params[6].asCommand=cm_Unknown;
|
||||
Params[0].asText=new char[str.Length()+1];
|
||||
strcpy(Params[0].asText,str.c_str());
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
if (str=="none")
|
||||
Params[1].asdouble=0.0;
|
||||
else
|
||||
try
|
||||
{Params[1].asdouble=str.ToDouble();}
|
||||
catch (...)
|
||||
{Params[1].asdouble=0.0;
|
||||
WriteLog("Error: number expected in PutValues event, found: "+str);
|
||||
}
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
if (str=="none")
|
||||
Params[2].asdouble=0.0;
|
||||
else
|
||||
try
|
||||
{Params[2].asdouble=str.ToDouble();}
|
||||
catch (...)
|
||||
{Params[2].asdouble=0.0;
|
||||
WriteLog("Error: number expected in PutValues event, found: "+str);
|
||||
}
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
break;
|
||||
case tp_Lights:
|
||||
i=0;
|
||||
do
|
||||
{
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
if (token.compare("endevent")!=0)
|
||||
{
|
||||
str=AnsiString(token.c_str());
|
||||
if (i<8)
|
||||
Params[i].asdouble=str.ToDouble(); //teraz mo¿e mieæ u³amek
|
||||
i++;
|
||||
}
|
||||
}
|
||||
while (token.compare("endevent")!=0);
|
||||
break;
|
||||
case tp_Visible: //zmiana wyœwietlania obiektu
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
Params[0].asInt=str.ToInt();
|
||||
parser->getTokens(); *parser >> token;
|
||||
break;
|
||||
case tp_Velocity:
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
Params[0].asdouble=str.ToDouble()*0.28;
|
||||
parser->getTokens(); *parser >> token;
|
||||
break;
|
||||
case tp_Sound:
|
||||
//Params[0].asRealSound->Init(asNodeName.c_str(),Parser->GetNextSymbol().ToDouble(),Parser->GetNextSymbol().ToDouble(),Parser->GetNextSymbol().ToDouble(),Parser->GetNextSymbol().ToDouble());
|
||||
//McZapkie-070502: dzwiek przestrzenny (ale do poprawy)
|
||||
//Params[1].asdouble=Parser->GetNextSymbol().ToDouble();
|
||||
//Params[2].asdouble=Parser->GetNextSymbol().ToDouble();
|
||||
//Params[3].asdouble=Parser->GetNextSymbol().ToDouble(); //polozenie X,Y,Z - do poprawy!
|
||||
parser->getTokens();
|
||||
*parser >> Params[0].asInt; //0: wylaczyc, 1: wlaczyc; -1: wlaczyc zapetlone
|
||||
parser->getTokens(); *parser >> token;
|
||||
break;
|
||||
case tp_Exit:
|
||||
while ((ptr=strchr(asNodeName.c_str(),'_'))!=NULL)
|
||||
*ptr=' ';
|
||||
parser->getTokens(); *parser >> token;
|
||||
break;
|
||||
case tp_Disable:
|
||||
parser->getTokens(); *parser >> token;
|
||||
break;
|
||||
case tp_Animation:
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
Params[0].asInt=0; //na razie nieznany typ
|
||||
if (token.compare("rotate")==0)
|
||||
{//obrót wzglêdem osi
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
Params[9].asText=new char[255]; //nazwa submodelu
|
||||
strcpy(Params[9].asText,token.c_str());
|
||||
Params[0].asInt=1;
|
||||
parser->getTokens(4);
|
||||
*parser >> Params[1].asdouble >> Params[2].asdouble >> Params[3].asdouble >> Params[4].asdouble;
|
||||
}
|
||||
else if (token.compare("translate")==0)
|
||||
{//przesuw o wektor
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
Params[9].asText=new char[255]; //nazwa submodelu
|
||||
strcpy(Params[9].asText,token.c_str());
|
||||
Params[0].asInt=2;
|
||||
parser->getTokens(4);
|
||||
*parser >> Params[1].asdouble >> Params[2].asdouble >> Params[3].asdouble >> Params[4].asdouble;
|
||||
}
|
||||
else if (token.compare("digital")==0)
|
||||
{//licznik cyfrowy
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
Params[9].asText=new char[255]; //nazwa submodelu
|
||||
strcpy(Params[9].asText,token.c_str());
|
||||
Params[0].asInt=8;
|
||||
parser->getTokens(4); //jaki ma byæ sens tych parametrów?
|
||||
*parser >> Params[1].asdouble >> Params[2].asdouble >> Params[3].asdouble >> Params[4].asdouble;
|
||||
}
|
||||
else if (token.substr(token.length()-4,4)==".vmd") //na razie tu, mo¿e bêdzie inaczej
|
||||
{//animacja z pliku VMD
|
||||
TFileStream *fs=new TFileStream("models\\"+AnsiString(token.c_str()),fmOpenRead);
|
||||
Params[7].asInt=fs->Size;
|
||||
Params[8].asPointer=new char[fs->Size];
|
||||
fs->Read(Params[8].asPointer,fs->Size); //wczytanie pliku
|
||||
delete fs;
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
Params[9].asText=new char[255]; //nazwa submodelu
|
||||
strcpy(Params[9].asText,token.c_str());
|
||||
Params[0].asInt=4; //rodzaj animacji
|
||||
parser->getTokens(4);
|
||||
*parser >> Params[1].asdouble >> Params[2].asdouble >> Params[3].asdouble >> Params[4].asdouble;
|
||||
}
|
||||
parser->getTokens(); *parser >> token;
|
||||
break;
|
||||
case tp_Switch:
|
||||
parser->getTokens(); *parser >> Params[0].asInt;
|
||||
parser->getTokens(); *parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
if (str!="endevent")
|
||||
{Params[1].asdouble=str.ToDouble(); //prêdkoœæ liniowa ruchu iglic
|
||||
parser->getTokens(); *parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
}
|
||||
else
|
||||
Params[1].asdouble=-1.0; //u¿yæ domyœlnej
|
||||
if (str!="endevent")
|
||||
{Params[2].asdouble=str.ToDouble(); //dodatkowy ruch drugiej iglicy (zamkniêcie nastawnicze)
|
||||
parser->getTokens(); *parser >> token;
|
||||
}
|
||||
else
|
||||
Params[2].asdouble=-1.0; //u¿yæ domyœlnej
|
||||
break;
|
||||
case tp_DynVel:
|
||||
parser->getTokens();
|
||||
*parser >> Params[0].asdouble; //McZapkie-090302 *0.28;
|
||||
parser->getTokens(); *parser >> token;
|
||||
break;
|
||||
case tp_TrackVel:
|
||||
parser->getTokens();
|
||||
*parser >> Params[0].asdouble; //McZapkie-090302 *0.28;
|
||||
parser->getTokens(); *parser >> token;
|
||||
break;
|
||||
case tp_Multiple:
|
||||
i=0;
|
||||
ti=0; //flaga dla else
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
while (str!=AnsiString("endevent") && str!=AnsiString("condition") && str!=AnsiString("randomdelay"))
|
||||
{
|
||||
if ((str.SubString(1,5)!="none_")?(i<8):false)
|
||||
{//eventy rozpoczynaj¹ce siê od "none_" s¹ ignorowane
|
||||
if (str!="else")
|
||||
{Params[i].asText=new char[255];
|
||||
strcpy(Params[i].asText,str.c_str());
|
||||
if (ti) iFlags|=conditional_else<<i; //oflagowanie dla eventów "else"
|
||||
i++;
|
||||
}
|
||||
else
|
||||
ti=!ti; //zmiana flagi dla s³owa "else"
|
||||
}
|
||||
else if (i>=8)
|
||||
ErrorLog("Bad event: \""+str+"\" ignored in multiple \""+asName+"\"!");
|
||||
else
|
||||
WriteLog("Event \""+str+"\" ignored in multiple \""+asName+"\"!");
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
}
|
||||
Conditions(parser,str); //sprawdzanie warunków
|
||||
break;
|
||||
case tp_Voltage: //zmiana napiêcia w zasilaczu (TractionPowerSource)
|
||||
case tp_Friction: //zmiana przyczepnosci na scenerii
|
||||
parser->getTokens();
|
||||
*parser >> Params[0].asdouble; //Ra 2014-01-27
|
||||
parser->getTokens(); *parser >> token;
|
||||
break;
|
||||
case tp_Message: //wyœwietlenie komunikatu
|
||||
do
|
||||
{parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
} while (str!="endevent");
|
||||
break;
|
||||
case tp_Ignored: //ignorowany
|
||||
case tp_Unknown: //nieznany
|
||||
do
|
||||
{parser->getTokens();
|
||||
*parser >> token;
|
||||
str=AnsiString(token.c_str());
|
||||
} while (str!="endevent");
|
||||
WriteLog("Bad event: \""+asName+(Type==tp_Unknown?"\" has unknown type.":"\" is ignored."));
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TEvent::AddToQuery(TEvent *e)
|
||||
{//dodanie eventu do kolejki
|
||||
if (evNext?(e->fStartTime>=evNext->fStartTime):false)
|
||||
evNext->AddToQuery(e); //sortowanie wg czasu
|
||||
else
|
||||
{//dodanie z przodu
|
||||
e->evNext=evNext;
|
||||
evNext=e;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
AnsiString __fastcall TEvent::CommandGet()
|
||||
{//odczytanie komendy z eventu
|
||||
switch (Type)
|
||||
{//to siê wykonuje równie¿ sk³adu jad¹cego bez obs³ugi
|
||||
case tp_GetValues:
|
||||
return String(Params[9].asMemCell->Text());
|
||||
case tp_PutValues:
|
||||
return String(Params[0].asText);
|
||||
}
|
||||
return ""; //inne eventy siê nie licz¹
|
||||
};
|
||||
|
||||
TCommandType __fastcall TEvent::Command()
|
||||
{//odczytanie komendy z eventu
|
||||
switch (Type)
|
||||
{//to siê wykonuje równie¿ dla sk³adu jad¹cego bez obs³ugi
|
||||
case tp_GetValues:
|
||||
return Params[9].asMemCell->Command();
|
||||
case tp_PutValues:
|
||||
return Params[6].asCommand; //komenda zakodowana binarnie
|
||||
}
|
||||
return cm_Unknown; //inne eventy siê nie licz¹
|
||||
};
|
||||
|
||||
double __fastcall TEvent::ValueGet(int n)
|
||||
{//odczytanie komendy z eventu
|
||||
n&=1; //tylko 1 albo 2 jest prawid³owy
|
||||
switch (Type)
|
||||
{//to siê wykonuje równie¿ sk³adu jad¹cego bez obs³ugi
|
||||
case tp_GetValues:
|
||||
return n?Params[9].asMemCell->Value1():Params[9].asMemCell->Value2();
|
||||
case tp_PutValues:
|
||||
return Params[2-n].asdouble;
|
||||
}
|
||||
return 0.0; //inne eventy siê nie licz¹
|
||||
};
|
||||
|
||||
vector3 __fastcall TEvent::PositionGet()
|
||||
{//pobranie wspó³rzêdnych eventu
|
||||
switch (Type)
|
||||
{//
|
||||
case tp_GetValues:
|
||||
return Params[9].asMemCell->Position(); //wspó³rzêdne pod³¹czonej komórki pamiêci
|
||||
case tp_PutValues:
|
||||
return vector3(Params[3].asdouble,Params[4].asdouble,Params[5].asdouble);
|
||||
}
|
||||
return vector3(0,0,0); //inne eventy siê nie licz¹
|
||||
};
|
||||
|
||||
bool __fastcall TEvent::StopCommand()
|
||||
{//
|
||||
if (Type==tp_GetValues)
|
||||
return Params[9].asMemCell->StopCommand(); //info o komendzie z komórki
|
||||
return false;
|
||||
};
|
||||
|
||||
void __fastcall TEvent::StopCommandSent()
|
||||
{
|
||||
if (Type==tp_GetValues)
|
||||
Params[9].asMemCell->StopCommandSent(); //komenda z komórki zosta³a wys³ana
|
||||
};
|
||||
|
||||
void __fastcall TEvent::Append(TEvent *e)
|
||||
{//doczepienie kolejnych z t¹ sam¹ nazw¹
|
||||
if (evJoined)
|
||||
evJoined->Append(e); //rekurencja! - góra kilkanaœcie eventów bêdzie potrzebne
|
||||
else
|
||||
{evJoined=e;
|
||||
e->bEnabled=true; //ten doczepiony mo¿e byæ tylko kolejkowany
|
||||
}
|
||||
};
|
||||
91
Event.h
Normal file
91
Event.h
Normal file
@@ -0,0 +1,91 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef EventH
|
||||
#define EventH
|
||||
|
||||
#include "Classes.h"
|
||||
#include "dumb3d.h"
|
||||
using namespace Math3D;
|
||||
|
||||
typedef enum { tp_Unknown, tp_Sound, tp_SoundPos, tp_Exit,
|
||||
tp_Disable, tp_Velocity, tp_Animation, tp_Lights,
|
||||
tp_UpdateValues, tp_GetValues, tp_PutValues,
|
||||
tp_Switch, tp_DynVel, tp_TrackVel, tp_Multiple,
|
||||
tp_AddValues, tp_Ignored, tp_CopyValues, tp_WhoIs,
|
||||
tp_LogValues, tp_Visible,
|
||||
tp_Voltage, tp_Message, tp_Friction
|
||||
} TEventType;
|
||||
|
||||
const int update_memstring =0x0000001; //zmodyfikowaæ tekst (UpdateValues)
|
||||
const int update_memval1 =0x0000002; //zmodyfikowaæ pierwsz¹ wartosæ
|
||||
const int update_memval2 =0x0000004; //zmodyfikowaæ drug¹ wartosæ
|
||||
const int update_memadd =0x0000008; //dodaæ do poprzedniej zawartoœci
|
||||
const int update_load =0x0000010; //odczytaæ ³adunek
|
||||
const int update_only =0x00000FF; //wartoϾ graniczna
|
||||
const int conditional_memstring =0x0000100; //porównanie tekstu
|
||||
const int conditional_memval1 =0x0000200; //porównanie pierwszej wartoœci liczbowej
|
||||
const int conditional_memval2 =0x0000400; //porównanie drugiej wartoœci
|
||||
const int conditional_else =0x0010000; //flaga odwrócenia warunku (przesuwana bitowo)
|
||||
const int conditional_anyelse =0x0FF0000; //do sprawdzania, czy s¹ odwrócone warunki
|
||||
const int conditional_trackoccupied =0x1000000; //jeœli tor zajêty
|
||||
const int conditional_trackfree =0x2000000; //jeœli tor wolny
|
||||
const int conditional_propability =0x4000000; //zale¿nie od generatora lizcb losowych
|
||||
const int conditional_memcompare =0x8000000; //porównanie zawartoœci
|
||||
|
||||
union TParam
|
||||
{
|
||||
void *asPointer;
|
||||
TMemCell *asMemCell;
|
||||
TGroundNode *nGroundNode;
|
||||
TTrack *asTrack;
|
||||
TAnimModel *asModel;
|
||||
TAnimContainer *asAnimContainer;
|
||||
TTrain *asTrain;
|
||||
TDynamicObject *asDynamic;
|
||||
TEvent *asEvent;
|
||||
bool asBool;
|
||||
double asdouble;
|
||||
int asInt;
|
||||
TTextSound *tsTextSound;
|
||||
char *asText;
|
||||
TCommandType asCommand;
|
||||
TTractionPowerSource *psPower;
|
||||
};
|
||||
|
||||
class TEvent //zmienne: ev*
|
||||
{//zdarzenie
|
||||
private:
|
||||
void __fastcall Conditions(cParser* parser,AnsiString s);
|
||||
public:
|
||||
AnsiString asName;
|
||||
bool bEnabled; //false gdy ma nie byæ dodawany do kolejki (skanowanie sygna³ów)
|
||||
int iQueued; //ile razy dodany do kolejki
|
||||
//bool bIsHistory;
|
||||
TEvent *evNext; //nastêpny w kolejce
|
||||
TEvent *evNext2;
|
||||
TEventType Type;
|
||||
double fStartTime;
|
||||
double fDelay;
|
||||
TDynamicObject *Activator;
|
||||
TParam Params[13]; //McZapkie-070502 //Ra: zamieniæ to na union/struct
|
||||
unsigned int iFlags; //zamiast Params[8] z flagami warunku
|
||||
AnsiString asNodeName; //McZapkie-100302 - dodalem zeby zapamietac nazwe toru
|
||||
TEvent *evJoined; //kolejny event z t¹ sam¹ nazw¹ - od wersji 378
|
||||
double fRandomDelay; //zakres dodatkowego opóŸnienia
|
||||
public: //metody
|
||||
__fastcall TEvent(AnsiString m="");
|
||||
__fastcall ~TEvent();
|
||||
void __fastcall Init();
|
||||
void __fastcall Load(cParser* parser,vector3 *org);
|
||||
void __fastcall AddToQuery(TEvent *e);
|
||||
AnsiString __fastcall CommandGet();
|
||||
TCommandType __fastcall Command();
|
||||
double __fastcall ValueGet(int n);
|
||||
vector3 __fastcall PositionGet();
|
||||
bool __fastcall StopCommand();
|
||||
void __fastcall StopCommandSent();
|
||||
void __fastcall Append(TEvent *e);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
105
FadeSound.cpp
Normal file
105
FadeSound.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
//---------------------------------------------------------------------------
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak and others
|
||||
|
||||
*/
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Timer.h"
|
||||
#include "FadeSound.h"
|
||||
|
||||
|
||||
__fastcall TFadeSound::TFadeSound()
|
||||
{
|
||||
Sound= NULL;
|
||||
fFade= 0;
|
||||
dt= 0;
|
||||
fTime= 0;
|
||||
}
|
||||
|
||||
|
||||
__fastcall TFadeSound::~TFadeSound()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
void __fastcall TFadeSound::Free()
|
||||
{
|
||||
}
|
||||
|
||||
void __fastcall TFadeSound::Init(char *Name, float fNewFade)
|
||||
{
|
||||
Sound= TSoundsManager::GetFromName(Name,false);
|
||||
if (Sound)
|
||||
Sound->SetVolume(0);
|
||||
fFade= fNewFade;
|
||||
fTime= 0;
|
||||
}
|
||||
|
||||
void __fastcall TFadeSound::TurnOn()
|
||||
{
|
||||
State= ss_Starting;
|
||||
Sound->Play(0,0,DSBPLAY_LOOPING);
|
||||
fTime= fFade;
|
||||
|
||||
}
|
||||
|
||||
void __fastcall TFadeSound::TurnOff()
|
||||
{
|
||||
State= ss_ShuttingDown;
|
||||
}
|
||||
|
||||
void __fastcall TFadeSound::Update()
|
||||
{
|
||||
|
||||
if (State==ss_Starting)
|
||||
{
|
||||
fTime+= Timer::GetDeltaTime();
|
||||
// SoundStart->SetVolume(-1000*(4-fTime)/4);
|
||||
if (fTime>=fFade)
|
||||
{
|
||||
fTime= fFade;
|
||||
State= ss_Commencing;
|
||||
Sound->SetVolume(-2000*(fFade-fTime)/fFade);
|
||||
Sound->SetFrequency(44100-500+500*(fTime)/fFade);
|
||||
}
|
||||
else
|
||||
if (Timer::GetSoundTimer())
|
||||
{
|
||||
Sound->SetVolume(-2000*(fFade-fTime)/fFade);
|
||||
Sound->SetFrequency(44100-500+500*(fTime)/fFade);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (State==ss_ShuttingDown)
|
||||
{
|
||||
fTime-= Timer::GetDeltaTime();
|
||||
|
||||
if (fTime<=0)
|
||||
{
|
||||
State= ss_Off;
|
||||
fTime= 0;
|
||||
Sound->Stop();
|
||||
}
|
||||
if (Timer::GetSoundTimer())
|
||||
{ //DSBVOLUME_MIN
|
||||
Sound->SetVolume(-2000*(fFade-fTime)/fFade);
|
||||
Sound->SetFrequency(44100-500+500*fTime/fFade);
|
||||
}
|
||||
}
|
||||
}
|
||||
void __fastcall TFadeSound::Volume(long vol)
|
||||
{
|
||||
float glos= 1;
|
||||
Sound->SetVolume(vol*glos);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
|
||||
|
||||
29
FadeSound.h
Normal file
29
FadeSound.h
Normal file
@@ -0,0 +1,29 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef FadeSoundH
|
||||
#define FadeSoundH
|
||||
|
||||
#include "Sound.h"
|
||||
#include "AdvSound.h"
|
||||
|
||||
class TFadeSound
|
||||
{
|
||||
PSound Sound;
|
||||
float fFade;
|
||||
float dt,fTime;
|
||||
TSoundState State;
|
||||
public:
|
||||
__fastcall TFadeSound();
|
||||
__fastcall ~TFadeSound();
|
||||
void __fastcall Init(char *Name, float fNewFade);
|
||||
void __fastcall TurnOn();
|
||||
void __fastcall TurnOff();
|
||||
bool __fastcall Playing() {return (State==ss_Commencing || State==ss_Starting); };
|
||||
void __fastcall Free();
|
||||
void __fastcall Update();
|
||||
void __fastcall Volume(long vol);
|
||||
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
27
Float3d.cpp
Normal file
27
Float3d.cpp
Normal file
@@ -0,0 +1,27 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <vcl.h>
|
||||
#pragma hdrstop
|
||||
|
||||
#include "float3d.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
|
||||
void __fastcall float4x4::Quaternion(float4 *q)
|
||||
{//konwersja kwaternionu obrotu na macierz obrotu
|
||||
float xx=q->x*q->x,yy=q->y*q->y,zz=q->z*q->z;
|
||||
float xy=q->x*q->y,xz=q->x*q->z,yz=q->y*q->z;
|
||||
float wx=q->w*q->x,wy=q->w*q->y,wz=q->w*q->z;
|
||||
e[ 0]=1.0f-yy-yy-zz-zz;
|
||||
e[ 1]=xy+xy+wz+wz;
|
||||
e[ 2]=xz+xz-wy-wy;
|
||||
e[ 4]=xy+xy-wz-wz;
|
||||
e[ 5]=1.0f-xx-xx-zz-zz;
|
||||
e[ 6]=yz+yz+wx+wx;
|
||||
e[ 8]=xz+xz+wy+wy;
|
||||
e[ 9]=yz+yz-wx-wx;
|
||||
e[10]=1.0f-xx-xx-yy-yy;
|
||||
//czwartej kolumny i czwartego wiersza nie ruszamy
|
||||
};
|
||||
269
Float3d.h
Normal file
269
Float3d.h
Normal file
@@ -0,0 +1,269 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef float3dH
|
||||
#define float3dH
|
||||
#include <math.h>
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class float3
|
||||
{//wapó³rzêdne wiercho³ka 3D o pojedynczej precyzji
|
||||
public:
|
||||
float x,y,z;
|
||||
float3(void) {};
|
||||
__fastcall float3(float a,float b,float c) {x=a;y=b;z=c;};
|
||||
double inline __fastcall Length() const;
|
||||
};
|
||||
|
||||
inline bool operator==(const float3& v1,const float3& v2)
|
||||
{return (v1.x==v2.x&&v1.y==v2.y&&v1.z==v2.z);
|
||||
};
|
||||
inline float3& operator+=(float3& v1,const float3& v2)
|
||||
{v1.x+=v2.x; v1.y+=v2.y; v1.z+=v2.z;
|
||||
return v1;
|
||||
};
|
||||
inline float3 operator-(const float3& v)
|
||||
{return float3(-v.x,-v.y,-v.z);
|
||||
};
|
||||
inline float3 operator-(const float3 &v1,const float3 &v2)
|
||||
{return float3(v1.x-v2.x,v1.y-v2.y,v1.z-v2.z);
|
||||
};
|
||||
inline float3 operator+(const float3 &v1,const float3 &v2)
|
||||
{return float3(v1.x+v2.x,v1.y+v2.y,v1.z+v2.z);
|
||||
};
|
||||
double inline __fastcall float3::Length() const
|
||||
{return sqrt(x*x+y*y+z*z);
|
||||
};
|
||||
inline float3 operator/(const float3& v, double k)
|
||||
{return float3(v.x/k,v.y/k,v.z/k);
|
||||
};
|
||||
inline float3 SafeNormalize(const float3 &v)
|
||||
{//bezpieczna normalizacja (wektor d³ugoœci 1.0)
|
||||
double l=v.Length();
|
||||
float3 retVal;
|
||||
if (l==0)
|
||||
retVal.x=retVal.y=retVal.z=0;
|
||||
else
|
||||
retVal=v/l;
|
||||
return retVal;
|
||||
};
|
||||
inline float3 CrossProduct(const float3& v1,const float3& v2)
|
||||
{return float3(v1.y*v2.z-v1.z*v2.y,v2.x*v1.z-v2.z*v1.x,v1.x*v2.y-v1.y*v2.x);
|
||||
}
|
||||
|
||||
class float4
|
||||
{//kwaternion obrotu
|
||||
public:
|
||||
float x,y,z,w;
|
||||
__fastcall float4() {x=y=z=0.f;w=1.f;};
|
||||
__fastcall float4(float a,float b,float c,float d) {x=a;y=b;z=c;w=d;};
|
||||
double inline float4::LengthSquared() const
|
||||
{return x*x+y*y+z*z+w*w;};
|
||||
double inline float4::Length() const
|
||||
{return sqrt(x*x+y*y+z*z+w*w);};
|
||||
};
|
||||
inline float4 operator*(const float4 &q1,const float4 &q2)
|
||||
{//mno¿enie to prawie jak mno¿enie macierzy
|
||||
return float4
|
||||
(q1.w*q2.x+q1.x*q2.w+q1.y*q2.z-q1.z*q2.y,
|
||||
q1.w*q2.y+q1.y*q2.w+q1.z*q2.x-q1.x*q2.z,
|
||||
q1.w*q2.z+q1.z*q2.w+q1.x*q2.y-q1.y*q2.x,
|
||||
q1.w*q2.w-q1.x*q2.x-q1.y*q2.y-q1.z*q2.z
|
||||
);
|
||||
}
|
||||
inline float4 operator-(const float4& q)
|
||||
{//sprzê¿ony; odwrotny tylko dla znormalizowanych!
|
||||
return float4(-q.x,-q.y,-q.z,q.w);
|
||||
};
|
||||
inline float4 operator-(const float4 &q1,const float4 &q2)
|
||||
{//z odejmowaniem nie ma lekko
|
||||
return (-q1)*q2; //inwersja tylko dla znormalizowanych!
|
||||
};
|
||||
inline float4 operator+(const float4 &v1,const float4 &v2)
|
||||
{return float4(v1.x+v2.x,v1.y+v2.y,v1.z+v2.z,v1.w+v2.w);};
|
||||
inline float4 operator/(const float4& v, double k)
|
||||
{return float4(v.x/k,v.y/k,v.z/k,v.w/k);};
|
||||
inline float4 Normalize(const float4 &v)
|
||||
{//bezpieczna normalizacja (wektor d³ugoœci 1.0)
|
||||
double l=v.LengthSquared();
|
||||
if (l==1.0)
|
||||
return v;
|
||||
if (l==0.0)
|
||||
return float4(); //wektor zerowy, w=1
|
||||
else
|
||||
return v/sqrt(l); //pierwiastek liczony tylko jeœli trzeba wykonaæ dzielenia
|
||||
};
|
||||
float Dot(const float4 &q1,const float4 &q2)
|
||||
{//iloczyn skalarny
|
||||
return q1.x*q2.x+q1.y*q2.y+q1.z*q2.z+q1.w*q2.w;
|
||||
}
|
||||
inline float4& operator*=(float4& v1,double d)
|
||||
{//mno¿enie przez skalar, jaki ma sens?
|
||||
v1.x*=d; v1.y*=d; v1.z*=d; v1.w*=d;
|
||||
return v1;
|
||||
};
|
||||
inline float4 Slerp(const float4 &q0,const float4 &q1,float t)
|
||||
//void Slerp(QUATERNION *Out, const QUATERNION &q0, const QUATERNION &q1, float t)
|
||||
{//interpolacja sweryczna
|
||||
float cosOmega=Dot(q0,q1);
|
||||
float4 new_q1(q1);
|
||||
if (cosOmega<0.0f)
|
||||
{//je¿eli s¹ niezgodne kierunki, jeden z nich trzeba zanegowaæ
|
||||
new_q1.x=-new_q1.x;
|
||||
new_q1.y=-new_q1.y;
|
||||
new_q1.z=-new_q1.z;
|
||||
new_q1.w=-new_q1.w;
|
||||
cosOmega=-cosOmega;
|
||||
}
|
||||
double k0,k1;
|
||||
if (cosOmega>0.9999f)
|
||||
{//jeœli jesteœmy z (t) na maksimum kosinusa, to tam prawie liniowo jest
|
||||
k0=1.0f-t;
|
||||
k1=t;
|
||||
}
|
||||
else
|
||||
{//a w ogólnym przypadku trzeba liczyæ na trygonometriê
|
||||
double sinOmega=sqrt(1.0f-cosOmega*cosOmega); //sinus z jedynki tryg.
|
||||
double omega=atan2(sinOmega,cosOmega); //wyznaczenie k¹ta
|
||||
double oneOverSinOmega=1.0f/sinOmega; //odwrotnoϾ sinusa, bo sinus w mianowniku
|
||||
k0=sin((1.0f-t)*omega)*oneOverSinOmega;
|
||||
k1=sin(t*omega)*oneOverSinOmega;
|
||||
}
|
||||
return float4
|
||||
(q0.x*k0+new_q1.x*k1,
|
||||
q0.y*k0+new_q1.y*k1,
|
||||
q0.z*k0+new_q1.z*k1,
|
||||
q0.w*k0+new_q1.w*k1
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
struct float8
|
||||
{//wiercho³ek 3D z wektorem normalnym i mapowaniem, pojedyncza precyzja
|
||||
public:
|
||||
float3 Point;
|
||||
float3 Normal;
|
||||
float tu,tv;
|
||||
};
|
||||
|
||||
class float4x4
|
||||
{//macierz transformacji pojedynczej precyzji
|
||||
float e[16];
|
||||
public:
|
||||
float4x4(void) {};
|
||||
float4x4(float f[16]) {for (int i=0;i<16;++i) e[i]=f[i];};
|
||||
float* __fastcall operator() (int i) { return &e[i<<2]; }
|
||||
const float* __fastcall readArray(void) { return e; }
|
||||
void __fastcall Identity()
|
||||
{for (int i=0;i<16;++i)
|
||||
e[i]=0;
|
||||
e[0]=e[5]=e[10]=e[15]=1.0f;
|
||||
}
|
||||
const float* operator[](int i) const {return &e[i<<2];};
|
||||
void __fastcall InitialRotate()
|
||||
{//taka specjalna rotacja, nie ma co ci¹gaæ trygonometrii
|
||||
float f;
|
||||
for (int i=0;i<16;i+=4)
|
||||
{e[i]=-e[i]; //zmiana znaku X
|
||||
f=e[i+1]; e[i+1]=e[i+2]; e[i+2]=f; //zamiana Y i Z
|
||||
}
|
||||
};
|
||||
inline float4x4& Rotation(double angle,float3 axis);
|
||||
inline bool IdentityIs()
|
||||
{//sprawdzenie jednostkowoœci
|
||||
for (int i=0;i<16;++i)
|
||||
if (e[i]!=((i%5)?0.0:1.0)) //jedynki tylko na 0, 5, 10 i 15
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
void __fastcall Quaternion(float4 *q);
|
||||
inline float3* TranslationGet()
|
||||
{return (float3*)(e+12);}
|
||||
};
|
||||
|
||||
inline float3 operator*(const float4x4& m,const float3& v)
|
||||
{//mno¿enie wektora przez macierz
|
||||
return float3(
|
||||
v.x*m[0][0]+v.y*m[1][0]+v.z*m[2][0]+m[3][0],
|
||||
v.x*m[0][1]+v.y*m[1][1]+v.z*m[2][1]+m[3][1],
|
||||
v.x*m[0][2]+v.y*m[1][2]+v.z*m[2][2]+m[3][2]
|
||||
);
|
||||
}
|
||||
|
||||
inline float4x4& float4x4::Rotation(double angle,float3 axis)
|
||||
{
|
||||
double c=cos(angle);
|
||||
double s=sin(angle);
|
||||
// One minus c (short name for legibility of formulai)
|
||||
double omc=(1-c);
|
||||
if (axis.Length()!=1.0f) axis=SafeNormalize(axis);
|
||||
double x = axis.x;
|
||||
double y = axis.y;
|
||||
double z = axis.z;
|
||||
double xs = x * s;
|
||||
double ys = y * s;
|
||||
double zs = z * s;
|
||||
double xyomc = x * y * omc;
|
||||
double xzomc = x * z * omc;
|
||||
double yzomc = y * z * omc;
|
||||
e[0] =x*x*omc+c;
|
||||
e[1] =xyomc+zs;
|
||||
e[2] =xzomc-ys;
|
||||
e[3] =0;
|
||||
e[4] =xyomc-zs;
|
||||
e[5] =y*y*omc+c;
|
||||
e[6] =yzomc+xs;
|
||||
e[7] =0;
|
||||
e[8] =xzomc+ys;
|
||||
e[9] =yzomc-xs;
|
||||
e[10]=z*z*omc+c;
|
||||
e[11]=0;
|
||||
e[12]=0;
|
||||
e[13]=0;
|
||||
e[14]=0;
|
||||
e[15]=1;
|
||||
return *this;
|
||||
};
|
||||
|
||||
inline float4x4 operator*(const float4x4& m1, const float4x4& m2)
|
||||
{//iloczyn macierzy
|
||||
float4x4 retVal;
|
||||
for (int x=0;x<4;++x)
|
||||
for (int y=0;y<4;++y)
|
||||
{
|
||||
retVal(x)[y]=0;
|
||||
for (int i=0;i<4;++i)
|
||||
retVal(x)[y]+=m1[i][y]*m2[x][i];
|
||||
}
|
||||
return retVal;
|
||||
};
|
||||
|
||||
// From code in Graphics Gems; p. 766
|
||||
inline float Det2x2(float a,float b,float c,float d)
|
||||
{//obliczenie wyznacznika macierzy 2×2
|
||||
return a*d-b*c;
|
||||
};
|
||||
|
||||
inline float Det3x3(float a1,float a2,float a3,
|
||||
float b1,float b2,float b3,
|
||||
float c1,float c2,float c3)
|
||||
{//obliczenie wyznacznika macierzy 3×3
|
||||
return
|
||||
+a1*Det2x2(b2,b3,c2,c3)
|
||||
-b1*Det2x2(a2,a3,c2,c3)
|
||||
+c1*Det2x2(a2,a3,b2,b3);
|
||||
};
|
||||
|
||||
float Det(const float4x4 &m)
|
||||
{//obliczenie wyznacznika macierzy 4×4
|
||||
float a1=m[0][0],a2=m[1][0],a3=m[2][0],a4=m[3][0];
|
||||
float b1=m[0][1],b2=m[1][1],b3=m[2][1],b4=m[3][1];
|
||||
float c1=m[0][2],c2=m[1][2],c3=m[2][2],c4=m[3][2];
|
||||
float d1=m[0][3],d2=m[1][3],d3=m[2][3],d4=m[3][3];
|
||||
return
|
||||
+a1*Det3x3(b2,b3,b4,c2,c3,c4,d2,d3,d4)
|
||||
-b1*Det3x3(a2,a3,a4,c2,c3,c4,d2,d3,d4)
|
||||
+c1*Det3x3(a2,a3,a4,b2,b3,b4,d2,d3,d4)
|
||||
-d1*Det3x3(a2,a3,a4,b2,b3,b4,c2,c3,c4);
|
||||
};
|
||||
|
||||
#endif
|
||||
45
Forth.cpp
Normal file
45
Forth.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <vcl.h>
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Forth.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
|
||||
/* Ra: Forth jest prostym językiem programowania, funkcjonującym na dosyć
|
||||
niskim poziomie. Może być zarówno interpretowany jak i kompilowany, co
|
||||
pozwala szybko działać skompilowanym programom, jak również wykonywać
|
||||
polecenia wprowadzane z klawiatury. Za pomocą zdefiniowanych kompilatorów
|
||||
można definiować nowe funkcje, można również tworzyć nowe struktury jezyka,
|
||||
np. wykraczające poza dotychczasową składnię. Prostota i wydajność są okupione
|
||||
nieco specyficzną składnią, wynikającą z użycia stosu do obliczeń (tzw. odwrotna
|
||||
notacja polska).
|
||||
|
||||
Forth ma być używany jako:
|
||||
1. Alternatywna postać eventów. Dotychczasowe eventy w sceneriach mogą być
|
||||
traktowane jako funkcje języka Forth. Jednocześnie można uzyskać uelastycznienie
|
||||
składni, poprzez np. połączenie w jednym wpisie różnych typów eventów wraz z
|
||||
dodaniem warunków dostępnych tylko dla Multiple. Również można będzie używać
|
||||
wyrażeń języka Forth, czyli dokonywać obliczeń.
|
||||
2. Jako docelowa postać schematów obwodów Ladder Diagram. Można zrobić tak, by
|
||||
program źródłowy w Forth (przy pewnych ograniczeniach) był wyświetlany graficznie
|
||||
jako Ladder Diagram. Jednocześnie graficzne modyfikacje schematu można by
|
||||
przełożyć na postać tekstową Forth i skompilować na kod niskiego poziomu.
|
||||
3. Jako algorytm funkcjonowania AI, możliwy do zaprogramowania na zewnątzr EXE.
|
||||
Każdy użytkownik będzie mógł swój własny styl jazdy.
|
||||
4. Jako algorytm sterowania ruchem (zależności na stacji).
|
||||
5. Jako AI stacji, zarządzające ruchem na stacji zależnie w czasie rzeczywistym.
|
||||
|
||||
Względem pierwotnego języka Forth, użyty tutaj będzie miał pewne odstępstwa:
|
||||
1. Operacje na liczbach czterobajtowych float. Należy we własnym zakresie dbać
|
||||
o zgodność użytych funkcji z typem argumentu na stosie.
|
||||
2. Jedynym typem całkowitym jest czterobajtowy int.
|
||||
3. Do wyszukiwania obiektów w scenerii po nazwie (torów, eventów), używane jest
|
||||
drzewo zamiast listy.
|
||||
|
||||
Wpisy w scenerii, przetwarzane jako komendy Forth, nie mogą używać średnika jako
|
||||
separatora słów. Uniemożliwia to używanie średnika jako słowa.
|
||||
*/
|
||||
10
Forth.h
Normal file
10
Forth.h
Normal file
@@ -0,0 +1,10 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef ForthH
|
||||
#define ForthH
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
class Forth
|
||||
{//klasa obs³ugi jêzyka
|
||||
};
|
||||
#endif
|
||||
217
Gauge.cpp
Normal file
217
Gauge.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak
|
||||
|
||||
*/
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Timer.h"
|
||||
#include "QueryParserComp.hpp"
|
||||
#include "Model3d.h"
|
||||
#include "Gauge.h"
|
||||
#include "Console.h"
|
||||
|
||||
__fastcall TGauge::TGauge()
|
||||
{
|
||||
eType=gt_Unknown;
|
||||
fFriction=0.0;
|
||||
fDesiredValue=0.0;
|
||||
fValue=0.0;
|
||||
fOffset=0.0;
|
||||
fScale=1.0;
|
||||
fStepSize=5;
|
||||
//iChannel=-1; //kana³ analogowej komunikacji zwrotnej
|
||||
SubModel=NULL;
|
||||
};
|
||||
|
||||
__fastcall TGauge::~TGauge()
|
||||
{
|
||||
};
|
||||
|
||||
void __fastcall TGauge::Clear()
|
||||
{
|
||||
SubModel=NULL;
|
||||
eType=gt_Unknown;
|
||||
fValue=0;
|
||||
fDesiredValue=0;
|
||||
};
|
||||
|
||||
void __fastcall TGauge::Init(TSubModel *NewSubModel,TGaugeType eNewType,double fNewScale,double fNewOffset,double fNewFriction,double fNewValue)
|
||||
{//ustawienie parametrów animacji submodelu
|
||||
if (NewSubModel)
|
||||
{//warunek na wszelki wypadek, gdyby siê submodel nie pod³¹czy³
|
||||
fFriction=fNewFriction;
|
||||
fValue=fNewValue;
|
||||
fOffset=fNewOffset;
|
||||
fScale=fNewScale;
|
||||
SubModel=NewSubModel;
|
||||
eType=eNewType;
|
||||
if (eType==gt_Digital)
|
||||
{
|
||||
TSubModel *sm=SubModel->ChildGet();
|
||||
do
|
||||
{//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')
|
||||
sm->WillBeAnimated(); //wy³¹czenie optymalizacji
|
||||
}
|
||||
sm=sm->NextGet();
|
||||
} while (sm);
|
||||
}
|
||||
else //a banan mo¿e byæ z optymalizacj¹?
|
||||
NewSubModel->WillBeAnimated(); //wy³¹czenie ignowania jedynkowego transformu
|
||||
}
|
||||
};
|
||||
|
||||
bool __fastcall TGauge::Load(TQueryParserComp *Parser,TModel3d *md1,TModel3d *md2,double mul)
|
||||
{
|
||||
AnsiString str1=Parser->GetNextSymbol();
|
||||
AnsiString str2=Parser->GetNextSymbol().LowerCase();
|
||||
double val3=Parser->GetNextSymbol().ToDouble()*mul;
|
||||
double val4=Parser->GetNextSymbol().ToDouble();
|
||||
double val5=Parser->GetNextSymbol().ToDouble();
|
||||
TSubModel *sm=md1->GetFromName(str1.c_str());
|
||||
if (sm) //jeœli nie znaleziony
|
||||
md2=NULL; //informacja, ¿e znaleziony
|
||||
else
|
||||
if (md2) //a jest podany drugi model (np. zewnêtrzny)
|
||||
sm=md2->GetFromName(str1.c_str()); //to mo¿e tam bêdzie, co za ró¿nica gdzie
|
||||
if (str2=="mov")
|
||||
Init(sm,gt_Move,val3,val4,val5);
|
||||
else if (str2=="wip")
|
||||
Init(sm,gt_Wiper,val3,val4,val5);
|
||||
else if (str2=="dgt")
|
||||
Init(sm,gt_Digital,val3,val4,val5);
|
||||
else
|
||||
Init(sm,gt_Rotate,val3,val4,val5);
|
||||
return (md2); //true, gdy podany model zewnêtrzny, a w kabinie nie by³o
|
||||
};
|
||||
|
||||
|
||||
void __fastcall TGauge::PermIncValue(double fNewDesired)
|
||||
{
|
||||
fDesiredValue=fDesiredValue+fNewDesired*fScale+fOffset;
|
||||
if (fDesiredValue-fOffset>360/fScale)
|
||||
{
|
||||
fDesiredValue=fDesiredValue-(360/fScale);
|
||||
fValue=fValue-(360/fScale);
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TGauge::IncValue(double fNewDesired)
|
||||
{//u¿ywane tylko dla uniwersali
|
||||
fDesiredValue=fDesiredValue+fNewDesired*fScale+fOffset;
|
||||
if (fDesiredValue>fScale+fOffset)
|
||||
fDesiredValue=fScale+fOffset;
|
||||
};
|
||||
|
||||
void __fastcall TGauge::DecValue(double fNewDesired)
|
||||
{//u¿ywane tylko dla uniwersali
|
||||
fDesiredValue=fDesiredValue-fNewDesired*fScale+fOffset;
|
||||
if (fDesiredValue<0) fDesiredValue=0;
|
||||
};
|
||||
|
||||
void __fastcall TGauge::UpdateValue(double fNewDesired)
|
||||
{//ustawienie wartoœci docelowej
|
||||
fDesiredValue=fNewDesired*fScale+fOffset;
|
||||
};
|
||||
|
||||
void __fastcall TGauge::PutValue(double fNewDesired)
|
||||
{//McZapkie-281102: natychmiastowe wpisanie wartosci
|
||||
fDesiredValue=fNewDesired*fScale+fOffset;
|
||||
fValue=fDesiredValue;
|
||||
};
|
||||
|
||||
void __fastcall TGauge::Update()
|
||||
{
|
||||
float dt=Timer::GetDeltaTime();
|
||||
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³
|
||||
TSubModel *sm;
|
||||
switch (eType)
|
||||
{
|
||||
case gt_Rotate:
|
||||
SubModel->SetRotate(float3(0,1,0),fValue*360.0);
|
||||
break;
|
||||
case gt_Move:
|
||||
SubModel->SetTranslate(float3(0,0,fValue));
|
||||
break;
|
||||
case gt_Wiper:
|
||||
SubModel->SetRotate(float3(0,1,0),fValue*360.0);
|
||||
sm=SubModel->ChildGet();
|
||||
if (sm)
|
||||
{sm->SetRotate(float3(0,1,0),fValue*360.0);
|
||||
sm=sm->ChildGet();
|
||||
if (sm)
|
||||
sm->SetRotate(float3(0,1,0),fValue*360.0);
|
||||
}
|
||||
break;
|
||||
case gt_Digital: //Ra 2014-07: licznik cyfrowy
|
||||
sm=SubModel->ChildGet();
|
||||
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)
|
||||
if (sm->pName)
|
||||
{//musi mieæ niepust¹ nazwê
|
||||
if ((*sm->pName)>='0')
|
||||
if ((*sm->pName)<='9')
|
||||
sm->SetRotate(float3(0,1,0),-36.0*(n['0'+10-(*sm->pName)]-'0'));
|
||||
}
|
||||
sm=sm->NextGet();
|
||||
} while (sm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TGauge::Render()
|
||||
{
|
||||
};
|
||||
|
||||
void __fastcall TGauge::AssignFloat(float* fValue)
|
||||
{
|
||||
cDataType='f';
|
||||
fData=fValue;
|
||||
};
|
||||
void __fastcall TGauge::AssignDouble(double* dValue)
|
||||
{
|
||||
cDataType='d';
|
||||
dData=dValue;
|
||||
};
|
||||
void __fastcall TGauge::AssignInt(int* iValue)
|
||||
{
|
||||
cDataType='i';
|
||||
iData=iValue;
|
||||
};
|
||||
void __fastcall TGauge::UpdateValue()
|
||||
{//ustawienie wartoœci docelowej z parametru
|
||||
switch (cDataType)
|
||||
{//to nie jest zbyt optymalne, mo¿na by zrobiæ osobne funkcje
|
||||
case 'f':
|
||||
fDesiredValue=(*fData)*fScale+fOffset;
|
||||
break;
|
||||
case 'd':
|
||||
fDesiredValue=(*dData)*fScale+fOffset;
|
||||
break;
|
||||
case 'i':
|
||||
fDesiredValue=(*iData)*fScale+fOffset;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
61
Gauge.h
Normal file
61
Gauge.h
Normal file
@@ -0,0 +1,61 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GaugeH
|
||||
#define GaugeH
|
||||
|
||||
//#include "Classes.h"
|
||||
#include "QueryParserComp.hpp"
|
||||
//class Queryparsercomp::TQueryParserComp;
|
||||
class TSubModel;
|
||||
class TModel3d;
|
||||
|
||||
typedef enum
|
||||
{//typ ruchu
|
||||
gt_Unknown, //na razie nie znany
|
||||
gt_Rotate, //obrót
|
||||
gt_Move, //przesuniêcie równoleg³e
|
||||
gt_Wiper, //obrót trzech kolejnych submodeli o ten sam k¹t (np. wycieraczka, drzwi harmonijkowe)
|
||||
gt_Digital //licznik cyfrowy, np. kilometrów
|
||||
} TGaugeType;
|
||||
|
||||
class TGauge //zmienne "gg"
|
||||
{//animowany wskaŸnik, mog¹cy przyjmowaæ wiele stanów poœrednich
|
||||
private:
|
||||
TGaugeType eType; //typ ruchu
|
||||
double fFriction; //hamowanie przy zli¿aniu siê do zadanej wartoœci
|
||||
double fDesiredValue; //wartoϾ docelowa
|
||||
double fValue; //wartoϾ obecna
|
||||
double fOffset; //wartoœæ pocz¹tkowa ("0")
|
||||
double fScale; //wartoœæ koñcowa ("1")
|
||||
double fStepSize; //nie u¿ywane
|
||||
char cDataType; //typ zmiennej parametru: f-float, d-double, i-int
|
||||
union
|
||||
{//wskaŸnik na parametr pokazywany przez animacjê
|
||||
float* fData;
|
||||
double* dData;
|
||||
int* iData;
|
||||
};
|
||||
public:
|
||||
__fastcall TGauge();
|
||||
__fastcall ~TGauge();
|
||||
void __fastcall Clear();
|
||||
void __fastcall Init(TSubModel *NewSubModel,TGaugeType eNewTyp,double fNewScale=1,double fNewOffset=0,double fNewFriction=0,double fNewValue=0);
|
||||
bool __fastcall Load(TQueryParserComp *Parser,TModel3d *md1,TModel3d *md2=NULL,double mul=1.0);
|
||||
void __fastcall PermIncValue(double fNewDesired);
|
||||
void __fastcall IncValue(double fNewDesired);
|
||||
void __fastcall DecValue(double fNewDesired);
|
||||
void __fastcall UpdateValue(double fNewDesired);
|
||||
void __fastcall PutValue(double fNewDesired);
|
||||
float GetValue() {return fValue;};
|
||||
void __fastcall Update();
|
||||
void __fastcall Render();
|
||||
void __fastcall AssignFloat(float* fValue);
|
||||
void __fastcall AssignDouble(double* dValue);
|
||||
void __fastcall AssignInt(int* iValue);
|
||||
void __fastcall UpdateValue();
|
||||
TSubModel *SubModel; //McZapkie-310302: zeby mozna bylo sprawdzac czy zainicjowany poprawnie
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
119
Geom.cpp
Normal file
119
Geom.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#include <gl/gl.h>
|
||||
#include <gl/glu.h>
|
||||
#include "opengl/glut.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Texture.h"
|
||||
#include "usefull.h"
|
||||
#include "Globals.h"
|
||||
#include "Geom.h"
|
||||
|
||||
|
||||
__fastcall TGeometry::TGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
__fastcall TGeometry::~TGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
bool __fastcall TGeometry::Init()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
vector3 __fastcall TGeometry::Load(TQueryParserComp *Parser)
|
||||
{
|
||||
str= Parser->GetNextSymbol().LowerCase();
|
||||
tmp->TextureID= TTexturesManager::GetTextureID(str.c_str());
|
||||
|
||||
i=0;
|
||||
do
|
||||
{
|
||||
tf= Parser->GetNextSymbol().ToDouble();
|
||||
TempVerts[i].Point.x= tf;
|
||||
tf= Parser->GetNextSymbol().ToDouble();
|
||||
TempVerts[i].Point.y= tf;
|
||||
tf= Parser->GetNextSymbol().ToDouble();
|
||||
TempVerts[i].Point.z= tf;
|
||||
tf= Parser->GetNextSymbol().ToDouble();
|
||||
TempVerts[i].Normal.x= tf;
|
||||
tf= Parser->GetNextSymbol().ToDouble();
|
||||
TempVerts[i].Normal.y= tf;
|
||||
tf= Parser->GetNextSymbol().ToDouble();
|
||||
TempVerts[i].Normal.z= tf;
|
||||
|
||||
str= Parser->GetNextSymbol().LowerCase();
|
||||
if (str=="x")
|
||||
TempVerts[i].tu= (TempVerts[i].Point.x+Parser->GetNextSymbol().ToDouble())/Parser->GetNextSymbol().ToDouble();
|
||||
else
|
||||
if (str=="y")
|
||||
TempVerts[i].tu= (TempVerts[i].Point.y+Parser->GetNextSymbol().ToDouble())/Parser->GetNextSymbol().ToDouble();
|
||||
else
|
||||
if (str=="z")
|
||||
TempVerts[i].tu= (TempVerts[i].Point.z+Parser->GetNextSymbol().ToDouble())/Parser->GetNextSymbol().ToDouble();
|
||||
else
|
||||
TempVerts[i].tu= str.ToDouble();;
|
||||
|
||||
str= Parser->GetNextSymbol().LowerCase();
|
||||
if (str=="x")
|
||||
TempVerts[i].tv= (TempVerts[i].Point.x+Parser->GetNextSymbol().ToDouble())/Parser->GetNextSymbol().ToDouble();
|
||||
else
|
||||
if (str=="y")
|
||||
TempVerts[i].tv= (TempVerts[i].Point.y+Parser->GetNextSymbol().ToDouble())/Parser->GetNextSymbol().ToDouble();
|
||||
else
|
||||
if (str=="z")
|
||||
TempVerts[i].tv= (TempVerts[i].Point.z+Parser->GetNextSymbol().ToDouble())/Parser->GetNextSymbol().ToDouble();
|
||||
else
|
||||
TempVerts[i].tv= str.ToDouble();;
|
||||
|
||||
// tf= Parser->GetNextSymbol().ToDouble();
|
||||
// TempVerts[i].tu= tf;
|
||||
// tf= Parser->GetNextSymbol().ToDouble();
|
||||
// TempVerts[i].tv= tf;
|
||||
|
||||
TempVerts[i].Point.RotateZ(aRotate.z/180*M_PI);
|
||||
TempVerts[i].Point.RotateX(aRotate.x/180*M_PI);
|
||||
TempVerts[i].Point.RotateY(aRotate.y/180*M_PI);
|
||||
TempVerts[i].Normal.RotateZ(aRotate.z/180*M_PI);
|
||||
TempVerts[i].Normal.RotateX(aRotate.x/180*M_PI);
|
||||
TempVerts[i].Normal.RotateY(aRotate.y/180*M_PI);
|
||||
|
||||
TempVerts[i].Point+= pOrigin;
|
||||
tmp->pCenter+= TempVerts[i].Point;
|
||||
|
||||
i++;
|
||||
|
||||
// }
|
||||
} while ( Parser->GetNextSymbol().LowerCase()!="endtri" );
|
||||
|
||||
nv= i;
|
||||
tmp->Init(nv);
|
||||
tmp->pCenter/= (nv>0?nv:1);
|
||||
|
||||
// memcpy(tmp->Vertices,TempVerts,nv*sizeof(TGroundVertex));
|
||||
|
||||
r= 0;
|
||||
for (int i=0; i<nv; i++)
|
||||
{
|
||||
tmp->Vertices[i]= TempVerts[i];
|
||||
tf= SquareMagnitude(tmp->Vertices[i].Point-tmp->pCenter);
|
||||
if (tf>r)
|
||||
r= tf;
|
||||
}
|
||||
|
||||
// tmp->fSquareRadius= 2000*2000+r;
|
||||
tmp->fSquareRadius+= r;
|
||||
|
||||
}
|
||||
|
||||
bool __fastcall TGeometry::Render()
|
||||
{
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
38
Geom.h
Normal file
38
Geom.h
Normal file
@@ -0,0 +1,38 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GeomH
|
||||
#define GeomH
|
||||
|
||||
#include <gl/gl.h>
|
||||
#include "QueryParserComp.hpp"
|
||||
|
||||
struct TGeomVertex
|
||||
{
|
||||
vector3 Point;
|
||||
vector3 Normal;
|
||||
double tu,tv;
|
||||
};
|
||||
|
||||
class TGeometry
|
||||
{
|
||||
private:
|
||||
GLuint iType;
|
||||
union
|
||||
{
|
||||
int iNumVerts;
|
||||
int iNumPts;
|
||||
};
|
||||
GLuint TextureID;
|
||||
TMaterialColor Ambient;
|
||||
TMaterialColor Diffuse;
|
||||
TMaterialColor Specular;
|
||||
public:
|
||||
__fastcall TGeometry();
|
||||
__fastcall ~TGeometry();
|
||||
bool __fastcall Init();
|
||||
vector3 __fastcall Load(TQueryParserComp *Parser);
|
||||
bool __fastcall Render();
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
778
Globals.cpp
Normal file
778
Globals.cpp
Normal file
@@ -0,0 +1,778 @@
|
||||
//---------------------------------------------------------------------------
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
||||
|
||||
*/
|
||||
|
||||
#include "system.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
#include "Globals.h"
|
||||
#include "QueryParserComp.hpp"
|
||||
#include "usefull.h"
|
||||
#include "Mover.h"
|
||||
#include "Driver.h"
|
||||
#include "Console.h"
|
||||
#include <Controls.hpp> //do odczytu daty
|
||||
#include "World.h"
|
||||
|
||||
|
||||
|
||||
//namespace Global {
|
||||
|
||||
//parametry do użytku wewnętrznego
|
||||
//double Global::tSinceStart=0;
|
||||
TGround *Global::pGround=NULL;
|
||||
//char Global::CreatorName1[30]="2001-2004 Maciej Czapkiewicz <McZapkie>";
|
||||
//char Global::CreatorName2[30]="2001-2003 Marcin Woźniak <Marcin_EU>";
|
||||
//char Global::CreatorName3[20]="2004-2005 Adam Bugiel <ABu>";
|
||||
//char Global::CreatorName4[30]="2004 Arkadiusz Ślusarczyk <Winger>";
|
||||
//char Global::CreatorName5[30]="2003-2009 Łukasz Kirchner <Nbmx>";
|
||||
AnsiString Global::asCurrentSceneryPath="scenery/";
|
||||
AnsiString Global::asCurrentTexturePath=AnsiString(szTexturePath);
|
||||
AnsiString Global::asCurrentDynamicPath="";
|
||||
int Global::iSlowMotion=0; //info o malym FPS: 0-OK, 1-wyłączyć multisampling, 3-promień 1.5km, 7-1km
|
||||
TDynamicObject *Global::changeDynObj=NULL; //info o zmianie pojazdu
|
||||
bool Global::detonatoryOK; //info o nowych detonatorach
|
||||
double Global::ABuDebug=0;
|
||||
AnsiString Global::asSky="1";
|
||||
double Global::fOpenGL=0.0; //wersja OpenGL - do sprawdzania obecności rozszerzeń
|
||||
bool Global::bOpenGL_1_5=false; //czy są dostępne funkcje OpenGL 1.5
|
||||
double Global::fLuminance=1.0; //jasność światła do automatycznego zapalania
|
||||
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.1166.469";
|
||||
AnsiString Global::asVersion="Compilation 2015-03-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,0,0,0,0,0,0}; //numer ekranu wyświetlacza tekstowego
|
||||
double Global::fSunDeclination=0.0; //deklinacja Słońca
|
||||
double Global::fTimeAngleDeg=0.0; //godzina w postaci kąta
|
||||
float Global::fClockAngleDeg[6]; //kąty obrotu cylindrów dla zegara cyfrowego
|
||||
char* Global::szTexturesTGA[4]={"tga","dds","tex","bmp"}; //lista tekstur od TGA
|
||||
char* Global::szTexturesDDS[4]={"dds","tga","tex","bmp"}; //lista tekstur od DDS
|
||||
int Global::iKeyLast=0; //ostatnio naciśnięty klawisz w celu logowania
|
||||
GLuint Global::iTextureId=0; //ostatnio użyta tekstura 2D
|
||||
int Global::iPause=0x10; //globalna pauza ruchu
|
||||
bool Global::bActive=true; //czy jest aktywnym oknem
|
||||
int Global::iErorrCounter=0; //licznik sprawdzań do śledzenia błędów OpenGL
|
||||
int Global::iTextures=0; //licznik użytych tekstur
|
||||
TWorld* Global::pWorld=NULL;
|
||||
Queryparsercomp::TQueryParserComp *Global::qParser=NULL;
|
||||
cParser *Global::pParser=NULL;
|
||||
int Global::iSegmentsRendered=90; //ilość segmentów do regulacji wydajności
|
||||
TCamera* Global::pCamera=NULL; //parametry kamery
|
||||
TDynamicObject *Global::pUserDynamic=NULL; //pojazd użytkownika, renderowany bez trzęsienia
|
||||
bool Global::bSmudge=false; //czy wyświetlać smugę, a pojazd użytkownika na końcu
|
||||
AnsiString Global::asTranscript[5]; //napisy na ekranie (widoczne)
|
||||
TTranscripts Global::tranTexts; //obiekt obsługujący stenogramy dźwięków na ekranie
|
||||
|
||||
//parametry scenerii
|
||||
vector3 Global::pCameraPosition;
|
||||
double Global::pCameraRotation;
|
||||
double Global::pCameraRotationDeg;
|
||||
vector3 Global::pFreeCameraInit[10];
|
||||
vector3 Global::pFreeCameraInitAngle[10];
|
||||
double Global::fFogStart=1700;
|
||||
double Global::fFogEnd=2000;
|
||||
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
|
||||
GLfloat Global::diffuseDayLight[] ={0.55f,0.54f,0.50f,1.0f};
|
||||
GLfloat Global::specularDayLight[]={0.95f,0.94f,0.90f,1.0f};
|
||||
GLfloat Global::ambientLight[] ={0.80f,0.80f,0.85f,1.0f}; //stałe
|
||||
GLfloat Global::diffuseLight[] ={0.85f,0.85f,0.80f,1.0f};
|
||||
GLfloat Global::specularLight[] ={0.95f,0.94f,0.90f,1.0f};
|
||||
GLfloat Global::whiteLight[] ={1.00f,1.00f,1.00f,1.0f};
|
||||
GLfloat Global::noLight[] ={0.00f,0.00f,0.00f,1.0f};
|
||||
GLfloat Global::darkLight[] ={0.03f,0.03f,0.03f,1.0f}; //śladowe
|
||||
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
|
||||
|
||||
//parametry użytkowe (jak komu pasuje)
|
||||
int Global::Keys[MaxKeys];
|
||||
int Global::iWindowWidth=800;
|
||||
int Global::iWindowHeight=600;
|
||||
float Global::fDistanceFactor=768.0; //baza do przeliczania odległości dla LoD
|
||||
int Global::iFeedbackMode=1; //tryb pracy informacji zwrotnej
|
||||
int Global::iFeedbackPort=0; //dodatkowy adres dla informacji zwrotnych
|
||||
bool Global::bFreeFly=false;
|
||||
bool Global::bFullScreen=false;
|
||||
bool Global::bInactivePause=true; //automatyczna pauza, gdy okno nieaktywne
|
||||
float Global::fMouseXScale=1.5;
|
||||
float Global::fMouseYScale=0.2;
|
||||
char Global::szSceneryFile[256]="td.scn";
|
||||
AnsiString Global::asHumanCtrlVehicle="EU07-424";
|
||||
int Global::iMultiplayer=0; //blokada działania niektórych funkcji na rzecz komunikacji
|
||||
double Global::fMoveLight=-1; //ruchome światło
|
||||
double Global::fLatitudeDeg=52.0; //szerokość geograficzna
|
||||
float Global::fFriction=1.0; //mnożnik tarcia - KURS90
|
||||
double Global::fBrakeStep=1.0; //krok zmiany hamulca dla klawiszy [Num3] i [Num9]
|
||||
AnsiString Global::asLang="pl"; //domyślny język - http://tools.ietf.org/html/bcp47
|
||||
|
||||
|
||||
//parametry wydajnościowe (np. regulacja FPS, szybkość wczytywania)
|
||||
bool Global::bAdjustScreenFreq=true;
|
||||
bool Global::bEnableTraction=true;
|
||||
bool Global::bLoadTraction=true;
|
||||
bool Global::bLiveTraction=true;
|
||||
int Global::iDefaultFiltering=9; //domyślne rozmywanie tekstur TGA bez alfa
|
||||
int Global::iBallastFiltering=9; //domyślne rozmywanie tekstur podsypki
|
||||
int Global::iRailProFiltering=5; //domyślne rozmywanie tekstur szyn
|
||||
int Global::iDynamicFiltering=5; //domyślne rozmywanie tekstur pojazdów
|
||||
bool Global::bUseVBO=false; //czy jest VBO w karcie graficznej (czy użyć)
|
||||
GLint Global::iMaxTextureSize=16384; //maksymalny rozmiar tekstury
|
||||
bool Global::bSmoothTraction=false; //wygładzanie drutów starym sposobem
|
||||
char** Global::szDefaultExt=Global::szTexturesDDS; //domyślnie od DDS
|
||||
int Global::iMultisampling=2; //tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px
|
||||
bool Global::bGlutFont=false; //czy tekst generowany przez GLUT32.DLL
|
||||
int Global::iConvertModels=7; //tworzenie plików binarnych, +2-optymalizacja transformów
|
||||
int Global::iSlowMotionMask=-1; //maska wyłączanych właściwości dla zwiększenia FPS
|
||||
int Global::iModifyTGA=7; //czy korygować pliki TGA dla szybszego wczytywania
|
||||
//bool Global::bTerrainCompact=true; //czy zapisać teren w pliku
|
||||
TAnimModel *Global::pTerrainCompact=NULL; //do zapisania terenu w pliku
|
||||
AnsiString Global::asTerrainModel=""; //nazwa obiektu terenu do zapisania w pliku
|
||||
double Global::fFpsAverage=20.0; //oczekiwana wartosć FPS
|
||||
double Global::fFpsDeviation=5.0; //odchylenie standardowe FPS
|
||||
double Global::fFpsMin=0.0; //dolna granica FPS, przy której promień scenerii będzie zmniejszany
|
||||
double Global::fFpsMax=0.0; //górna granica FPS, przy której promień scenerii będzie zwiększany
|
||||
double Global::fFpsRadiusMax=3000.0; //maksymalny promień renderowania
|
||||
int Global::iFpsRadiusMax=225; //maksymalny promień renderowania
|
||||
double Global::fRadiusFactor=1.1; //współczynnik jednorazowej zmiany promienia scenerii
|
||||
|
||||
//parametry testowe (do testowania scenerii i obiektów)
|
||||
bool Global::bWireFrame=false;
|
||||
bool Global::bSoundEnabled=true;
|
||||
int Global::iWriteLogEnabled=3; //maska bitowa: 1-zapis do pliku, 2-okienko, 4-nazwy torów
|
||||
bool Global::bManageNodes=true;
|
||||
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}};
|
||||
|
||||
//parametry przejściowe (do usunięcia)
|
||||
//bool Global::bTimeChange=false; //Ra: ZiomalCl wyłączył starą wersję nocy
|
||||
//bool Global::bRenderAlpha=true; //Ra: wywaliłam tę flagę
|
||||
bool Global::bnewAirCouplers=true;
|
||||
bool Global::bDoubleAmbient=false; //podwójna jasność ambient
|
||||
double Global::fTimeSpeed=1.0; //przyspieszenie czasu, zmienna do testów
|
||||
bool Global::bHideConsole=false; //hunter-271211: ukrywanie konsoli
|
||||
int Global::iBpp=32; //chyba już nie używa się kart, na których 16bpp coś poprawi
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
AnsiString __fastcall Global::GetNextSymbol()
|
||||
{//pobranie tokenu z aktualnego parsera
|
||||
if (qParser) return qParser->EndOfFile?AnsiString("endconfig"):qParser->GetNextSymbol();
|
||||
if (pParser)
|
||||
{std::string token;
|
||||
pParser->getTokens();
|
||||
*pParser >> token;
|
||||
return AnsiString(token.c_str());
|
||||
};
|
||||
return "";
|
||||
};
|
||||
|
||||
void __fastcall Global::LoadIniFile(AnsiString asFileName)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<10;++i)
|
||||
{//zerowanie pozycji kamer
|
||||
pFreeCameraInit[i]=vector3(0,0,0); //współrzędne w scenerii
|
||||
pFreeCameraInitAngle[i]=vector3(0,0,0); //kąty obrotu w radianach
|
||||
}
|
||||
TFileStream *fs;
|
||||
fs=new TFileStream(asFileName,fmOpenRead|fmShareCompat);
|
||||
if (!fs) return;
|
||||
AnsiString str="";
|
||||
int size=fs->Size;
|
||||
str.SetLength(size);
|
||||
fs->Read(str.c_str(),size);
|
||||
//str+="";
|
||||
delete fs;
|
||||
TQueryParserComp *Parser;
|
||||
Parser=new TQueryParserComp(NULL);
|
||||
Parser->TextToParse=str;
|
||||
//Parser->LoadStringToParse(asFile);
|
||||
Parser->First();
|
||||
ConfigParse(Parser);
|
||||
delete Parser; //Ra: tego jak zwykle nie było wcześniej :]
|
||||
};
|
||||
|
||||
void __fastcall Global::ConfigParse(TQueryParserComp *qp,cParser *cp)
|
||||
{//Ra: trzeba by przerobić na cParser, żeby to działało w scenerii
|
||||
pParser=cp;
|
||||
qParser=qp;
|
||||
AnsiString str;
|
||||
int i;
|
||||
do
|
||||
{
|
||||
str=GetNextSymbol().LowerCase();
|
||||
if (str==AnsiString("sceneryfile"))
|
||||
{
|
||||
str=GetNextSymbol().LowerCase();
|
||||
strcpy(szSceneryFile,str.c_str());
|
||||
}
|
||||
else
|
||||
if (str==AnsiString("humanctrlvehicle"))
|
||||
{
|
||||
str=GetNextSymbol().LowerCase();
|
||||
asHumanCtrlVehicle=str;
|
||||
}
|
||||
else if (str==AnsiString("width"))
|
||||
iWindowWidth=GetNextSymbol().ToInt();
|
||||
else if (str==AnsiString("height"))
|
||||
iWindowHeight=GetNextSymbol().ToInt();
|
||||
else if (str==AnsiString("heightbase"))
|
||||
fDistanceFactor=GetNextSymbol().ToInt();
|
||||
else if (str==AnsiString("bpp"))
|
||||
iBpp=((GetNextSymbol().LowerCase()==AnsiString("32")) ? 32 : 16 );
|
||||
else if (str==AnsiString("fullscreen"))
|
||||
bFullScreen=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("freefly")) //Mczapkie-130302
|
||||
{
|
||||
bFreeFly=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
pFreeCameraInit[0].x=GetNextSymbol().ToDouble();
|
||||
pFreeCameraInit[0].y=GetNextSymbol().ToDouble();
|
||||
pFreeCameraInit[0].z=GetNextSymbol().ToDouble();
|
||||
}
|
||||
else if (str==AnsiString("wireframe"))
|
||||
bWireFrame=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("debugmode")) //McZapkie! - DebugModeFlag uzywana w mover.pas, warto tez blokowac cheaty gdy false
|
||||
DebugModeFlag=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("soundenabled")) //McZapkie-040302 - blokada dzwieku - przyda sie do debugowania oraz na komp. bez karty dzw.
|
||||
bSoundEnabled=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
//else if (str==AnsiString("renderalpha")) //McZapkie-1312302 - dwuprzebiegowe renderowanie
|
||||
// bRenderAlpha=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("physicslog")) //McZapkie-030402 - logowanie parametrow fizycznych dla kazdego pojazdu z maszynista
|
||||
WriteLogFlag=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("physicsdeactivation")) //McZapkie-291103 - usypianie fizyki
|
||||
PhysicActivationFlag=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("debuglog"))
|
||||
{//McZapkie-300402 - wylaczanie log.txt
|
||||
str=GetNextSymbol().LowerCase();
|
||||
if (str=="yes") iWriteLogEnabled=3;
|
||||
else if (str=="no") iWriteLogEnabled=0;
|
||||
else iWriteLogEnabled=str.ToIntDef(3);
|
||||
}
|
||||
else if (str==AnsiString("adjustscreenfreq"))
|
||||
{//McZapkie-240403 - czestotliwosc odswiezania ekranu
|
||||
str=GetNextSymbol();
|
||||
bAdjustScreenFreq=(str.LowerCase()==AnsiString("yes"));
|
||||
}
|
||||
else if (str==AnsiString("mousescale"))
|
||||
{//McZapkie-060503 - czulosc ruchu myszy (krecenia glowa)
|
||||
str=GetNextSymbol();
|
||||
fMouseXScale=str.ToDouble();
|
||||
str=GetNextSymbol();
|
||||
fMouseYScale=str.ToDouble();
|
||||
}
|
||||
else if (str==AnsiString("enabletraction"))
|
||||
{//Winger 040204 - 'zywe' patyki dostosowujace sie do trakcji; Ra 2014-03: teraz łamanie
|
||||
bEnableTraction=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
}
|
||||
else if (str==AnsiString("loadtraction"))
|
||||
{//Winger 140404 - ladowanie sie trakcji
|
||||
bLoadTraction=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
}
|
||||
else if (str==AnsiString("friction")) //mnożnik tarcia - KURS90
|
||||
fFriction=GetNextSymbol().ToDouble();
|
||||
else if (str==AnsiString("livetraction"))
|
||||
{//Winger 160404 - zaleznosc napiecia loka od trakcji; Ra 2014-03: teraz prąd przy braku sieci
|
||||
bLiveTraction=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
}
|
||||
else if (str==AnsiString("skyenabled"))
|
||||
{//youBy - niebo
|
||||
if (GetNextSymbol().LowerCase()==AnsiString("yes"))
|
||||
asSky="1"; else asSky="0";
|
||||
}
|
||||
else if (str==AnsiString("managenodes"))
|
||||
{
|
||||
bManageNodes=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
}
|
||||
else if (str==AnsiString("decompressdds"))
|
||||
{
|
||||
bDecompressDDS=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
}
|
||||
// ShaXbee - domyslne rozszerzenie tekstur
|
||||
else if (str==AnsiString("defaultext"))
|
||||
{str=GetNextSymbol().LowerCase(); //rozszerzenie
|
||||
if (str=="tga")
|
||||
szDefaultExt=szTexturesTGA; //domyślnie od TGA
|
||||
//szDefaultExt=std::string(Parser->GetNextSymbol().LowerCase().c_str());
|
||||
}
|
||||
else if (str==AnsiString("newaircouplers"))
|
||||
bnewAirCouplers=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("defaultfiltering"))
|
||||
iDefaultFiltering=GetNextSymbol().ToIntDef(-1);
|
||||
else if (str==AnsiString("ballastfiltering"))
|
||||
iBallastFiltering=GetNextSymbol().ToIntDef(-1);
|
||||
else if (str==AnsiString("railprofiltering"))
|
||||
iRailProFiltering=GetNextSymbol().ToIntDef(-1);
|
||||
else if (str==AnsiString("dynamicfiltering"))
|
||||
iDynamicFiltering=GetNextSymbol().ToIntDef(-1);
|
||||
else if (str==AnsiString("usevbo"))
|
||||
bUseVBO=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("feedbackmode"))
|
||||
iFeedbackMode=GetNextSymbol().ToIntDef(1); //domyślnie 1
|
||||
else if (str==AnsiString("feedbackport"))
|
||||
iFeedbackPort=GetNextSymbol().ToIntDef(0); //domyślnie 0
|
||||
else if (str==AnsiString("multiplayer"))
|
||||
iMultiplayer=GetNextSymbol().ToIntDef(0); //domyślnie 0
|
||||
else if (str==AnsiString("maxtexturesize"))
|
||||
{//wymuszenie przeskalowania tekstur
|
||||
i=GetNextSymbol().ToIntDef(16384); //domyślnie duże
|
||||
if (i<= 64) iMaxTextureSize= 64; else
|
||||
if (i<= 128) iMaxTextureSize= 128; else
|
||||
if (i<= 256) iMaxTextureSize= 256; else
|
||||
if (i<= 512) iMaxTextureSize= 512; else
|
||||
if (i<=1024) iMaxTextureSize=1024; else
|
||||
if (i<=2048) iMaxTextureSize=2048; else
|
||||
if (i<=4096) iMaxTextureSize=4096; else
|
||||
if (i<=8192) iMaxTextureSize=8192; else
|
||||
iMaxTextureSize=16384;
|
||||
}
|
||||
else if (str==AnsiString("doubleambient")) //podwójna jasność ambient
|
||||
bDoubleAmbient=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("movelight")) //numer dnia w roku albo -1
|
||||
{fMoveLight=GetNextSymbol().ToIntDef(-1); //numer dnia 1..365
|
||||
if (fMoveLight==0.0)
|
||||
{//pobranie daty z systemu
|
||||
unsigned short y,m,d;
|
||||
TDate date=Now();
|
||||
date.DecodeDate(&y,&m,&d);
|
||||
fMoveLight=(double)date-(double)TDate(y,1,1)+1; //numer bieżącego dnia w roku
|
||||
}
|
||||
if (fMoveLight>0.0) //tu jest nadal zwiększone o 1
|
||||
{//obliczenie deklinacji wg:
|
||||
//http://naturalfrequency.com/Tregenza_Sharples/Daylight_Algorithms/algorithm_1_11.htm
|
||||
//Spencer J W Fourier series representation of the position of the sun Search 2 (5) 172 (1971)
|
||||
fMoveLight=M_PI/182.5*(Global::fMoveLight-1.0); //numer dnia w postaci kąta
|
||||
fSunDeclination=0.006918-0.3999120*cos( fMoveLight)+0.0702570*sin( fMoveLight)
|
||||
-0.0067580*cos(2*fMoveLight)+0.0009070*sin(2*fMoveLight)
|
||||
-0.0026970*cos(3*fMoveLight)+0.0014800*sin(3*fMoveLight);
|
||||
}
|
||||
}
|
||||
else if (str==AnsiString("smoothtraction")) //podwójna jasność ambient
|
||||
bSmoothTraction=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("timespeed")) //przyspieszenie czasu, zmienna do testów
|
||||
fTimeSpeed=GetNextSymbol().ToIntDef(1);
|
||||
else if (str==AnsiString("multisampling")) //tryb antyaliasingu: 0=brak,1=2px,2=4px
|
||||
iMultisampling=GetNextSymbol().ToIntDef(2); //domyślnie 2
|
||||
else if (str==AnsiString("glutfont")) //tekst generowany przez GLUT
|
||||
bGlutFont=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("latitude")) //szerokość geograficzna
|
||||
fLatitudeDeg=GetNextSymbol().ToDouble();
|
||||
else if (str==AnsiString("convertmodels")) //tworzenie plików binarnych
|
||||
iConvertModels=GetNextSymbol().ToIntDef(7); //domyślnie 7
|
||||
else if (str==AnsiString("inactivepause")) //automatyczna pauza, gdy okno nieaktywne
|
||||
bInactivePause=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("slowmotion")) //tworzenie plików binarnych
|
||||
iSlowMotionMask=GetNextSymbol().ToIntDef(-1); //domyślnie -1
|
||||
else if (str==AnsiString("modifytga")) //czy korygować pliki TGA dla szybszego wczytywania
|
||||
iModifyTGA=GetNextSymbol().ToIntDef(0); //domyślnie 0
|
||||
else if (str==AnsiString("hideconsole")) //hunter-271211: ukrywanie konsoli
|
||||
bHideConsole=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("rollfix")) //Ra: poprawianie przechyłki, aby wewnętrzna szyna była "pozioma"
|
||||
bRollFix=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("fpsaverage")) //oczekiwana wartosć FPS
|
||||
fFpsAverage=GetNextSymbol().ToDouble();
|
||||
else if (str==AnsiString("fpsdeviation")) //odchylenie standardowe FPS
|
||||
fFpsDeviation=GetNextSymbol().ToDouble();
|
||||
else if (str==AnsiString("fpsradiusmax")) //maksymalny promień renderowania
|
||||
fFpsRadiusMax=GetNextSymbol().ToDouble();
|
||||
else if (str==AnsiString("calibratein")) //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
|
||||
}
|
||||
else if (str==AnsiString("calibrateout")) //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
|
||||
}
|
||||
else if (str==AnsiString("brakestep")) //krok zmiany hamulca dla klawiszy [Num3] i [Num9]
|
||||
fBrakeStep=GetNextSymbol().ToDouble();
|
||||
else if (str==AnsiString("joinduplicatedevents")) //czy grupować eventy o tych samych nazwach
|
||||
bJoinEvents=(GetNextSymbol().LowerCase()==AnsiString("yes"));
|
||||
else if (str==AnsiString("hiddenevents")) //czy łączyć eventy z torami poprzez nazwę toru
|
||||
iHiddenEvents=GetNextSymbol().ToIntDef(0);
|
||||
else if (str==AnsiString("pause")) //czy po wczytaniu ma być pauza?
|
||||
iPause|=(GetNextSymbol().LowerCase()==AnsiString("yes"))?1:0;
|
||||
else if (str==AnsiString("lang"))
|
||||
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)
|
||||
//na koniec trochę zależności
|
||||
if (!bLoadTraction) //wczytywanie drutów i słupów
|
||||
{//tutaj wyłączenie, bo mogą nie być zdefiniowane w INI
|
||||
bEnableTraction=false; //false = pantograf się nie połamie
|
||||
bLiveTraction=false; //false = pantografy zawsze zbierają 95% MaxVoltage
|
||||
}
|
||||
//if (fMoveLight>0) bDoubleAmbient=false; //wtedy tylko jedno światło ruchome
|
||||
//if (fOpenGL<1.3) iMultisampling=0; //można by z góry wyłączyć, ale nie mamy jeszcze fOpenGL
|
||||
if (iMultisampling)
|
||||
{//antyaliasing całoekranowy wyłącza rozmywanie drutów
|
||||
bSmoothTraction=false;
|
||||
}
|
||||
if (iMultiplayer>0)
|
||||
{bInactivePause=false; //okno "w tle" nie może pauzować, jeśli włączona komunikacja
|
||||
//pauzowanie jest zablokowane dla (iMultiplayer&2)>0, więc iMultiplayer=1 da się zapauzować (tryb instruktora)
|
||||
}
|
||||
fFpsMin=fFpsAverage-fFpsDeviation; //dolna granica FPS, przy której promień scenerii będzie zmniejszany
|
||||
fFpsMax=fFpsAverage+fFpsDeviation; //górna granica FPS, przy której promień scenerii będzie zwiększany
|
||||
if (iPause) iTextMode=VK_F1; //jak pauza, to pokazać zegar
|
||||
if (qp)
|
||||
{//to poniżej wykonywane tylko raz, jedynie po wczytaniu eu07.ini
|
||||
Console::ModeSet(iFeedbackMode,iFeedbackPort); //tryb pracy konsoli sterowniczej
|
||||
iFpsRadiusMax=0.000025*fFpsRadiusMax*fFpsRadiusMax; //maksymalny promień renderowania 3000.0 -> 225
|
||||
if (iFpsRadiusMax>400) iFpsRadiusMax=400;
|
||||
if (fDistanceFactor>1.0)
|
||||
{//dla 1.0 specjalny tryb bez przeliczania
|
||||
fDistanceFactor=iWindowHeight/fDistanceFactor; //fDistanceFactor>1.0 dla rozdzielczości większych niż bazowa
|
||||
fDistanceFactor*=(iMultisampling+1.0)*fDistanceFactor; //do kwadratu, bo większość odległości to ich kwadraty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __fastcall Global::InitKeys(AnsiString asFileName)
|
||||
{
|
||||
// if (FileExists(asFileName))
|
||||
// {
|
||||
// Error("Chwilowo plik keys.ini nie jest obsługiwany. Ładuję standardowe ustawienia.\nKeys.ini file is temporarily not functional, loading default keymap...");
|
||||
/* TQueryParserComp *Parser;
|
||||
Parser=new TQueryParserComp(NULL);
|
||||
Parser->LoadStringToParse(asFileName);
|
||||
|
||||
for (int keycount=0; keycount<MaxKeys; keycount++)
|
||||
{
|
||||
Keys[keycount]=Parser->GetNextSymbol().ToInt();
|
||||
}
|
||||
|
||||
delete Parser;
|
||||
*/
|
||||
// }
|
||||
// else
|
||||
{
|
||||
Keys[k_IncMainCtrl]=VK_ADD;
|
||||
Keys[k_IncMainCtrlFAST]=VK_ADD;
|
||||
Keys[k_DecMainCtrl]=VK_SUBTRACT;
|
||||
Keys[k_DecMainCtrlFAST]=VK_SUBTRACT;
|
||||
Keys[k_IncScndCtrl]=VK_DIVIDE;
|
||||
Keys[k_IncScndCtrlFAST]=VK_DIVIDE;
|
||||
Keys[k_DecScndCtrl]=VK_MULTIPLY;
|
||||
Keys[k_DecScndCtrlFAST]=VK_MULTIPLY;
|
||||
///*NORMALNE
|
||||
Keys[k_IncLocalBrakeLevel]=VK_NUMPAD1; //VK_NUMPAD7;
|
||||
//Keys[k_IncLocalBrakeLevelFAST]=VK_END; //VK_HOME;
|
||||
Keys[k_DecLocalBrakeLevel]=VK_NUMPAD7; //VK_NUMPAD1;
|
||||
//Keys[k_DecLocalBrakeLevelFAST]=VK_HOME; //VK_END;
|
||||
Keys[k_IncBrakeLevel]=VK_NUMPAD3; //VK_NUMPAD9;
|
||||
Keys[k_DecBrakeLevel]=VK_NUMPAD9; //VK_NUMPAD3;
|
||||
Keys[k_Releaser]=VK_NUMPAD6;
|
||||
Keys[k_EmergencyBrake]=VK_NUMPAD0;
|
||||
Keys[k_Brake3]=VK_NUMPAD8;
|
||||
Keys[k_Brake2]=VK_NUMPAD5;
|
||||
Keys[k_Brake1]=VK_NUMPAD2;
|
||||
Keys[k_Brake0]=VK_NUMPAD4;
|
||||
Keys[k_WaveBrake]=VK_DECIMAL;
|
||||
//*/
|
||||
/*MOJE
|
||||
Keys[k_IncLocalBrakeLevel]=VK_NUMPAD3; //VK_NUMPAD7;
|
||||
Keys[k_IncLocalBrakeLevelFAST]=VK_NUMPAD3; //VK_HOME;
|
||||
Keys[k_DecLocalBrakeLevel]=VK_DECIMAL; //VK_NUMPAD1;
|
||||
Keys[k_DecLocalBrakeLevelFAST]=VK_DECIMAL; //VK_END;
|
||||
Keys[k_IncBrakeLevel]=VK_NUMPAD6; //VK_NUMPAD9;
|
||||
Keys[k_DecBrakeLevel]=VK_NUMPAD9; //VK_NUMPAD3;
|
||||
Keys[k_Releaser]=VK_NUMPAD5;
|
||||
Keys[k_EmergencyBrake]=VK_NUMPAD0;
|
||||
Keys[k_Brake3]=VK_NUMPAD2;
|
||||
Keys[k_Brake2]=VK_NUMPAD1;
|
||||
Keys[k_Brake1]=VK_NUMPAD4;
|
||||
Keys[k_Brake0]=VK_NUMPAD7;
|
||||
Keys[k_WaveBrake]=VK_NUMPAD8;
|
||||
*/
|
||||
Keys[k_AntiSlipping]=VK_RETURN;
|
||||
Keys[k_Sand]=VkKeyScan('s');
|
||||
Keys[k_Main]=VkKeyScan('m');
|
||||
Keys[k_Active]=VkKeyScan('w');
|
||||
Keys[k_Battery]=VkKeyScan('j');
|
||||
Keys[k_DirectionForward]=VkKeyScan('d');
|
||||
Keys[k_DirectionBackward]=VkKeyScan('r');
|
||||
Keys[k_Fuse]=VkKeyScan('n');
|
||||
Keys[k_Compressor]=VkKeyScan('c');
|
||||
Keys[k_Converter]=VkKeyScan('x');
|
||||
Keys[k_MaxCurrent]=VkKeyScan('f');
|
||||
Keys[k_CurrentAutoRelay]=VkKeyScan('g');
|
||||
Keys[k_BrakeProfile]=VkKeyScan('b');
|
||||
Keys[k_CurrentNext]=VkKeyScan('z');
|
||||
|
||||
Keys[k_Czuwak]=VkKeyScan(' ');
|
||||
Keys[k_Horn]=VkKeyScan('a');
|
||||
Keys[k_Horn2]=VkKeyScan('a');
|
||||
|
||||
Keys[k_FailedEngineCutOff]=VkKeyScan('e');
|
||||
|
||||
Keys[k_MechUp]=VK_PRIOR;
|
||||
Keys[k_MechDown]=VK_NEXT ;
|
||||
Keys[k_MechLeft]=VK_LEFT ;
|
||||
Keys[k_MechRight]=VK_RIGHT;
|
||||
Keys[k_MechForward]=VK_UP;
|
||||
Keys[k_MechBackward]=VK_DOWN;
|
||||
|
||||
Keys[k_CabForward]=VK_HOME;
|
||||
Keys[k_CabBackward]=VK_END;
|
||||
|
||||
Keys[k_Couple]=VK_INSERT;
|
||||
Keys[k_DeCouple]=VK_DELETE;
|
||||
|
||||
Keys[k_ProgramQuit]=VK_F10;
|
||||
//Keys[k_ProgramPause]=VK_F3;
|
||||
Keys[k_ProgramHelp]=VK_F1;
|
||||
//Keys[k_FreeFlyMode]=VK_F4;
|
||||
Keys[k_WalkMode]=VK_F5;
|
||||
|
||||
Keys[k_OpenLeft]=VkKeyScan(',');
|
||||
Keys[k_OpenRight]=VkKeyScan('.');
|
||||
Keys[k_CloseLeft]=VkKeyScan(',');
|
||||
Keys[k_CloseRight]=VkKeyScan('.');
|
||||
Keys[k_DepartureSignal]=VkKeyScan('/');
|
||||
|
||||
//Winger 160204 - obsluga pantografow
|
||||
Keys[k_PantFrontUp]=VkKeyScan('p'); //Ra: zamieniony przedni z tylnym
|
||||
Keys[k_PantFrontDown]=VkKeyScan('p');
|
||||
Keys[k_PantRearUp]=VkKeyScan('o');
|
||||
Keys[k_PantRearDown]=VkKeyScan('o');
|
||||
//Winger 020304 - ogrzewanie
|
||||
Keys[k_Heating]=VkKeyScan('h');
|
||||
Keys[k_LeftSign]=VkKeyScan('y');
|
||||
Keys[k_UpperSign]=VkKeyScan('u');
|
||||
Keys[k_RightSign]=VkKeyScan('i');
|
||||
Keys[k_EndSign]=VkKeyScan('t');
|
||||
|
||||
Keys[k_SmallCompressor]=VkKeyScan('v');
|
||||
Keys[k_StLinOff]=VkKeyScan('l');
|
||||
//ABu 090305 - przyciski uniwersalne, do roznych bajerow :)
|
||||
Keys[k_Univ1]=VkKeyScan('[');
|
||||
Keys[k_Univ2]=VkKeyScan(']');
|
||||
Keys[k_Univ3]=VkKeyScan(';');
|
||||
Keys[k_Univ4]=VkKeyScan('\'');
|
||||
}
|
||||
}
|
||||
/*
|
||||
vector3 __fastcall Global::GetCameraPosition()
|
||||
{
|
||||
return pCameraPosition;
|
||||
}
|
||||
*/
|
||||
void __fastcall Global::SetCameraPosition(vector3 pNewCameraPosition)
|
||||
{
|
||||
pCameraPosition=pNewCameraPosition;
|
||||
}
|
||||
|
||||
void __fastcall Global::SetCameraRotation(double Yaw)
|
||||
{//ustawienie bezwzględnego kierunku kamery z korekcją do przedziału <-M_PI,M_PI>
|
||||
pCameraRotation=Yaw;
|
||||
while (pCameraRotation<-M_PI) pCameraRotation+=2*M_PI;
|
||||
while (pCameraRotation> M_PI) pCameraRotation-=2*M_PI;
|
||||
pCameraRotationDeg=pCameraRotation*180.0/M_PI;
|
||||
}
|
||||
|
||||
void __fastcall Global::BindTexture(GLuint t)
|
||||
{//ustawienie aktualnej tekstury, tylko gdy się zmienia
|
||||
if (t!=iTextureId)
|
||||
{iTextureId=t;
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall Global::TrainDelete(TDynamicObject *d)
|
||||
{//usunięcie pojazdu prowadzonego przez użytkownika
|
||||
if (pWorld) pWorld->TrainDelete(d);
|
||||
};
|
||||
|
||||
TDynamicObject* __fastcall Global::DynamicNearest()
|
||||
{//ustalenie pojazdu najbliższego kamerze
|
||||
return pGround->DynamicNearest(pCamera->Pos);
|
||||
};
|
||||
|
||||
TDynamicObject* __fastcall Global::CouplerNearest()
|
||||
{//ustalenie pojazdu najbliższego kamerze
|
||||
return pGround->CouplerNearest(pCamera->Pos);
|
||||
};
|
||||
|
||||
bool __fastcall Global::AddToQuery(TEvent *event,TDynamicObject *who)
|
||||
{
|
||||
return pGround->AddToQuery(event,who);
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool __fastcall Global::DoEvents()
|
||||
{//wywoływać czasem, żeby nie robił wrażenia zawieszonego
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (msg.message==WM_QUIT)
|
||||
return FALSE;
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
__fastcall TTranscripts::TTranscripts()
|
||||
{
|
||||
iCount=0; //brak linijek do wyświetlenia
|
||||
iStart=0; //wypełniać od linijki 0
|
||||
for (int i=0;i<MAX_TRANSCRIPTS;++i)
|
||||
{//to do konstruktora można by dać
|
||||
aLines[i].fHide=-1.0; //wolna pozycja (czas symulacji, 360.0 to doba)
|
||||
aLines[i].iNext=-1; //nie ma kolejnej
|
||||
}
|
||||
fRefreshTime=360.0; //wartośc zaporowa
|
||||
};
|
||||
__fastcall TTranscripts::~TTranscripts()
|
||||
{
|
||||
};
|
||||
void __fastcall TTranscripts::AddLine(char *txt,float show,float hide,bool it)
|
||||
{//dodanie linii do tabeli, (show) i (hide) w [s] od aktualnego czasu
|
||||
if (show==hide) return; //komentarz jest ignorowany
|
||||
show=Global::fTimeAngleDeg+show/240.0; //jeśli doba to 360, to 1s będzie równe 1/240
|
||||
hide=Global::fTimeAngleDeg+hide/240.0;
|
||||
int i=iStart,j,k; //od czegoś trzeba zacząć
|
||||
while ((aLines[i].iNext>=0)?(aLines[aLines[i].iNext].fShow<=show):false) //póki nie koniec i wcześniej puszczane
|
||||
i=aLines[i].iNext; //przejście do kolejnej linijki
|
||||
//(i) wskazuje na linię, po której należy wstawić dany tekst, chyba że
|
||||
while (txt?*txt:false)
|
||||
for (j=0;j<MAX_TRANSCRIPTS;++j)
|
||||
if (aLines[j].fHide<0.0)
|
||||
{//znaleziony pierwszy wolny
|
||||
aLines[j].iNext=aLines[i].iNext; //dotychczasowy następny będzie za nowym
|
||||
if (aLines[iStart].fHide<0.0) //jeśli tablica jest pusta
|
||||
iStart=j; //fHide trzeba sprawdzić przed ewentualnym nadpisaniem, gdy i=j=0
|
||||
else
|
||||
aLines[i].iNext=j; //a nowy będzie za tamtym wcześniejszym
|
||||
aLines[j].fShow=show; //wyświetlać od
|
||||
aLines[j].fHide=hide; //wyświetlać do
|
||||
aLines[j].bItalic=it;
|
||||
aLines[j].asText=AnsiString(txt); //bez sensu, wystarczyłby wskaźnik
|
||||
if ((k=aLines[j].asText.Pos("|"))>0)
|
||||
{//jak jest podział linijki na wiersze
|
||||
aLines[j].asText=aLines[j].asText.SubString(1,k-1);
|
||||
txt+=k;
|
||||
i=j; //kolejna linijka dopisywana będzie na koniec właśnie dodanej
|
||||
}
|
||||
else
|
||||
txt=NULL; //koniec dodawania
|
||||
if (fRefreshTime>show) //jeśli odświeżacz ustawiony jest na później
|
||||
fRefreshTime=show; //to odświeżyć wcześniej
|
||||
break; //więcej już nic
|
||||
}
|
||||
};
|
||||
void __fastcall TTranscripts::Add(char *txt,float len,bool backgorund)
|
||||
{//dodanie tekstów, długość dźwięku, czy istotne
|
||||
if (!txt) return; //pusty tekst
|
||||
int i=0,j=int(0.5+10.0*len); //[0.1s]
|
||||
if (*txt=='[')
|
||||
{//powinny być dwa nawiasy
|
||||
while (*++txt?*txt!=']':false)
|
||||
if ((*txt>='0')&&(*txt<='9'))
|
||||
i=10*i+int(*txt-'0'); //pierwsza liczba aż do ]
|
||||
if (*txt?*++txt=='[':false)
|
||||
{j=0; //drugi nawias określa czas zakończenia wyświetlania
|
||||
while (*++txt?*txt!=']':false)
|
||||
if ((*txt>='0')&&(*txt<='9'))
|
||||
j=10*j+int(*txt-'0'); //druga liczba aż do ]
|
||||
if (*txt) ++txt; //pominięcie drugiego ]
|
||||
}
|
||||
}
|
||||
AddLine(txt,0.1*i,0.1*j,false);
|
||||
};
|
||||
void __fastcall TTranscripts::Update()
|
||||
{//usuwanie niepotrzebnych (nie częściej niż 10 razy na sekundę)
|
||||
if (fRefreshTime>Global::fTimeAngleDeg)
|
||||
return; //nie czas jeszcze na zmiany
|
||||
//czas odświeżenia można ustalić wg tabelki, kiedy coś się w niej zmienia
|
||||
fRefreshTime=Global::fTimeAngleDeg+360.0; //wartość zaporowa
|
||||
int i=iStart,j=-1; //od czegoś trzeba zacząć
|
||||
bool change=false; //czy zmieniać napisy?
|
||||
do
|
||||
{
|
||||
if (aLines[i].fHide>=0.0) //o ile aktywne
|
||||
if (aLines[i].fHide<Global::fTimeAngleDeg)
|
||||
{//gdy czas wyświetlania upłynął
|
||||
aLines[i].fHide=-1.0; //teraz będzie wolną pozycją
|
||||
if (i==iStart)
|
||||
iStart=aLines[i].iNext>=0?aLines[i].iNext:0; //przestawienie pierwszego
|
||||
else if (j>=0)
|
||||
aLines[j].iNext=aLines[i].iNext; //usunięcie ze środka
|
||||
change=true;
|
||||
}
|
||||
else
|
||||
{//gdy ma być pokazane
|
||||
if (aLines[i].fShow>Global::fTimeAngleDeg) //będzie pokazane w przyszłości
|
||||
if (fRefreshTime>aLines[i].fShow) //a nie ma nic wcześniej
|
||||
fRefreshTime=aLines[i].fShow;
|
||||
if (fRefreshTime>aLines[i].fHide)
|
||||
fRefreshTime=aLines[i].fHide;
|
||||
}
|
||||
//można by jeszcze wykrywać, które nowe mają być pokazane
|
||||
j=i;
|
||||
i=aLines[i].iNext; //kolejna linijka
|
||||
} while (i>=0); //póki po tablicy
|
||||
change=true; //bo na razie nie ma warunku, że coś się dodało
|
||||
if (change)
|
||||
{//aktualizacja linijek ekranowych
|
||||
i=iStart; j=-1;
|
||||
do
|
||||
{
|
||||
if (aLines[i].fHide>0.0) //jeśli nie ukryte
|
||||
if (aLines[i].fShow<Global::fTimeAngleDeg) //to dodanie linijki do wyświetlania
|
||||
if (j<5-1) //ograniczona liczba linijek
|
||||
Global::asTranscript[++j]=aLines[i].asText; //skopiowanie tekstu
|
||||
i=aLines[i].iNext; //kolejna linijka
|
||||
} while (i>=0); //póki po tablicy
|
||||
for (++j;j<5;++j)
|
||||
Global::asTranscript[j]=""; //i czyszczenie nieużywanych linijek
|
||||
}
|
||||
};
|
||||
|
||||
//Ra: tymczasowe rozwiązanie kwestii zagranicznych (czeskich) napisów
|
||||
char bezogonkowo[128]=
|
||||
"E?,?\"_++?%S<STZZ?`'\"\".--??s>stzz"
|
||||
" ^^L$A|S^CS<--RZo±,l'uP.,as>L\"lz"
|
||||
"RAAAALCCCEEEEIIDDNNOOOOxRUUUUYTB"
|
||||
"raaaalccceeeeiiddnnoooo-ruuuuyt?";
|
||||
|
||||
AnsiString __fastcall Global::Bezogonkow(AnsiString str, bool _)
|
||||
{//wycięcie liter z ogonkami, bo OpenGL nie umie wyświetlić
|
||||
for (int i=1;i<=str.Length();++i)
|
||||
if (str[i]&0x80)
|
||||
str[i]=bezogonkowo[str[i]&0x7F];
|
||||
else if (str[i]<' ') //znaki sterujące nie są obsługiwane
|
||||
str[i]=' ';
|
||||
else if (_) if (str[i]=='_') //nazwy stacji nie mogą zawierać spacji
|
||||
str[i]=' '; //więc trzeba wyświetlać inaczej
|
||||
return str;
|
||||
}
|
||||
|
||||
#pragma package(smart_init)
|
||||
306
Globals.h
Normal file
306
Globals.h
Normal file
@@ -0,0 +1,306 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef GlobalsH
|
||||
#define GlobalsH
|
||||
|
||||
#include <string>
|
||||
#include "system.hpp"
|
||||
#include "opengl/glew.h"
|
||||
#include "dumb3d.h"
|
||||
//#include "Classes.h"
|
||||
|
||||
using namespace Math3D;
|
||||
|
||||
//definicje klawiszy
|
||||
const int k_IncMainCtrl= 0; //[Num+]
|
||||
const int k_IncMainCtrlFAST= 1; //[Num+] [Shift]
|
||||
const int k_DecMainCtrl= 2; //[Num-]
|
||||
const int k_DecMainCtrlFAST= 3; //[Num-] [Shift]
|
||||
const int k_IncScndCtrl= 4; //[Num/]
|
||||
const int k_IncScndCtrlFAST= 5;
|
||||
const int k_DecScndCtrl= 6;
|
||||
const int k_DecScndCtrlFAST= 7;
|
||||
const int k_IncLocalBrakeLevel= 8;
|
||||
const int k_IncLocalBrakeLevelFAST= 9;
|
||||
const int k_DecLocalBrakeLevel=10 ;
|
||||
const int k_DecLocalBrakeLevelFAST= 11;
|
||||
const int k_IncBrakeLevel= 12;
|
||||
const int k_DecBrakeLevel= 13;
|
||||
const int k_Releaser= 14;
|
||||
const int k_EmergencyBrake= 15;
|
||||
const int k_Brake3= 16;
|
||||
const int k_Brake2= 17;
|
||||
const int k_Brake1= 18;
|
||||
const int k_Brake0= 19;
|
||||
const int k_WaveBrake= 20;
|
||||
const int k_AntiSlipping= 21;
|
||||
const int k_Sand= 22;
|
||||
|
||||
const int k_Main= 23;
|
||||
const int k_DirectionForward= 24;
|
||||
const int k_DirectionBackward= 25;
|
||||
|
||||
const int k_Fuse= 26;
|
||||
const int k_Compressor= 27;
|
||||
const int k_Converter= 28;
|
||||
const int k_MaxCurrent= 29;
|
||||
const int k_CurrentAutoRelay= 30;
|
||||
const int k_BrakeProfile= 31;
|
||||
|
||||
const int k_Czuwak= 32;
|
||||
const int k_Horn= 33;
|
||||
const int k_Horn2= 34;
|
||||
|
||||
const int k_FailedEngineCutOff= 35;
|
||||
|
||||
const int k_MechUp= 36;
|
||||
const int k_MechDown= 37;
|
||||
const int k_MechLeft= 38;
|
||||
const int k_MechRight= 39;
|
||||
const int k_MechForward= 40;
|
||||
const int k_MechBackward= 41;
|
||||
|
||||
const int k_CabForward= 42;
|
||||
const int k_CabBackward= 43;
|
||||
|
||||
const int k_Couple= 44;
|
||||
const int k_DeCouple= 45;
|
||||
|
||||
const int k_ProgramQuit= 46;
|
||||
//const int k_ProgramPause= 47;
|
||||
const int k_ProgramHelp= 48;
|
||||
//NBMX
|
||||
const int k_OpenLeft= 49;
|
||||
const int k_OpenRight= 50;
|
||||
const int k_CloseLeft= 51;
|
||||
const int k_CloseRight= 52;
|
||||
const int k_DepartureSignal= 53;
|
||||
//NBMX
|
||||
const int k_PantFrontUp= 54;
|
||||
const int k_PantRearUp= 55;
|
||||
const int k_PantFrontDown= 56;
|
||||
const int k_PantRearDown= 57;
|
||||
|
||||
const int k_Heating= 58;
|
||||
|
||||
//const int k_FreeFlyMode= 59;
|
||||
|
||||
const int k_LeftSign = 60;
|
||||
const int k_UpperSign= 61;
|
||||
const int k_RightSign= 62;
|
||||
|
||||
const int k_SmallCompressor= 63;
|
||||
|
||||
const int k_StLinOff= 64;
|
||||
|
||||
const int k_CurrentNext=65;
|
||||
|
||||
const int k_Univ1=66;
|
||||
const int k_Univ2=67;
|
||||
const int k_Univ3=68;
|
||||
const int k_Univ4=69;
|
||||
const int k_EndSign=70;
|
||||
|
||||
const int k_Active=71;
|
||||
//Winger 020304
|
||||
const int k_Battery=72;
|
||||
const int k_WalkMode=73;
|
||||
const int MaxKeys= 74;
|
||||
|
||||
//klasy dla wskaŸników globalnych
|
||||
class TGround;
|
||||
class TWorld;
|
||||
class TCamera;
|
||||
class TDynamicObject;
|
||||
class TAnimModel; //obiekt terenu
|
||||
namespace Queryparsercomp
|
||||
{
|
||||
class TQueryParserComp; //stary(?) parser
|
||||
}
|
||||
class cParser; //nowy (powolny!) parser
|
||||
class TEvent;
|
||||
class TTextSound;
|
||||
|
||||
class TTranscript
|
||||
{//klasa obs³uguj¹ca linijkê napisu do dŸwiêku
|
||||
public:
|
||||
float fShow; //czas pokazania
|
||||
float fHide; //czas ukrycia/usuniêcia
|
||||
AnsiString asText; //tekst gotowy do wyœwietlenia (usuniête znaczniki czasu)
|
||||
bool bItalic; //czy kursywa (dŸwiêk nieistotny dla prowadz¹cego)
|
||||
int iNext; //nastêpna u¿ywana linijka, ¿eby nie przestawiaæ fizycznie tabeli
|
||||
};
|
||||
|
||||
#define MAX_TRANSCRIPTS 30
|
||||
class TTranscripts
|
||||
{//klasa obs³uguj¹ca napisy do dŸwiêków
|
||||
TTranscript aLines[MAX_TRANSCRIPTS]; //pozycje na napisy do wyœwietlenia
|
||||
int iCount; //liczba zajêtych pozycji
|
||||
int iStart; //pierwsza istotna pozycja w tabeli, ¿eby sortowaæ przestawiaj¹c numerki
|
||||
float fRefreshTime;
|
||||
public:
|
||||
__fastcall TTranscripts();
|
||||
__fastcall ~TTranscripts();
|
||||
void __fastcall AddLine(char *txt,float show,float hide,bool it);
|
||||
void __fastcall Add(char *txt,float len,bool backgorund=false); //dodanie tekstów, d³ugoœæ dŸwiêku, czy istotne
|
||||
void __fastcall Update(); //usuwanie niepotrzebnych (ok. 10 razy na sekundê)
|
||||
};
|
||||
|
||||
class Global
|
||||
{
|
||||
private:
|
||||
static GLuint iTextureId; //ostatnio u¿yta tekstura 2D
|
||||
public:
|
||||
//double Global::tSinceStart;
|
||||
static int Keys[MaxKeys];
|
||||
static vector3 pCameraPosition; //pozycja kamery w œwiecie
|
||||
static double pCameraRotation; //kierunek bezwzglêdny kamery w œwiecie: 0=pó³noc, 90°=zachód (-azymut)
|
||||
static double pCameraRotationDeg; //w stopniach, dla animacji billboard
|
||||
static vector3 pFreeCameraInit[10]; //pozycje kamery
|
||||
static vector3 pFreeCameraInitAngle[10];
|
||||
static int iWindowWidth;
|
||||
static int iWindowHeight;
|
||||
static float fDistanceFactor;
|
||||
static int iBpp;
|
||||
static bool bFullScreen;
|
||||
static bool bFreeFly;
|
||||
//float RunningTime;
|
||||
static bool bWireFrame;
|
||||
static bool bSoundEnabled;
|
||||
//McZapkie-131202
|
||||
//static bool bRenderAlpha;
|
||||
static bool bAdjustScreenFreq;
|
||||
static bool bEnableTraction;
|
||||
static bool bLoadTraction;
|
||||
static float fFriction;
|
||||
static bool bLiveTraction;
|
||||
static bool bManageNodes;
|
||||
static bool bDecompressDDS;
|
||||
// bool WFreeFly;
|
||||
static float Global::fMouseXScale;
|
||||
static float Global::fMouseYScale;
|
||||
static double fFogStart;
|
||||
static double fFogEnd;
|
||||
static TGround *pGround;
|
||||
static char** szDefaultExt;
|
||||
static char szSceneryFile[256];
|
||||
static char CreatorName1[20];
|
||||
static char CreatorName2[20];
|
||||
static char CreatorName3[20];
|
||||
static char CreatorName4[30];
|
||||
static char CreatorName5[30];
|
||||
static AnsiString asCurrentSceneryPath;
|
||||
static AnsiString asCurrentTexturePath;
|
||||
static AnsiString asCurrentDynamicPath;
|
||||
//McZapkie-170602: zewnetrzna definicja pojazdu uzytkownika
|
||||
static AnsiString asHumanCtrlVehicle;
|
||||
static void __fastcall LoadIniFile(AnsiString asFileName);
|
||||
static void __fastcall InitKeys(AnsiString asFileName);
|
||||
inline static vector3 __fastcall GetCameraPosition()
|
||||
{return pCameraPosition;};
|
||||
static void __fastcall SetCameraPosition(vector3 pNewCameraPosition);
|
||||
static void __fastcall SetCameraRotation(double Yaw);
|
||||
static int iWriteLogEnabled; //maska bitowa: 1-zapis do pliku, 2-okienko
|
||||
//McZapkie-221002: definicja swiatla dziennego
|
||||
static GLfloat AtmoColor[];
|
||||
static GLfloat FogColor[];
|
||||
//static bool bTimeChange;
|
||||
static GLfloat ambientDayLight[];
|
||||
static GLfloat diffuseDayLight[];
|
||||
static GLfloat specularDayLight[];
|
||||
static GLfloat ambientLight[];
|
||||
static GLfloat diffuseLight[];
|
||||
static GLfloat specularLight[];
|
||||
static GLfloat whiteLight[];
|
||||
static GLfloat noLight[];
|
||||
static GLfloat darkLight[];
|
||||
static GLfloat lightPos[4];
|
||||
static int iSlowMotion;
|
||||
static TDynamicObject *changeDynObj;
|
||||
static double ABuDebug;
|
||||
static bool detonatoryOK;
|
||||
static AnsiString asSky;
|
||||
static bool bnewAirCouplers;
|
||||
//Ra: nowe zmienne globalne
|
||||
static int iDefaultFiltering; //domyœlne rozmywanie tekstur TGA
|
||||
static int iBallastFiltering; //domyœlne rozmywanie tekstury podsypki
|
||||
static int iRailProFiltering; //domyœlne rozmywanie tekstury szyn
|
||||
static int iDynamicFiltering; //domyœlne rozmywanie tekstur pojazdów
|
||||
static int iReCompile; //zwiêkszany, gdy trzeba odœwie¿yæ siatki
|
||||
static bool bUseVBO; //czy jest VBO w karcie graficznej
|
||||
static int iFeedbackMode; //tryb pracy informacji zwrotnej
|
||||
static int iFeedbackPort; //dodatkowy adres dla informacji zwrotnych
|
||||
static double fOpenGL; //wersja OpenGL - przyda siê
|
||||
static bool bOpenGL_1_5; //czy s¹ dostêpne funkcje OpenGL 1.5
|
||||
static double fLuminance; //jasnoœæ œwiat³a do automatycznego zapalania
|
||||
static int iMultiplayer; //blokada dzia³ania niektórych eventów na rzecz kominikacji
|
||||
static HWND hWnd; //uchwyt okna
|
||||
static int iCameraLast;
|
||||
static AnsiString asRelease; //numer
|
||||
static AnsiString asVersion; //z opisem
|
||||
static int iViewMode; //co aktualnie widaæ: 0-kabina, 1-latanie, 2-sprzêgi, 3-dokumenty, 4-obwody
|
||||
static GLint iMaxTextureSize; //maksymalny rozmiar tekstury
|
||||
static int iTextMode; //tryb pracy wyœwietlacza tekstowego
|
||||
static int iScreenMode[12]; //numer ekranu wyœwietlacza tekstowego
|
||||
static bool bDoubleAmbient; //podwójna jasnoœæ ambient
|
||||
static double fMoveLight; //numer dnia w roku albo -1
|
||||
static bool bSmoothTraction; //wyg³adzanie drutów
|
||||
static double fSunDeclination; //deklinacja S³oñca
|
||||
static double fTimeSpeed; //przyspieszenie czasu, zmienna do testów
|
||||
static double fTimeAngleDeg; //godzina w postaci k¹ta
|
||||
static float fClockAngleDeg[6]; //k¹ty obrotu cylindrów dla zegara cyfrowego
|
||||
static double fLatitudeDeg; //szerokoϾ geograficzna
|
||||
static char* szTexturesTGA[4]; //lista tekstur od TGA
|
||||
static char* szTexturesDDS[4]; //lista tekstur od DDS
|
||||
static int iMultisampling; //tryb antyaliasingu: 0=brak,1=2px,2=4px,3=8px,4=16px
|
||||
static bool bGlutFont; //tekst generowany przez GLUT
|
||||
static int iKeyLast; //ostatnio naciœniêty klawisz w celu logowania
|
||||
static int iPause; //globalna pauza ruchu: b0=start,b1=klawisz,b2=t³o,b3=lagi,b4=wczytywanie
|
||||
static bool bActive; //czy jest aktywnym oknem
|
||||
static void __fastcall BindTexture(GLuint t);
|
||||
static int iConvertModels; //tworzenie plików binarnych
|
||||
static int iErorrCounter; //licznik sprawdzañ do œledzenia b³êdów OpenGL
|
||||
static bool bInactivePause; //automatyczna pauza, gdy okno nieaktywne
|
||||
static int iTextures; //licznik u¿ytych tekstur
|
||||
static int iSlowMotionMask; //maska wy³¹czanych w³aœciwoœci
|
||||
static int iModifyTGA; //czy korygowaæ pliki TGA dla szybszego wczytywania
|
||||
static bool bHideConsole; //hunter-271211: ukrywanie konsoli
|
||||
static TWorld *pWorld; //wskaŸnik na œwiat do usuwania pojazdów
|
||||
static TAnimModel *pTerrainCompact; //obiekt terenu do ewentualnego zapisania w pliku
|
||||
static AnsiString asTerrainModel; //nazwa obiektu terenu do zapisania w pliku
|
||||
static bool bRollFix; //czy wykonaæ przeliczanie przechy³ki
|
||||
static Queryparsercomp::TQueryParserComp *qParser;
|
||||
static cParser *pParser;
|
||||
static int iSegmentsRendered; //iloœæ segmentów do regulacji wydajnoœci
|
||||
static double fFpsAverage; //oczekiwana wartosæ FPS
|
||||
static double fFpsDeviation; //odchylenie standardowe FPS
|
||||
static double fFpsMin; //dolna granica FPS, przy której promieñ scenerii bêdzie zmniejszany
|
||||
static double fFpsMax; //górna granica FPS, przy której promieñ scenerii bêdzie zwiêkszany
|
||||
static double fFpsRadiusMax; //maksymalny promieñ renderowania
|
||||
static int iFpsRadiusMax; //maksymalny promieñ renderowania w rozmiarze tabeli sektorów
|
||||
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 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
|
||||
static AnsiString asTranscript[5]; //napisy na ekranie (widoczne)
|
||||
static TTranscripts tranTexts; //obiekt obs³uguj¹cy stenogramy dŸwiêków na ekranie
|
||||
static AnsiString asLang; //domyœlny jêzyk - http://tools.ietf.org/html/bcp47
|
||||
static int iHiddenEvents; //czy ³¹czyæ eventy z torami poprzez nazwê toru
|
||||
static TTextSound *tsRadioBusy[10]; //zajêtoœæ kana³ów radiowych (wskaŸnik na odgrywany dŸwiêk)
|
||||
//metody
|
||||
static void __fastcall TrainDelete(TDynamicObject *d);
|
||||
static void __fastcall ConfigParse(Queryparsercomp::TQueryParserComp *qp,cParser *cp=NULL);
|
||||
static AnsiString __fastcall GetNextSymbol();
|
||||
static TDynamicObject* __fastcall DynamicNearest();
|
||||
static TDynamicObject* __fastcall CouplerNearest();
|
||||
static bool __fastcall AddToQuery(TEvent *event,TDynamicObject *who);
|
||||
static bool __fastcall DoEvents();
|
||||
static AnsiString __fastcall Bezogonkow(AnsiString str, bool _=false);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
4511
Ground.cpp
Normal file
4511
Ground.cpp
Normal file
File diff suppressed because it is too large
Load Diff
367
Ground.h
Normal file
367
Ground.h
Normal file
@@ -0,0 +1,367 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef groundH
|
||||
#define groundH
|
||||
|
||||
#include "dumb3d.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "VBO.h"
|
||||
#include "Classes.h"
|
||||
|
||||
using namespace Math3D;
|
||||
|
||||
//Ra: zmniejszone liczby, aby zrobić tabelkę i zoptymalizować wyszukiwanie
|
||||
const int TP_MODEL=10;
|
||||
const int TP_MESH=11; //Ra: specjalny obiekt grupojący siatki dla tekstury
|
||||
const int TP_DUMMYTRACK=12; //Ra: zdublowanie obiektu toru dla rozdzielenia tekstur
|
||||
const int TP_TERRAIN=13; //Ra: specjalny model dla terenu
|
||||
const int TP_DYNAMIC=14;
|
||||
const int TP_SOUND=15;
|
||||
const int TP_TRACK=16;
|
||||
//const int TP_GEOMETRY=17;
|
||||
const int TP_MEMCELL=18;
|
||||
const int TP_EVLAUNCH=19; //MC
|
||||
const int TP_TRACTION=20;
|
||||
const int TP_TRACTIONPOWERSOURCE=21; //MC
|
||||
//const int TP_ISOLATED=22; //Ra
|
||||
const int TP_SUBMODEL=22; //Ra: submodele terenu
|
||||
const int TP_LAST=25; //rozmiar tablicy
|
||||
|
||||
struct DaneRozkaz
|
||||
{//struktura komunikacji z EU07.EXE
|
||||
int iSygn; //sygnatura 'EU07'
|
||||
int iComm; //rozkaz/status (kod ramki)
|
||||
union
|
||||
{float fPar[62];
|
||||
int iPar[62];
|
||||
char cString[248]; //upakowane stringi
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef int TGroundNodeType;
|
||||
|
||||
struct TGroundVertex
|
||||
{
|
||||
vector3 Point;
|
||||
vector3 Normal;
|
||||
float tu,tv;
|
||||
void HalfSet(const TGroundVertex &v1,const TGroundVertex &v2)
|
||||
{//wyliczenie współrzędnych i mapowania punktu na środku odcinka v1<->v2
|
||||
Point=0.5*(v1.Point+v2.Point);
|
||||
Normal=0.5*(v1.Normal+v2.Normal);
|
||||
tu=0.5*(v1.tu+v2.tu);
|
||||
tv=0.5*(v1.tv+v2.tv);
|
||||
}
|
||||
void SetByX(const TGroundVertex &v1,const TGroundVertex &v2,double x)
|
||||
{//wyliczenie współrzędnych i mapowania punktu na odcinku v1<->v2
|
||||
double i=(x-v1.Point.x)/(v2.Point.x-v1.Point.x); //parametr równania
|
||||
double j=1.0-i;
|
||||
Point=j*v1.Point+i*v2.Point;
|
||||
Normal=j*v1.Normal+i*v2.Normal;
|
||||
tu=j*v1.tu+i*v2.tu;
|
||||
tv=j*v1.tv+i*v2.tv;
|
||||
}
|
||||
void SetByZ(const TGroundVertex &v1,const TGroundVertex &v2,double z)
|
||||
{//wyliczenie współrzędnych i mapowania punktu na odcinku v1<->v2
|
||||
double i=(z-v1.Point.z)/(v2.Point.z-v1.Point.z); //parametr równania
|
||||
double j=1.0-i;
|
||||
Point=j*v1.Point+i*v2.Point;
|
||||
Normal=j*v1.Normal+i*v2.Normal;
|
||||
tu=j*v1.tu+i*v2.tu;
|
||||
tv=j*v1.tv+i*v2.tv;
|
||||
}
|
||||
};
|
||||
|
||||
class TSubRect; //sektor (aktualnie 200m×200m, ale może być zmieniony)
|
||||
|
||||
class TGroundNode : public Resource
|
||||
{//obiekt scenerii
|
||||
private:
|
||||
public:
|
||||
TGroundNodeType iType; //typ obiektu
|
||||
union
|
||||
{//Ra: wskażniki zależne od typu - zrobić klasy dziedziczone zamiast
|
||||
void *Pointer; //do przypisywania NULL
|
||||
TSubModel *smTerrain; //modele terenu (kwadratow kilometrowych)
|
||||
TAnimModel *Model; //model z animacjami
|
||||
TDynamicObject *DynamicObject; //pojazd
|
||||
vector3 *Points; //punkty dla linii
|
||||
TTrack *pTrack; //trajektoria ruchu
|
||||
TGroundVertex *Vertices; //wierzchołki dla trójkątów
|
||||
TMemCell *MemCell; //komórka pamięci
|
||||
TEventLauncher *EvLaunch; //wyzwalacz zdarzeń
|
||||
TTraction *hvTraction; //drut zasilający
|
||||
TTractionPowerSource *psTractionPowerSource; //zasilanie drutu (zaniedbane w sceneriach)
|
||||
TTextSound *tsStaticSound; //dźwięk przestrzenny
|
||||
TGroundNode *nNode; //obiekt renderujący grupowo ma tu wskaźnik na listę obiektów
|
||||
};
|
||||
AnsiString asName; //nazwa (nie zawsze ma znaczenie)
|
||||
union
|
||||
{
|
||||
int iNumVerts; //dla trójkątów
|
||||
int iNumPts; //dla linii
|
||||
int iCount; //dla terenu
|
||||
//int iState; //Ra: nie używane - dźwięki zapętlone
|
||||
};
|
||||
vector3 pCenter; //współrzędne środka do przydzielenia sektora
|
||||
|
||||
union
|
||||
{
|
||||
//double fAngle; //kąt obrotu dla modelu
|
||||
double fLineThickness; //McZapkie-120702: grubosc linii
|
||||
//int Status; //McZapkie-170303: status dzwieku
|
||||
};
|
||||
double fSquareRadius; //kwadrat widoczności do
|
||||
double fSquareMinRadius; //kwadrat widoczności od
|
||||
//TGroundNode *nMeshGroup; //Ra: obiekt grupujący trójkąty w TSubRect dla tekstury
|
||||
int iVersion; //wersja siatki (do wykonania rekompilacji)
|
||||
//union ?
|
||||
GLuint DisplayListID; //numer siatki DisplayLists
|
||||
bool PROBLEND;
|
||||
int iVboPtr; //indeks w buforze VBO
|
||||
GLuint TextureID; //główna (jedna) tekstura obiektu
|
||||
int iFlags; //tryb przezroczystości: 0x10-nieprz.,0x20-przezroczysty,0x30-mieszany
|
||||
int Ambient[4],Diffuse[4],Specular[4]; //oświetlenie
|
||||
bool bVisible;
|
||||
TGroundNode *nNext; //lista wszystkich w scenerii, ostatni na początku
|
||||
TGroundNode *nNext2; //lista obiektów w sektorze
|
||||
TGroundNode *nNext3; //lista obiektów renderowanych we wspólnym cyklu
|
||||
__fastcall TGroundNode();
|
||||
__fastcall TGroundNode(TGroundNodeType t,int n=0);
|
||||
__fastcall ~TGroundNode();
|
||||
void __fastcall Init(int n);
|
||||
void __fastcall InitCenter(); //obliczenie współrzędnych środka
|
||||
void __fastcall InitNormals();
|
||||
|
||||
void __fastcall MoveMe(vector3 pPosition); //przesuwanie (nie działa)
|
||||
|
||||
//bool __fastcall Disable();
|
||||
inline TGroundNode* __fastcall Find(const AnsiString &asNameToFind,TGroundNodeType iNodeType)
|
||||
{//wyszukiwanie czołgowe z typem
|
||||
if ((iNodeType==iType)&&(asNameToFind==asName))
|
||||
return this;
|
||||
else
|
||||
if (nNext) return nNext->Find(asNameToFind,iNodeType);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
void __fastcall Compile(bool many=false);
|
||||
void Release();
|
||||
bool __fastcall GetTraction();
|
||||
|
||||
void __fastcall RenderHidden(); //obsługa dźwięków i wyzwalaczy zdarzeń
|
||||
void __fastcall RenderDL(); //renderowanie nieprzezroczystych w Display Lists
|
||||
void __fastcall RenderAlphaDL(); //renderowanie przezroczystych w Display Lists (McZapkie-131202)
|
||||
void __fastcall RaRenderVBO(); //renderowanie (nieprzezroczystych) ze wspólnego VBO
|
||||
void __fastcall RenderVBO(); //renderowanie nieprzezroczystych z własnego VBO
|
||||
void __fastcall RenderAlphaVBO(); //renderowanie przezroczystych z (własnego) VBO
|
||||
};
|
||||
|
||||
class TSubRect : public Resource, public CMesh
|
||||
{//sektor składowy kwadratu kilometrowego
|
||||
public:
|
||||
int iTracks; //ilość torów w (tTracks)
|
||||
TTrack **tTracks; //tory do renderowania pojazdów
|
||||
protected:
|
||||
TTrack *tTrackAnim; //obiekty do przeliczenia animacji
|
||||
TGroundNode *nRootMesh; //obiekty renderujące wg tekstury (wtórne, lista po nNext2)
|
||||
TGroundNode *nMeshed; //lista obiektów dla których istnieją obiekty renderujące grupowo
|
||||
public:
|
||||
TGroundNode *nRootNode; //wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2)
|
||||
TGroundNode *nRenderHidden; //lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3)
|
||||
TGroundNode *nRenderRect; //z poziomu sektora - nieprzezroczyste (nNext3)
|
||||
TGroundNode *nRenderRectAlpha; //z poziomu sektora - przezroczyste (nNext3)
|
||||
TGroundNode *nRenderWires; //z poziomu sektora - druty i inne linie (nNext3)
|
||||
TGroundNode *nRender; //indywidualnie - nieprzezroczyste (nNext3)
|
||||
TGroundNode *nRenderMixed; //indywidualnie - nieprzezroczyste i przezroczyste (nNext3)
|
||||
TGroundNode *nRenderAlpha; //indywidualnie - przezroczyste (nNext3)
|
||||
int iNodeCount; //licznik obiektów, do pomijania pustych sektorów
|
||||
public:
|
||||
void __fastcall LoadNodes(); //utworzenie VBO sektora
|
||||
public:
|
||||
__fastcall TSubRect();
|
||||
virtual __fastcall ~TSubRect();
|
||||
virtual void Release(); //zwalnianie VBO sektora
|
||||
void __fastcall NodeAdd(TGroundNode *Node); //dodanie obiektu do sektora na etapie rozdzielania na sektory
|
||||
void __fastcall RaNodeAdd(TGroundNode *Node); //dodanie obiektu do listy renderowania
|
||||
void __fastcall 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);
|
||||
bool __fastcall StartVBO(); //ustwienie VBO sektora dla (nRenderRect), (nRenderRectAlpha) i (nRenderWires)
|
||||
bool __fastcall RaTrackAnimAdd(TTrack *t); //zgłoszenie toru do animacji
|
||||
void __fastcall RaAnimate(); //przeliczenie animacji torów
|
||||
void __fastcall RenderDL(); //renderowanie nieprzezroczystych w Display Lists
|
||||
void __fastcall RenderAlphaDL(); //renderowanie przezroczystych w Display Lists (McZapkie-131202)
|
||||
void __fastcall RenderVBO(); //renderowanie nieprzezroczystych z własnego VBO
|
||||
void __fastcall RenderAlphaVBO(); //renderowanie przezroczystych z (własnego) VBO
|
||||
void __fastcall RenderSounds(); //dźwięki pojazdów z niewidocznych sektorów
|
||||
};
|
||||
|
||||
//Ra: trzeba sprawdzić wydajność siatki
|
||||
const int iNumSubRects=5; //na ile dzielimy kilometr
|
||||
const int iNumRects=500;
|
||||
//const double fHalfNumRects=iNumRects/2.0; //połowa do wyznaczenia środka
|
||||
const int iTotalNumSubRects=iNumRects*iNumSubRects;
|
||||
const double fHalfTotalNumSubRects=iTotalNumSubRects/2.0;
|
||||
const double fSubRectSize=1000.0/iNumSubRects;
|
||||
const double fRectSize=fSubRectSize*iNumSubRects;
|
||||
|
||||
class TGroundRect : public TSubRect
|
||||
{//kwadrat kilometrowy
|
||||
//obiekty o niewielkiej ilości wierzchołków będą renderowane stąd
|
||||
//Ra: 2012-02 doszły submodele terenu
|
||||
private:
|
||||
int iLastDisplay; //numer klatki w której był ostatnio wyświetlany
|
||||
TSubRect *pSubRects;
|
||||
void __fastcall Init() { pSubRects=new TSubRect[iNumSubRects*iNumSubRects]; };
|
||||
public:
|
||||
static int iFrameNumber; //numer kolejny wyświetlanej klatki
|
||||
TGroundNode *nTerrain; //model terenu z E3D - użyć nRootMesh?
|
||||
__fastcall TGroundRect();
|
||||
virtual __fastcall ~TGroundRect();
|
||||
|
||||
TSubRect* __fastcall 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)
|
||||
{//pobranie wskaźnika do małego kwadratu, bez tworzenia jeśli nie ma
|
||||
return (pSubRects?pSubRects+iRow*iNumSubRects+iCol:NULL);
|
||||
};
|
||||
void __fastcall Optimize()
|
||||
{//optymalizacja obiektów w sektorach
|
||||
if (pSubRects)
|
||||
for (int i=iNumSubRects*iNumSubRects-1;i>=0;--i)
|
||||
pSubRects[i].Sort(); //optymalizacja obiektów w sektorach
|
||||
};
|
||||
void __fastcall RenderDL();
|
||||
void __fastcall RenderVBO();
|
||||
};
|
||||
|
||||
|
||||
class TGround
|
||||
{
|
||||
vector3 CameraDirection; //zmienna robocza przy renderowaniu
|
||||
int const *iRange; //tabela widoczności
|
||||
//TGroundNode *nRootNode; //lista wszystkich węzłów
|
||||
TGroundNode *nRootDynamic; //lista pojazdów
|
||||
TGroundRect Rects[iNumRects][iNumRects]; //mapa kwadratów kilometrowych
|
||||
TEvent *RootEvent; //lista zdarzeń
|
||||
TEvent *QueryRootEvent,*tmpEvent,*tmp2Event,*OldQRE;
|
||||
TSubRect *pRendered[1500]; //lista renderowanych sektorów
|
||||
int iNumNodes;
|
||||
vector3 pOrigin;
|
||||
vector3 aRotate;
|
||||
bool bInitDone;
|
||||
TGroundNode *nRootOfType[TP_LAST]; //tablica grupująca obiekty, przyspiesza szukanie
|
||||
//TGroundNode *nLastOfType[TP_LAST]; //ostatnia
|
||||
TSubRect srGlobal; //zawiera obiekty globalne (na razie wyzwalacze czasowe)
|
||||
int hh,mm,srh,srm,ssh,ssm; //ustawienia czasu
|
||||
//int tracks,tracksfar; //liczniki torów
|
||||
TNames *sTracks; //posortowane nazwy torów i eventów
|
||||
private: //metody prywatne
|
||||
bool __fastcall EventConditon(TEvent *e);
|
||||
public:
|
||||
bool bDynamicRemove; //czy uruchomić procedurę usuwania pojazdów
|
||||
TDynamicObject *LastDyn; //ABu: paskudnie, ale na bardzo szybko moze jakos przejdzie...
|
||||
//TTrain *pTrain;
|
||||
//double fVDozwolona;
|
||||
//bool bTrabil;
|
||||
|
||||
__fastcall TGround();
|
||||
__fastcall ~TGround();
|
||||
void __fastcall Free();
|
||||
bool __fastcall Init(AnsiString asFile,HDC hDC);
|
||||
void __fastcall FirstInit();
|
||||
void __fastcall InitTracks();
|
||||
void __fastcall InitTraction();
|
||||
bool __fastcall InitEvents();
|
||||
bool __fastcall 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);
|
||||
//TGroundNode* __fastcall CreateGroundNode();
|
||||
TGroundNode* __fastcall AddGroundNode(cParser* parser);
|
||||
bool __fastcall AddGroundNode(double x,double z,TGroundNode *Node)
|
||||
{
|
||||
TSubRect *tmp=GetSubRect(x,z);
|
||||
if (tmp)
|
||||
{
|
||||
tmp->NodeAdd(Node);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
};
|
||||
// bool __fastcall Include(TQueryParserComp *Parser);
|
||||
//TGroundNode* __fastcall GetVisible(AnsiString asName);
|
||||
TGroundNode* __fastcall GetNode(AnsiString asName);
|
||||
bool __fastcall AddDynamic(TGroundNode *Node);
|
||||
void __fastcall MoveGroundNode(vector3 pPosition);
|
||||
void __fastcall UpdatePhys(double dt,int iter); //aktualizacja fizyki stałym krokiem
|
||||
bool __fastcall Update(double dt,int iter); //aktualizacja przesunięć zgodna z FPS
|
||||
bool __fastcall AddToQuery(TEvent *Event, TDynamicObject *Node);
|
||||
bool __fastcall GetTraction(TDynamicObject *model);
|
||||
bool __fastcall RenderDL(vector3 pPosition);
|
||||
bool __fastcall RenderAlphaDL(vector3 pPosition);
|
||||
bool __fastcall RenderVBO(vector3 pPosition);
|
||||
bool __fastcall RenderAlphaVBO(vector3 pPosition);
|
||||
bool __fastcall CheckQuery();
|
||||
// __fastcall GetRect(double x, double z) { return &(Rects[int(x/fSubRectSize+fHalfNumRects)][int(z/fSubRectSize+fHalfNumRects)]); };
|
||||
/*
|
||||
int __fastcall GetRowFromZ(double z) { return (z/fRectSize+fHalfNumRects); };
|
||||
int __fastcall GetColFromX(double x) { return (x/fRectSize+fHalfNumRects); };
|
||||
int __fastcall GetSubRowFromZ(double z) { return (z/fSubRectSize+fHalfNumSubRects); };
|
||||
int __fastcall GetSubColFromX(double x) { return (x/fSubRectSize+fHalfNumSubRects); };
|
||||
*/
|
||||
/*
|
||||
inline TGroundNode* __fastcall FindGroundNode(const AnsiString &asNameToFind )
|
||||
{
|
||||
if (RootNode)
|
||||
return (RootNode->Find( asNameToFind ));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
TGroundNode* __fastcall DynamicFindAny(AnsiString asNameToFind);
|
||||
TGroundNode* __fastcall DynamicFind(AnsiString asNameToFind);
|
||||
void __fastcall DynamicList(bool all=false);
|
||||
TGroundNode* __fastcall FindGroundNode(AnsiString asNameToFind,TGroundNodeType iNodeType);
|
||||
TGroundRect* __fastcall GetRect(double x, double z) { return &Rects[GetColFromX(x)/iNumSubRects][GetRowFromZ(z)/iNumSubRects]; };
|
||||
TSubRect* __fastcall GetSubRect(double x, double z) { return GetSubRect(GetColFromX(x),GetRowFromZ(z)); };
|
||||
TSubRect* __fastcall 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);
|
||||
int __fastcall GetRowFromZ(double z) { return (z/fSubRectSize+fHalfTotalNumSubRects); };
|
||||
int __fastcall GetColFromX(double x) { return (x/fSubRectSize+fHalfTotalNumSubRects); };
|
||||
TEvent* __fastcall FindEvent(const AnsiString &asEventName);
|
||||
TEvent* __fastcall FindEventScan(const AnsiString &asEventName);
|
||||
void __fastcall TrackJoin(TGroundNode *Current);
|
||||
private:
|
||||
void __fastcall OpenGLUpdate(HDC hDC);
|
||||
void __fastcall RaTriangleDivider(TGroundNode* node);
|
||||
void __fastcall Navigate(String ClassName,UINT Msg,WPARAM wParam,LPARAM lParam);
|
||||
bool PROBLEND;
|
||||
public:
|
||||
void __fastcall WyslijEvent(const AnsiString &e,const AnsiString &d);
|
||||
int iRendered; //ilość renderowanych sektorów, pobierana przy pokazywniu FPS
|
||||
void __fastcall WyslijString(const AnsiString &t,int n);
|
||||
void __fastcall WyslijWolny(const AnsiString &t);
|
||||
void __fastcall WyslijNamiary(TGroundNode* t);
|
||||
void __fastcall WyslijParam(int nr,int fl);
|
||||
void __fastcall RadioStop(vector3 pPosition);
|
||||
TDynamicObject* __fastcall DynamicNearest(vector3 pPosition,double distance=20.0,bool mech=false);
|
||||
TDynamicObject* __fastcall CouplerNearest(vector3 pPosition,double distance=20.0,bool mech=false);
|
||||
void __fastcall DynamicRemove(TDynamicObject* dyn);
|
||||
void __fastcall TerrainRead(const AnsiString &f);
|
||||
void __fastcall TerrainWrite();
|
||||
void __fastcall TrackBusyList();
|
||||
void __fastcall IsolatedBusyList();
|
||||
void __fastcall IsolatedBusy(const AnsiString t);
|
||||
void __fastcall Silence(vector3 gdzie);
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
94
Logs.cpp
Normal file
94
Logs.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Logs.h"
|
||||
#include "Globals.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
std::ofstream output; //standardowy "log.txt", mo¿na go wy³¹czyæ
|
||||
std::ofstream errors; //lista b³êdów "errors.txt", zawsze dzia³a
|
||||
|
||||
char endstring[10]="\n";
|
||||
|
||||
void __fastcall WriteConsoleOnly(const char* str, double value)
|
||||
{
|
||||
char buf[255];
|
||||
sprintf(buf,"%s %f \n",str,value);
|
||||
//stdout= GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD wr= 0;
|
||||
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),buf,strlen(buf),&wr,NULL);
|
||||
//WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),endstring,strlen(endstring),&wr,NULL);
|
||||
}
|
||||
|
||||
void __fastcall WriteConsoleOnly(const char* str)
|
||||
{
|
||||
//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);
|
||||
}
|
||||
|
||||
void __fastcall WriteLog(const char* str, double value)
|
||||
{
|
||||
if (Global::iWriteLogEnabled)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
char buf[255];
|
||||
sprintf(buf,"%s %f",str,value);
|
||||
WriteLog(buf);
|
||||
}
|
||||
}
|
||||
};
|
||||
void __fastcall WriteLog(const char* str)
|
||||
{
|
||||
if (str)
|
||||
{
|
||||
if (Global::iWriteLogEnabled&1)
|
||||
{if (!output.is_open())
|
||||
output.open("log.txt",std::ios::trunc);
|
||||
output << str << "\n";
|
||||
output.flush();
|
||||
}
|
||||
//hunter-271211: pisanie do konsoli tylko, gdy nie jest ukrywana
|
||||
if (Global::iWriteLogEnabled&2)
|
||||
WriteConsoleOnly(str);
|
||||
}
|
||||
};
|
||||
void __fastcall ErrorLog(const char* str)
|
||||
{//Ra: bezwarunkowa rejestracja powa¿nych b³êdów
|
||||
if (!errors.is_open())
|
||||
{errors.open("errors.txt",std::ios::trunc);
|
||||
errors << AnsiString("EU07.EXE "+Global::asRelease).c_str() << "\n";
|
||||
}
|
||||
if (str) errors << str;
|
||||
errors << "\n";
|
||||
errors.flush();
|
||||
};
|
||||
|
||||
void __fastcall Error(const AnsiString &asMessage,bool box)
|
||||
{
|
||||
if (box)
|
||||
MessageBox(NULL,asMessage.c_str(),AnsiString("EU07 "+Global::asRelease).c_str(),MB_OK);
|
||||
WriteLog(asMessage.c_str());
|
||||
}
|
||||
void __fastcall ErrorLog(const AnsiString &asMessage)
|
||||
{//zapisywanie b³êdów "errors.txt"
|
||||
ErrorLog(asMessage.c_str());
|
||||
WriteLog(asMessage.c_str()); //do "log.txt" ewentualnie te¿
|
||||
}
|
||||
|
||||
void __fastcall WriteLog(const AnsiString &str)
|
||||
{//Ra: wersja z AnsiString jest zamienna z Error()
|
||||
WriteLog(str.c_str());
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
15
Logs.h
Normal file
15
Logs.h
Normal file
@@ -0,0 +1,15 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef LogsH
|
||||
#define LogsH
|
||||
#include <system.hpp>
|
||||
|
||||
void __fastcall WriteConsoleOnly(const char *str, double value);
|
||||
void __fastcall WriteConsoleOnly(const char *str);
|
||||
void __fastcall WriteLog(const char *str, double value);
|
||||
void __fastcall WriteLog(const char *str);
|
||||
void __fastcall Error(const AnsiString &asMessage,bool box=true);
|
||||
void __fastcall ErrorLog(const AnsiString &asMessage);
|
||||
void __fastcall WriteLog(const AnsiString &str);
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
94
Machajka.cpp
Normal file
94
Machajka.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
|
||||
#include "Machajka.h"
|
||||
#include "Timer.h"
|
||||
#include "Globals.h"
|
||||
|
||||
__fastcall TMachajka::TMachajka():TTrain()
|
||||
{
|
||||
TTrain::TTrain();
|
||||
}
|
||||
|
||||
__fastcall TMachajka::~TMachajka()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool __fastcall TMachajka::Init(TDynamicObject *NewDynamicObject)
|
||||
{
|
||||
TTrain::Init(NewDynamicObject);
|
||||
return true;
|
||||
}
|
||||
|
||||
void __fastcall TMachajka::OnKeyPress(int cKey)
|
||||
{
|
||||
if (!GetAsyncKeyState(VK_SHIFT)<0) //bez shifta
|
||||
{
|
||||
if (cKey==Global::Keys[k_IncMainCtrl])
|
||||
(DynamicObject->MoverParameters->AddPulseForce(1));
|
||||
else
|
||||
if (cKey==Global::Keys[k_DecMainCtrl])
|
||||
(DynamicObject->MoverParameters->AddPulseForce(-1));
|
||||
else
|
||||
if (cKey==Global::Keys[k_IncLocalBrakeLevel])
|
||||
(DynamicObject->MoverParameters->IncLocalBrakeLevel(1));
|
||||
else
|
||||
if (cKey==Global::Keys[k_DecLocalBrakeLevel])
|
||||
(DynamicObject->MoverParameters->DecLocalBrakeLevel(1));
|
||||
else
|
||||
if (cKey==Global::Keys[k_MechLeft])
|
||||
vMechMovement.x+=fMechCroach;
|
||||
else
|
||||
if (cKey==Global::Keys[k_MechRight])
|
||||
vMechMovement.x-=fMechCroach;
|
||||
else
|
||||
if (cKey==Global::Keys[k_MechBackward])
|
||||
vMechMovement.z-=fMechCroach;
|
||||
else
|
||||
if (cKey==Global::Keys[k_MechForward])
|
||||
vMechMovement.z+=fMechCroach;
|
||||
else
|
||||
if (cKey==Global::Keys[k_MechUp])
|
||||
pMechOffset.y+=0.3; //McZapkie-120302 - wstawanie
|
||||
else
|
||||
if (cKey==Global::Keys[k_MechDown])
|
||||
pMechOffset.y-=0.3; //McZapkie-120302 - siadanie, kucanie itp
|
||||
}
|
||||
else //z shiftem
|
||||
{
|
||||
if (cKey==Global::Keys[k_IncMainCtrlFAST])
|
||||
(DynamicObject->MoverParameters->AddPulseForce(2));
|
||||
else
|
||||
if (cKey==Global::Keys[k_DecMainCtrlFAST])
|
||||
(DynamicObject->MoverParameters->AddPulseForce(-2));
|
||||
else
|
||||
if (cKey==Global::Keys[k_IncLocalBrakeLevelFAST])
|
||||
(DynamicObject->MoverParameters->IncLocalBrakeLevel(2));
|
||||
else
|
||||
if (cKey==Global::Keys[k_DecLocalBrakeLevelFAST])
|
||||
(DynamicObject->MoverParameters->DecLocalBrakeLevel(2));
|
||||
}
|
||||
}
|
||||
|
||||
bool __fastcall TMachajka::Update(double dt)
|
||||
{
|
||||
TTrain::Update(dt);
|
||||
}
|
||||
|
||||
bool __fastcall TMachajka::UpdateMechPosition()
|
||||
{
|
||||
TTrain::UpdateMechPosition();
|
||||
}
|
||||
|
||||
bool __fastcall TMachajka::Render()
|
||||
{
|
||||
TTrain::Render();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
30
Machajka.h
Normal file
30
Machajka.h
Normal file
@@ -0,0 +1,30 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef MachajkaH
|
||||
#define MachajkaH
|
||||
|
||||
#include "Train.h"
|
||||
|
||||
class TMachajka:public TTrain
|
||||
{
|
||||
public:
|
||||
TSubModel *wajcha;
|
||||
// double v;
|
||||
// double m;
|
||||
// double a;
|
||||
// double f;
|
||||
// bool enter;
|
||||
// bool space;
|
||||
// double wa,wv;
|
||||
__fastcall TMachajka();
|
||||
virtual __fastcall ~TMachajka();
|
||||
virtual bool __fastcall Init(TDynamicObject *NewDynamicObject);
|
||||
virtual void __fastcall OnKeyPress(int cKey);
|
||||
virtual bool __fastcall Update(double dt);
|
||||
virtual bool __fastcall UpdateMechPosition();
|
||||
virtual bool __fastcall Render();
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
882
McZapkie/Mover.hpp
Normal file
882
McZapkie/Mover.hpp
Normal file
@@ -0,0 +1,882 @@
|
||||
// Borland C++ Builder
|
||||
// Copyright (c) 1995, 1999 by Borland International
|
||||
// All rights reserved
|
||||
|
||||
// (DO NOT EDIT: machine generated header) '_mover.pas' rev: 5.00
|
||||
//Ra: eee... tam, sam siê generuje b³êdnie i trzeba rêcznie poprawiaæ!
|
||||
|
||||
#ifndef _moverHPP
|
||||
#define _moverHPP
|
||||
|
||||
#pragma delphiheader begin
|
||||
#pragma option push -w-
|
||||
#pragma option push -Vx
|
||||
#include <Oerlikon_ESt.hpp> // Pascal unit
|
||||
#include <hamulce.hpp> // Pascal unit
|
||||
#include <SysUtils.hpp> // Pascal unit
|
||||
#include <mctools.hpp> // Pascal unit
|
||||
#include <SysInit.hpp> // Pascal unit
|
||||
#include <System.hpp> // Pascal unit
|
||||
|
||||
//-- user supplied -----------------------------------------------------------
|
||||
|
||||
namespace _mover
|
||||
{
|
||||
//-- type declarations -------------------------------------------------------
|
||||
struct TLocation
|
||||
{
|
||||
double X;
|
||||
double Y;
|
||||
double Z;
|
||||
} ;
|
||||
|
||||
struct TRotation
|
||||
{
|
||||
double Rx;
|
||||
double Ry;
|
||||
double Rz;
|
||||
} ;
|
||||
|
||||
struct TDimension
|
||||
{
|
||||
double W;
|
||||
double L;
|
||||
double H;
|
||||
} ;
|
||||
|
||||
struct TCommand
|
||||
{
|
||||
AnsiString Command;
|
||||
double Value1;
|
||||
double Value2;
|
||||
TLocation Location;
|
||||
} ;
|
||||
|
||||
struct TTrackShape
|
||||
{
|
||||
double R;
|
||||
double Len;
|
||||
double dHtrack;
|
||||
double dHrail;
|
||||
} ;
|
||||
|
||||
struct TTrackParam
|
||||
{
|
||||
double Width;
|
||||
double friction;
|
||||
Byte CategoryFlag;
|
||||
Byte QualityFlag;
|
||||
Byte DamageFlag;
|
||||
double Velmax;
|
||||
} ;
|
||||
|
||||
struct TTractionParam
|
||||
{
|
||||
double TractionVoltage;
|
||||
double TractionFreq;
|
||||
double TractionMaxCurrent;
|
||||
double TractionResistivity;
|
||||
} ;
|
||||
|
||||
#pragma option push -b-
|
||||
enum TBrakeSystem { Individual, Pneumatic, ElectroPneumatic };
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum TBrakeSubSystem { ss_None, ss_W, ss_K, ss_KK, ss_Hik, ss_ESt, ss_KE, ss_LSt, ss_MT, ss_Dako };
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum 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
|
||||
};
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum TBrakeHandle { NoHandle, West, FV4a, M394, M254, FVel1, FVel6, D2, Knorr, FD1, BS2, testH, St113
|
||||
};
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum TLocalBrake { NoBrake, ManualBrake, PneumaticBrake, HydraulicBrake };
|
||||
#pragma option pop
|
||||
|
||||
typedef double TBrakeDelayTable[4];
|
||||
|
||||
struct TBrakePressure
|
||||
{
|
||||
double PipePressureVal;
|
||||
double BrakePressureVal;
|
||||
double FlowSpeedVal;
|
||||
TBrakeSystem BrakeType;
|
||||
} ;
|
||||
|
||||
typedef TBrakePressure TBrakePressureTable[13];
|
||||
|
||||
#pragma option push -b-
|
||||
enum TEngineTypes { None, Dumb, WheelsDriven, ElectricSeriesMotor, ElectricInductionMotor, DieselEngine,
|
||||
SteamEngine, DieselElectric };
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum TPowerType { NoPower, BioPower, MechPower, ElectricPower, SteamPower };
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum TFuelType { Undefined, Coal, Oil };
|
||||
#pragma option pop
|
||||
|
||||
struct TGrateType
|
||||
{
|
||||
TFuelType FuelType;
|
||||
double GrateSurface;
|
||||
double FuelTransportSpeed;
|
||||
double IgnitionTemperature;
|
||||
double MaxTemperature;
|
||||
} ;
|
||||
|
||||
struct TBoilerType
|
||||
{
|
||||
double BoilerVolume;
|
||||
double BoilerHeatSurface;
|
||||
double SuperHeaterSurface;
|
||||
double MaxWaterVolume;
|
||||
double MinWaterVolume;
|
||||
double MaxPressure;
|
||||
} ;
|
||||
|
||||
struct TCurrentCollector
|
||||
{
|
||||
int CollectorsNo;
|
||||
double MinH;
|
||||
double MaxH;
|
||||
double CSW;
|
||||
double MinV;
|
||||
double MaxV;
|
||||
double InsetV;
|
||||
double MinPress;
|
||||
double MaxPress;
|
||||
} ;
|
||||
|
||||
#pragma option push -b-
|
||||
enum TPowerSource { NotDefined, InternalSource, Transducer, Generator, Accumulator, CurrentCollector,
|
||||
PowerCable, Heater };
|
||||
#pragma option pop
|
||||
|
||||
struct _mover__1
|
||||
{
|
||||
double MaxCapacity;
|
||||
TPowerSource RechargeSource;
|
||||
} ;
|
||||
|
||||
struct _mover__2
|
||||
{
|
||||
TPowerType PowerTrans;
|
||||
double SteamPressure;
|
||||
} ;
|
||||
|
||||
struct _mover__3
|
||||
{
|
||||
TGrateType Grate;
|
||||
TBoilerType Boiler;
|
||||
} ;
|
||||
|
||||
struct TPowerParameters
|
||||
{
|
||||
double MaxVoltage;
|
||||
double MaxCurrent;
|
||||
double IntR;
|
||||
TPowerSource SourceType;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
_mover__3 RHeater;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
_mover__2 RPowerCable;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
TCurrentCollector CollectorParameters;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
_mover__1 RAccumulator;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
TEngineTypes GeneratorEngine;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
double InputVoltage;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
TPowerType PowerType;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
} ;
|
||||
|
||||
struct TScheme
|
||||
{
|
||||
Byte Relay;
|
||||
double R;
|
||||
Byte Bn;
|
||||
Byte Mn;
|
||||
bool AutoSwitch;
|
||||
Byte ScndAct;
|
||||
} ;
|
||||
|
||||
typedef TScheme TSchemeTable[65];
|
||||
|
||||
struct TDEScheme
|
||||
{
|
||||
double RPM;
|
||||
double GenPower;
|
||||
double Umax;
|
||||
double Imax;
|
||||
} ;
|
||||
|
||||
typedef TDEScheme TDESchemeTable[33];
|
||||
|
||||
struct TShuntScheme
|
||||
{
|
||||
double Umin;
|
||||
double Umax;
|
||||
double Pmin;
|
||||
double Pmax;
|
||||
} ;
|
||||
|
||||
typedef TShuntScheme TShuntSchemeTable[33];
|
||||
|
||||
struct TMPTRelay
|
||||
{
|
||||
double Iup;
|
||||
double Idown;
|
||||
} ;
|
||||
|
||||
typedef TMPTRelay TMPTRelayTable[8];
|
||||
|
||||
struct TMotorParameters
|
||||
{
|
||||
double mfi;
|
||||
double mIsat;
|
||||
double mfi0;
|
||||
double fi;
|
||||
double Isat;
|
||||
double fi0;
|
||||
bool AutoSwitch;
|
||||
} ;
|
||||
|
||||
struct TSecuritySystem
|
||||
{
|
||||
Byte SystemType;
|
||||
double AwareDelay;
|
||||
double AwareMinSpeed;
|
||||
double SoundSignalDelay;
|
||||
double EmergencyBrakeDelay;
|
||||
Byte Status;
|
||||
double SystemTimer;
|
||||
double SystemSoundCATimer;
|
||||
double SystemSoundSHPTimer;
|
||||
double SystemBrakeCATimer;
|
||||
double SystemBrakeSHPTimer;
|
||||
double SystemBrakeCATestTimer;
|
||||
int VelocityAllowed;
|
||||
int NextVelocityAllowed;
|
||||
bool RadioStop;
|
||||
} ;
|
||||
|
||||
struct TTransmision
|
||||
{
|
||||
Byte NToothM;
|
||||
Byte NToothW;
|
||||
double Ratio;
|
||||
} ;
|
||||
|
||||
#pragma option push -b-
|
||||
enum TCouplerType { NoCoupler, Articulated, Bare, Chain, Screw, Automatic };
|
||||
#pragma option pop
|
||||
|
||||
class DELPHICLASS T_MoverParameters;
|
||||
struct TCoupling
|
||||
{
|
||||
double SpringKB;
|
||||
double SpringKC;
|
||||
double beta;
|
||||
double DmaxB;
|
||||
double FmaxB;
|
||||
double DmaxC;
|
||||
double FmaxC;
|
||||
TCouplerType CouplerType;
|
||||
Byte CouplingFlag;
|
||||
int AllowedFlag;
|
||||
bool Render;
|
||||
double CoupleDist;
|
||||
T_MoverParameters* Connected;
|
||||
Byte ConnectedNr;
|
||||
double CForce;
|
||||
double Dist;
|
||||
bool CheckCollision;
|
||||
} ;
|
||||
|
||||
class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject
|
||||
{
|
||||
typedef System::TObject inherited;
|
||||
|
||||
public:
|
||||
double dMoveLen;
|
||||
AnsiString filename;
|
||||
Byte CategoryFlag;
|
||||
AnsiString TypeName;
|
||||
int TrainType;
|
||||
TEngineTypes EngineType;
|
||||
TPowerParameters EnginePowerSource;
|
||||
TPowerParameters SystemPowerSource;
|
||||
TPowerParameters HeatingPowerSource;
|
||||
TPowerParameters AlterHeatPowerSource;
|
||||
TPowerParameters LightPowerSource;
|
||||
TPowerParameters AlterLightPowerSource;
|
||||
double Vmax;
|
||||
double Mass;
|
||||
double Power;
|
||||
double Mred;
|
||||
double TotalMass;
|
||||
double HeatingPower;
|
||||
double LightPower;
|
||||
double BatteryVoltage;
|
||||
bool Battery;
|
||||
bool EpFuse;
|
||||
bool Signalling;
|
||||
bool DoorSignalling;
|
||||
bool Radio;
|
||||
double NominalBatteryVoltage;
|
||||
TDimension Dim;
|
||||
double Cx;
|
||||
double Floor;
|
||||
double WheelDiameter;
|
||||
double WheelDiameterL;
|
||||
double WheelDiameterT;
|
||||
double TrackW;
|
||||
double AxleInertialMoment;
|
||||
AnsiString AxleArangement;
|
||||
Byte NPoweredAxles;
|
||||
Byte NAxles;
|
||||
Byte BearingType;
|
||||
double ADist;
|
||||
double BDist;
|
||||
Byte NBpA;
|
||||
int SandCapacity;
|
||||
TBrakeSystem BrakeSystem;
|
||||
TBrakeSubSystem BrakeSubsystem;
|
||||
TBrakeValve BrakeValve;
|
||||
TBrakeHandle BrakeHandle;
|
||||
TBrakeHandle BrakeLocHandle;
|
||||
double MBPM;
|
||||
Hamulce::TBrake* Hamulec;
|
||||
Hamulce::THandle* Handle;
|
||||
Hamulce::THandle* LocHandle;
|
||||
Hamulce::TReservoir* Pipe;
|
||||
Hamulce::TReservoir* Pipe2;
|
||||
TLocalBrake LocalBrake;
|
||||
TBrakePressure BrakePressureTable[13];
|
||||
TBrakePressure BrakePressureActual;
|
||||
Byte ASBType;
|
||||
Byte TurboTest;
|
||||
double MaxBrakeForce;
|
||||
double MaxBrakePress[5];
|
||||
double P2FTrans;
|
||||
double TrackBrakeForce;
|
||||
Byte BrakeMethod;
|
||||
double HighPipePress;
|
||||
double LowPipePress;
|
||||
double DeltaPipePress;
|
||||
double CntrlPipePress;
|
||||
double BrakeVolume;
|
||||
double BrakeVVolume;
|
||||
double VeselVolume;
|
||||
int BrakeCylNo;
|
||||
double BrakeCylRadius;
|
||||
double BrakeCylDist;
|
||||
double BrakeCylMult[3];
|
||||
Byte LoadFlag;
|
||||
double BrakeCylSpring;
|
||||
double BrakeSlckAdj;
|
||||
double BrakeRigEff;
|
||||
double RapidMult;
|
||||
int BrakeValveSize;
|
||||
AnsiString BrakeValveParams;
|
||||
double Spg;
|
||||
double MinCompressor;
|
||||
double MaxCompressor;
|
||||
double CompressorSpeed;
|
||||
double BrakeDelay[4];
|
||||
Byte BrakeCtrlPosNo;
|
||||
Byte MainCtrlPosNo;
|
||||
Byte ScndCtrlPosNo;
|
||||
bool ScndInMain;
|
||||
bool MBrake;
|
||||
TSecuritySystem SecuritySystem;
|
||||
TScheme RList[65];
|
||||
int RlistSize;
|
||||
TMotorParameters MotorParam[11];
|
||||
TTransmision Transmision;
|
||||
double NominalVoltage;
|
||||
double WindingRes;
|
||||
double u;
|
||||
double CircuitRes;
|
||||
int IminLo;
|
||||
int IminHi;
|
||||
int ImaxLo;
|
||||
int ImaxHi;
|
||||
double nmax;
|
||||
double InitialCtrlDelay;
|
||||
double CtrlDelay;
|
||||
double CtrlDownDelay;
|
||||
Byte FastSerialCircuit;
|
||||
Byte AutoRelayType;
|
||||
bool CoupledCtrl;
|
||||
bool IsCoupled;
|
||||
Byte DynamicBrakeType;
|
||||
Byte RVentType;
|
||||
double RVentnmax;
|
||||
double RVentCutOff;
|
||||
int CompressorPower;
|
||||
int SmallCompressorPower;
|
||||
double dizel_Mmax;
|
||||
double dizel_nMmax;
|
||||
double dizel_Mnmax;
|
||||
double dizel_nmax;
|
||||
double dizel_nominalfill;
|
||||
double dizel_Mstand;
|
||||
double dizel_nmax_cutoff;
|
||||
double dizel_nmin;
|
||||
double dizel_minVelfullengage;
|
||||
double dizel_AIM;
|
||||
double dizel_engageDia;
|
||||
double dizel_engageMaxForce;
|
||||
double dizel_engagefriction;
|
||||
double AnPos;
|
||||
bool AnalogCtrl;
|
||||
bool AnMainCtrl;
|
||||
bool ShuntModeAllow;
|
||||
bool ShuntMode;
|
||||
bool Flat;
|
||||
double Vhyp;
|
||||
TDEScheme DElist[33];
|
||||
double Vadd;
|
||||
TMPTRelay MPTRelay[8];
|
||||
Byte RelayType;
|
||||
TShuntScheme SST[33];
|
||||
double PowerCorRatio;
|
||||
double Ftmax;
|
||||
double eimc[21];
|
||||
int MaxLoad;
|
||||
AnsiString LoadAccepted;
|
||||
AnsiString LoadQuantity;
|
||||
double OverLoadFactor;
|
||||
double LoadSpeed;
|
||||
double UnLoadSpeed;
|
||||
Byte DoorOpenCtrl;
|
||||
Byte DoorCloseCtrl;
|
||||
double DoorStayOpen;
|
||||
bool DoorClosureWarning;
|
||||
double DoorOpenSpeed;
|
||||
double DoorCloseSpeed;
|
||||
double DoorMaxShiftL;
|
||||
double DoorMaxShiftR;
|
||||
Byte DoorOpenMethod;
|
||||
bool ScndS;
|
||||
TLocation Loc;
|
||||
TRotation Rot;
|
||||
AnsiString Name;
|
||||
TCoupling Couplers[2];
|
||||
double HVCouplers[2][2];
|
||||
int ScanCounter;
|
||||
bool EventFlag;
|
||||
Byte SoundFlag;
|
||||
double DistCounter;
|
||||
double V;
|
||||
double Vel;
|
||||
double AccS;
|
||||
double AccN;
|
||||
double AccV;
|
||||
double nrot;
|
||||
double EnginePower;
|
||||
double dL;
|
||||
double Fb;
|
||||
double Ff;
|
||||
double FTrain;
|
||||
double FStand;
|
||||
double FTotal;
|
||||
double UnitBrakeForce;
|
||||
double Ntotal;
|
||||
bool SlippingWheels;
|
||||
bool SandDose;
|
||||
double Sand;
|
||||
double BrakeSlippingTimer;
|
||||
double dpBrake;
|
||||
double dpPipe;
|
||||
double dpMainValve;
|
||||
double dpLocalValve;
|
||||
double ScndPipePress;
|
||||
double BrakePress;
|
||||
double LocBrakePress;
|
||||
double PipeBrakePress;
|
||||
double PipePress;
|
||||
double EqvtPipePress;
|
||||
double Volume;
|
||||
double CompressedVolume;
|
||||
double PantVolume;
|
||||
double Compressor;
|
||||
bool CompressorFlag;
|
||||
bool PantCompFlag;
|
||||
bool CompressorAllow;
|
||||
bool ConverterFlag;
|
||||
bool ConverterAllow;
|
||||
int BrakeCtrlPos;
|
||||
double BrakeCtrlPosR;
|
||||
double BrakeCtrlPos2;
|
||||
Byte LocalBrakePos;
|
||||
Byte ManualBrakePos;
|
||||
double LocalBrakePosA;
|
||||
Byte BrakeStatus;
|
||||
bool EmergencyBrakeFlag;
|
||||
Byte BrakeDelayFlag;
|
||||
Byte BrakeDelays;
|
||||
bool DynamicBrakeFlag;
|
||||
double LimPipePress;
|
||||
double ActFlowSpeed;
|
||||
Byte DamageFlag;
|
||||
Byte DerailReason;
|
||||
TCommand CommandIn;
|
||||
AnsiString CommandOut;
|
||||
AnsiString CommandLast;
|
||||
double ValueOut;
|
||||
TTrackShape RunningShape;
|
||||
TTrackParam RunningTrack;
|
||||
double OffsetTrackH;
|
||||
double OffsetTrackV;
|
||||
bool Mains;
|
||||
Byte MainCtrlPos;
|
||||
Byte ScndCtrlPos;
|
||||
int ActiveDir;
|
||||
int CabNo;
|
||||
int DirAbsolute;
|
||||
int ActiveCab;
|
||||
double LastSwitchingTime;
|
||||
bool DepartureSignal;
|
||||
bool InsideConsist;
|
||||
TTractionParam RunningTraction;
|
||||
double enrot;
|
||||
double Im;
|
||||
double Itot;
|
||||
double IHeating;
|
||||
double ITraction;
|
||||
double TotalCurrent;
|
||||
double Mm;
|
||||
double Mw;
|
||||
double Fw;
|
||||
double Ft;
|
||||
int Imin;
|
||||
int Imax;
|
||||
double Voltage;
|
||||
Byte MainCtrlActualPos;
|
||||
Byte ScndCtrlActualPos;
|
||||
bool DelayCtrlFlag;
|
||||
double LastRelayTime;
|
||||
bool AutoRelayFlag;
|
||||
bool FuseFlag;
|
||||
bool ConvOvldFlag;
|
||||
bool StLinFlag;
|
||||
bool ResistorsFlag;
|
||||
double RventRot;
|
||||
bool UnBrake;
|
||||
double PantPress;
|
||||
bool s_CAtestebrake;
|
||||
double dizel_fill;
|
||||
double dizel_engagestate;
|
||||
double dizel_engage;
|
||||
double dizel_automaticgearstatus;
|
||||
bool dizel_enginestart;
|
||||
double dizel_engagedeltaomega;
|
||||
double eimv[21];
|
||||
double PulseForce;
|
||||
double PulseForceTimer;
|
||||
int PulseForceCount;
|
||||
double eAngle;
|
||||
int Load;
|
||||
AnsiString LoadType;
|
||||
Byte LoadStatus;
|
||||
double LastLoadChangeTime;
|
||||
bool DoorBlocked;
|
||||
bool DoorLeftOpened;
|
||||
bool DoorRightOpened;
|
||||
bool PantFrontUp;
|
||||
bool PantRearUp;
|
||||
bool PantFrontSP;
|
||||
bool PantRearSP;
|
||||
int PantFrontStart;
|
||||
int PantRearStart;
|
||||
double PantFrontVolt;
|
||||
double PantRearVolt;
|
||||
AnsiString PantSwitchType;
|
||||
AnsiString ConvSwitchType;
|
||||
bool Heating;
|
||||
int DoubleTr;
|
||||
bool PhysicActivation;
|
||||
double FrictConst1;
|
||||
double FrictConst2s;
|
||||
double FrictConst2d;
|
||||
double TotalMassxg;
|
||||
double __fastcall GetTrainsetVoltage(void);
|
||||
bool __fastcall Physic_ReActivation(void);
|
||||
double __fastcall LocalBrakeRatio(void);
|
||||
double __fastcall ManualBrakeRatio(void);
|
||||
double __fastcall PipeRatio(void);
|
||||
double __fastcall RealPipeRatio(void);
|
||||
double __fastcall BrakeVP(void);
|
||||
bool __fastcall DynamicBrakeSwitch(bool Switch);
|
||||
bool __fastcall SendCtrlBroadcast(AnsiString CtrlCommand, double ctrlvalue);
|
||||
bool __fastcall SendCtrlToNext(AnsiString CtrlCommand, double ctrlvalue, double dir);
|
||||
bool __fastcall CabActivisation(void);
|
||||
bool __fastcall CabDeactivisation(void);
|
||||
bool __fastcall IncMainCtrl(int CtrlSpeed);
|
||||
bool __fastcall DecMainCtrl(int CtrlSpeed);
|
||||
bool __fastcall IncScndCtrl(int CtrlSpeed);
|
||||
bool __fastcall DecScndCtrl(int CtrlSpeed);
|
||||
bool __fastcall AddPulseForce(int Multipler);
|
||||
bool __fastcall SandDoseOn(void);
|
||||
bool __fastcall SecuritySystemReset(void);
|
||||
void __fastcall SecuritySystemCheck(double dt);
|
||||
bool __fastcall BatterySwitch(bool State);
|
||||
bool __fastcall EpFuseSwitch(bool State);
|
||||
bool __fastcall IncBrakeLevelOld(void);
|
||||
bool __fastcall DecBrakeLevelOld(void);
|
||||
bool __fastcall IncLocalBrakeLevel(Byte CtrlSpeed);
|
||||
bool __fastcall DecLocalBrakeLevel(Byte CtrlSpeed);
|
||||
bool __fastcall IncLocalBrakeLevelFAST(void);
|
||||
bool __fastcall DecLocalBrakeLevelFAST(void);
|
||||
bool __fastcall IncManualBrakeLevel(Byte CtrlSpeed);
|
||||
bool __fastcall DecManualBrakeLevel(Byte CtrlSpeed);
|
||||
bool __fastcall EmergencyBrakeSwitch(bool Switch);
|
||||
bool __fastcall AntiSlippingBrake(void);
|
||||
bool __fastcall BrakeReleaser(Byte state);
|
||||
bool __fastcall SwitchEPBrake(Byte state);
|
||||
bool __fastcall AntiSlippingButton(void);
|
||||
bool __fastcall IncBrakePress(double &brake, double PressLimit, double dp);
|
||||
bool __fastcall DecBrakePress(double &brake, double PressLimit, double dp);
|
||||
bool __fastcall BrakeDelaySwitch(Byte BDS);
|
||||
bool __fastcall IncBrakeMult(void);
|
||||
bool __fastcall DecBrakeMult(void);
|
||||
void __fastcall UpdateBrakePressure(double dt);
|
||||
void __fastcall UpdatePipePressure(double dt);
|
||||
void __fastcall CompressorCheck(double dt);
|
||||
//void __fastcall UpdatePantVolume(double dt);
|
||||
void __fastcall UpdateScndPipePressure(double dt);
|
||||
void __fastcall UpdateBatteryVoltage(double dt);
|
||||
double __fastcall GetDVc(double dt);
|
||||
void __fastcall ComputeConstans(void);
|
||||
double __fastcall ComputeMass(void);
|
||||
double __fastcall Adhesive(double staticfriction);
|
||||
double __fastcall TractionForce(double dt);
|
||||
double __fastcall FrictionForce(double R, Byte TDamage);
|
||||
double __fastcall BrakeForce(const TTrackParam &Track);
|
||||
double __fastcall CouplerForce(Byte CouplerN, double dt);
|
||||
void __fastcall CollisionDetect(Byte CouplerN, double dt);
|
||||
double __fastcall ComputeRotatingWheel(double WForce, double dt, double n);
|
||||
bool __fastcall SetInternalCommand(AnsiString NewCommand, double NewValue1, double NewValue2);
|
||||
double __fastcall GetExternalCommand(AnsiString &Command);
|
||||
bool __fastcall RunCommand(AnsiString command, double CValue1, double CValue2);
|
||||
bool __fastcall RunInternalCommand(void);
|
||||
void __fastcall PutCommand(AnsiString NewCommand, double NewValue1, double NewValue2, const TLocation
|
||||
&NewLocation);
|
||||
bool __fastcall DirectionBackward(void);
|
||||
bool __fastcall MainSwitch(bool State);
|
||||
bool __fastcall ConverterSwitch(bool State);
|
||||
bool __fastcall CompressorSwitch(bool State);
|
||||
bool __fastcall FuseOn(void);
|
||||
bool __fastcall FuseFlagCheck(void);
|
||||
void __fastcall FuseOff(void);
|
||||
int __fastcall ShowCurrent(Byte AmpN);
|
||||
double __fastcall v2n(void);
|
||||
double __fastcall current(double n, double U);
|
||||
double __fastcall Momentum(double I);
|
||||
double __fastcall MomentumF(double I, double Iw, Byte SCP);
|
||||
bool __fastcall CutOffEngine(void);
|
||||
bool __fastcall MaxCurrentSwitch(bool State);
|
||||
bool __fastcall ResistorsFlagCheck(void);
|
||||
bool __fastcall MinCurrentSwitch(bool State);
|
||||
bool __fastcall AutoRelaySwitch(bool State);
|
||||
bool __fastcall AutoRelayCheck(void);
|
||||
bool __fastcall dizel_EngageSwitch(double state);
|
||||
bool __fastcall dizel_EngageChange(double dt);
|
||||
bool __fastcall dizel_AutoGearCheck(void);
|
||||
double __fastcall dizel_fillcheck(Byte mcp);
|
||||
double __fastcall dizel_Momentum(double dizel_fill, double n, double dt);
|
||||
bool __fastcall dizel_Update(double dt);
|
||||
bool __fastcall LoadingDone(double LSpeed, AnsiString LoadInit);
|
||||
void __fastcall ComputeTotalForce(double dt, double dt1, bool FullVer);
|
||||
double __fastcall ComputeMovement(double dt, double dt1, const TTrackShape &Shape, TTrackParam &Track
|
||||
, TTractionParam &ElectricTraction, const TLocation &NewLoc, TRotation &NewRot);
|
||||
double __fastcall FastComputeMovement(double dt, const TTrackShape &Shape, TTrackParam &Track, const
|
||||
TLocation &NewLoc, TRotation &NewRot);
|
||||
bool __fastcall ChangeOffsetH(double DeltaOffset);
|
||||
__fastcall T_MoverParameters(double VelInitial, AnsiString TypeNameInit, AnsiString NameInit, int LoadInitial
|
||||
, AnsiString LoadTypeInitial, int Cab);
|
||||
bool __fastcall LoadChkFile(AnsiString chkpath);
|
||||
bool __fastcall CheckLocomotiveParameters(bool ReadyFlag, int Dir);
|
||||
AnsiString __fastcall EngineDescription(int what);
|
||||
bool __fastcall DoorLeft(bool State);
|
||||
bool __fastcall DoorRight(bool State);
|
||||
bool __fastcall DoorBlockedFlag(void);
|
||||
bool __fastcall PantFront(bool State);
|
||||
bool __fastcall PantRear(bool State);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall T_MoverParameters(void) : System::TObject() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~T_MoverParameters(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
//-- var, const, procedure ---------------------------------------------------
|
||||
static const bool Go = true;
|
||||
static const bool Hold = false;
|
||||
static const Shortint ResArraySize = 0x40;
|
||||
static const Shortint MotorParametersArraySize = 0xa;
|
||||
static const Shortint maxcc = 0x4;
|
||||
static const Shortint LocalBrakePosNo = 0xa;
|
||||
static const Shortint MainBrakeMaxPos = 0xa;
|
||||
static const Shortint ManualBrakePosNo = 0x14;
|
||||
static const Shortint dtrack_railwear = 0x2;
|
||||
static const Shortint dtrack_freerail = 0x4;
|
||||
static const Shortint dtrack_thinrail = 0x8;
|
||||
static const Shortint dtrack_railbend = 0x10;
|
||||
static const Shortint dtrack_plants = 0x20;
|
||||
static const Shortint dtrack_nomove = 0x40;
|
||||
static const Byte dtrack_norail = 0x80;
|
||||
static const Shortint dtrain_thinwheel = 0x1;
|
||||
static const Shortint dtrain_loadshift = 0x1;
|
||||
static const Shortint dtrain_wheelwear = 0x2;
|
||||
static const Shortint dtrain_bearing = 0x4;
|
||||
static const Shortint dtrain_coupling = 0x8;
|
||||
static const Shortint dtrain_ventilator = 0x10;
|
||||
static const Shortint dtrain_loaddamage = 0x10;
|
||||
static const Shortint dtrain_engine = 0x20;
|
||||
static const Shortint dtrain_loaddestroyed = 0x20;
|
||||
static const Shortint dtrain_axle = 0x40;
|
||||
static const Byte dtrain_out = 0x80;
|
||||
#define p_elengproblem (1.000000E-02)
|
||||
#define p_elengdamage (1.000000E-01)
|
||||
#define p_coupldmg (2.000000E-02)
|
||||
#define p_derail (1.000000E-03)
|
||||
#define p_accn (1.000000E-01)
|
||||
#define p_slippdmg (1.000000E-03)
|
||||
static const Shortint ctrain_virtual = 0x0;
|
||||
static const Shortint ctrain_coupler = 0x1;
|
||||
static const Shortint ctrain_pneumatic = 0x2;
|
||||
static const Shortint ctrain_controll = 0x4;
|
||||
static const Shortint ctrain_power = 0x8;
|
||||
static const Shortint ctrain_passenger = 0x10;
|
||||
static const Shortint ctrain_scndpneumatic = 0x20;
|
||||
static const Shortint ctrain_heating = 0x40;
|
||||
static const Byte ctrain_depot = 0x80;
|
||||
static const Shortint dbrake_none = 0x0;
|
||||
static const Shortint dbrake_passive = 0x1;
|
||||
static const Shortint dbrake_switch = 0x2;
|
||||
static const Shortint dbrake_reversal = 0x4;
|
||||
static const Shortint dbrake_automatic = 0x8;
|
||||
static const Shortint s_waiting = 0x1;
|
||||
static const Shortint s_aware = 0x2;
|
||||
static const Shortint s_active = 0x4;
|
||||
static const Shortint s_CAalarm = 0x8;
|
||||
static const Shortint s_SHPalarm = 0x10;
|
||||
static const Shortint s_CAebrake = 0x20;
|
||||
static const Shortint s_SHPebrake = 0x40;
|
||||
static const Byte s_CAtest = 0x80;
|
||||
static const Shortint sound_none = 0x0;
|
||||
static const Shortint sound_loud = 0x1;
|
||||
static const Shortint sound_couplerstretch = 0x2;
|
||||
static const Shortint sound_bufferclamp = 0x4;
|
||||
static const Shortint sound_bufferbump = 0x8;
|
||||
static const Shortint sound_relay = 0x10;
|
||||
static const Shortint sound_manyrelay = 0x20;
|
||||
static const Shortint sound_brakeacc = 0x40;
|
||||
extern PACKAGE bool PhysicActivationFlag;
|
||||
static const Shortint dt_Default = 0x0;
|
||||
static const Shortint dt_EZT = 0x1;
|
||||
static const Shortint dt_ET41 = 0x2;
|
||||
static const Shortint dt_ET42 = 0x4;
|
||||
static const Shortint dt_PseudoDiesel = 0x8;
|
||||
static const Shortint dt_ET22 = 0x10;
|
||||
static const Shortint dt_SN61 = 0x20;
|
||||
static const Shortint dt_EP05 = 0x40;
|
||||
static const Byte dt_ET40 = 0x80;
|
||||
static const Word dt_181 = 0x100;
|
||||
static const Shortint eimc_s_dfic = 0x0;
|
||||
static const Shortint eimc_s_dfmax = 0x1;
|
||||
static const Shortint eimc_s_p = 0x2;
|
||||
static const Shortint eimc_s_cfu = 0x3;
|
||||
static const Shortint eimc_s_cim = 0x4;
|
||||
static const Shortint eimc_s_icif = 0x5;
|
||||
static const Shortint eimc_f_Uzmax = 0x7;
|
||||
static const Shortint eimc_f_uzh = 0x8;
|
||||
static const Shortint eimc_f_DU = 0x9;
|
||||
static const Shortint eimc_f_I0 = 0xa;
|
||||
static const Shortint eimc_f_cfu = 0xb;
|
||||
static const Shortint eimc_p_F0 = 0xd;
|
||||
static const Shortint eimc_p_a1 = 0xe;
|
||||
static const Shortint eimc_p_Pmax = 0xf;
|
||||
static const Shortint eimc_p_Fh = 0x10;
|
||||
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 eimv_FMAXMAX = 0x0;
|
||||
static const Shortint eimv_Fmax = 0x1;
|
||||
static const Shortint eimv_ks = 0x2;
|
||||
static const Shortint eimv_df = 0x3;
|
||||
static const Shortint eimv_fp = 0x4;
|
||||
static const Shortint eimv_U = 0x5;
|
||||
static const Shortint eimv_pole = 0x6;
|
||||
static const Shortint eimv_Ic = 0x7;
|
||||
static const Shortint eimv_If = 0x8;
|
||||
static const Shortint eimv_M = 0x9;
|
||||
static const Shortint eimv_Fr = 0xa;
|
||||
static const Shortint eimv_Ipoj = 0xb;
|
||||
static const Shortint eimv_Pm = 0xc;
|
||||
static const Shortint eimv_Pe = 0xd;
|
||||
static const Shortint eimv_eta = 0xe;
|
||||
static const Shortint eimv_fkr = 0xf;
|
||||
static const Shortint eimv_Uzsmax = 0x10;
|
||||
static const Shortint eimv_Pmax = 0x11;
|
||||
static const Shortint eimv_Fzad = 0x12;
|
||||
static const Shortint eimv_Imax = 0x13;
|
||||
extern PACKAGE double __fastcall Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension
|
||||
&Dim1, const TDimension &Dim2);
|
||||
|
||||
} /* namespace _mover */
|
||||
#if !defined(NO_IMPLICIT_NAMESPACE_USE)
|
||||
using namespace _mover;
|
||||
#endif
|
||||
#pragma option pop // -w-
|
||||
#pragma option pop // -Vx
|
||||
|
||||
#pragma delphiheader end.
|
||||
//-- end unit ----------------------------------------------------------------
|
||||
#endif // _mover
|
||||
293
McZapkie/Oerlikon_ESt.hpp
Normal file
293
McZapkie/Oerlikon_ESt.hpp
Normal file
@@ -0,0 +1,293 @@
|
||||
// Borland C++ Builder
|
||||
// Copyright (c) 1995, 1999 by Borland International
|
||||
// All rights reserved
|
||||
|
||||
// (DO NOT EDIT: machine generated header) 'Oerlikon_ESt.pas' rev: 5.00
|
||||
|
||||
#ifndef Oerlikon_EStHPP
|
||||
#define Oerlikon_EStHPP
|
||||
|
||||
#pragma delphiheader begin
|
||||
#pragma option push -w-
|
||||
#pragma option push -Vx
|
||||
#include <hamulce.hpp> // Pascal unit
|
||||
#include <friction.hpp> // Pascal unit
|
||||
#include <SysUtils.hpp> // Pascal unit
|
||||
#include <mctools.hpp> // Pascal unit
|
||||
#include <SysInit.hpp> // Pascal unit
|
||||
#include <System.hpp> // Pascal unit
|
||||
|
||||
//-- user supplied -----------------------------------------------------------
|
||||
|
||||
namespace Oerlikon_est
|
||||
{
|
||||
//-- type declarations -------------------------------------------------------
|
||||
class DELPHICLASS TPrzekladnik;
|
||||
class PASCALIMPLEMENTATION TPrzekladnik : public Hamulce::TReservoir
|
||||
{
|
||||
typedef Hamulce::TReservoir inherited;
|
||||
|
||||
public:
|
||||
Hamulce::TReservoir* *BrakeRes;
|
||||
Hamulce::TReservoir* *Next;
|
||||
virtual void __fastcall Update(double dt);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TReservoir.Create */ inline __fastcall TPrzekladnik(void) : Hamulce::TReservoir() { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TPrzekladnik(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TRura;
|
||||
class PASCALIMPLEMENTATION TRura : public TPrzekladnik
|
||||
{
|
||||
typedef TPrzekladnik inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall P(void);
|
||||
virtual void __fastcall Update(double dt);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TReservoir.Create */ inline __fastcall TRura(void) : TPrzekladnik() { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TRura(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TPrzeciwposlizg;
|
||||
class PASCALIMPLEMENTATION TPrzeciwposlizg : public TRura
|
||||
{
|
||||
typedef TRura inherited;
|
||||
|
||||
private:
|
||||
bool Poslizg;
|
||||
|
||||
public:
|
||||
void __fastcall SetPoslizg(bool flag);
|
||||
virtual void __fastcall Update(double dt);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TReservoir.Create */ inline __fastcall TPrzeciwposlizg(void) : TRura() { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TPrzeciwposlizg(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TRapid;
|
||||
class PASCALIMPLEMENTATION TRapid : public TPrzekladnik
|
||||
{
|
||||
typedef TPrzekladnik inherited;
|
||||
|
||||
private:
|
||||
bool RapidStatus;
|
||||
double RapidMult;
|
||||
double DN;
|
||||
double DL;
|
||||
|
||||
public:
|
||||
void __fastcall SetRapidParams(double mult, double size);
|
||||
void __fastcall SetRapidStatus(bool rs);
|
||||
virtual void __fastcall Update(double dt);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TReservoir.Create */ inline __fastcall TRapid(void) : TPrzekladnik() { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TRapid(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TPrzekCiagly;
|
||||
class PASCALIMPLEMENTATION TPrzekCiagly : public TPrzekladnik
|
||||
{
|
||||
typedef TPrzekladnik inherited;
|
||||
|
||||
private:
|
||||
double Mult;
|
||||
|
||||
public:
|
||||
void __fastcall SetMult(double m);
|
||||
virtual void __fastcall Update(double dt);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TReservoir.Create */ inline __fastcall TPrzekCiagly(void) : TPrzekladnik() { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TPrzekCiagly(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TPrzek_PZZ;
|
||||
class PASCALIMPLEMENTATION TPrzek_PZZ : public TPrzekladnik
|
||||
{
|
||||
typedef TPrzekladnik inherited;
|
||||
|
||||
private:
|
||||
double LBP;
|
||||
|
||||
public:
|
||||
void __fastcall SetLBP(double P);
|
||||
virtual void __fastcall Update(double dt);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TReservoir.Create */ inline __fastcall TPrzek_PZZ(void) : TPrzekladnik() { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TPrzek_PZZ(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TPrzekZalamany;
|
||||
class PASCALIMPLEMENTATION TPrzekZalamany : public TPrzekladnik
|
||||
{
|
||||
typedef TPrzekladnik inherited;
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TReservoir.Create */ inline __fastcall TPrzekZalamany(void) : TPrzekladnik() { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TPrzekZalamany(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TPrzekED;
|
||||
class PASCALIMPLEMENTATION TPrzekED : public TRura
|
||||
{
|
||||
typedef TRura inherited;
|
||||
|
||||
private:
|
||||
double MaxP;
|
||||
|
||||
public:
|
||||
void __fastcall SetP(double P);
|
||||
virtual void __fastcall Update(double dt);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TReservoir.Create */ inline __fastcall TPrzekED(void) : TRura() { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TPrzekED(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TNESt3;
|
||||
class PASCALIMPLEMENTATION TNESt3 : public Hamulce::TBrake
|
||||
{
|
||||
typedef Hamulce::TBrake inherited;
|
||||
|
||||
private:
|
||||
double Nozzles[11];
|
||||
Hamulce::TReservoir* CntrlRes;
|
||||
double BVM;
|
||||
bool Zamykajacy;
|
||||
bool Przys_blok;
|
||||
Hamulce::TReservoir* Miedzypoj;
|
||||
TPrzekladnik* Przekladniki[3];
|
||||
bool RapidStatus;
|
||||
bool RapidStaly;
|
||||
double LoadC;
|
||||
double TareM;
|
||||
double LoadM;
|
||||
double TareBP;
|
||||
double HBG300;
|
||||
double Podskok;
|
||||
bool autom;
|
||||
double LBP;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
void __fastcall EStParams(double i_crc);
|
||||
virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF);
|
||||
virtual double __fastcall GetCRP(void);
|
||||
void __fastcall CheckState(double BCP, double &dV1);
|
||||
void __fastcall CheckReleaser(double dt);
|
||||
double __fastcall CVs(double bp);
|
||||
double __fastcall BVs(double BCP);
|
||||
void __fastcall SetSize(int size, AnsiString params);
|
||||
void __fastcall PLC(double mass);
|
||||
void __fastcall SetLP(double TM, double LM, double TBP);
|
||||
virtual void __fastcall ForceEmptiness(void);
|
||||
void __fastcall SetLBP(double P);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TNESt3(double i_mbp, double i_bcr, double i_bcd, double i_brc
|
||||
, Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : Hamulce::TBrake(i_mbp, i_bcr, i_bcd
|
||||
, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TNESt3(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
//-- var, const, procedure ---------------------------------------------------
|
||||
static const Shortint dMAX = 0xa;
|
||||
static const Shortint dON = 0x0;
|
||||
static const Shortint dOO = 0x1;
|
||||
static const Shortint dTN = 0x2;
|
||||
static const Shortint dTO = 0x3;
|
||||
static const Shortint dP = 0x4;
|
||||
static const Shortint dSd = 0x5;
|
||||
static const Shortint dSm = 0x6;
|
||||
static const Shortint dPd = 0x7;
|
||||
static const Shortint dPm = 0x8;
|
||||
static const Shortint dPO = 0x9;
|
||||
static const Shortint dPT = 0xa;
|
||||
static const Shortint p_none = 0x0;
|
||||
static const Shortint p_rapid = 0x1;
|
||||
static const Shortint p_pp = 0x2;
|
||||
static const Shortint p_al2 = 0x3;
|
||||
static const Shortint p_ppz = 0x4;
|
||||
static const Shortint P_ed = 0x5;
|
||||
extern PACKAGE double __fastcall d2A(double d);
|
||||
|
||||
} /* namespace Oerlikon_est */
|
||||
#if !defined(NO_IMPLICIT_NAMESPACE_USE)
|
||||
using namespace Oerlikon_est;
|
||||
#endif
|
||||
#pragma option pop // -w-
|
||||
#pragma option pop // -Vx
|
||||
|
||||
#pragma delphiheader end.
|
||||
//-- end unit ----------------------------------------------------------------
|
||||
#endif // Oerlikon_ESt
|
||||
797
McZapkie/Oerlikon_ESt.pas
Normal file
797
McZapkie/Oerlikon_ESt.pas
Normal file
@@ -0,0 +1,797 @@
|
||||
unit Oerlikon_ESt; {fizyka hamulcow Oerlikon ESt dla symulatora}
|
||||
|
||||
(*
|
||||
MaSzyna EU07 - SPKS
|
||||
Brakes. Oerlikon ESt.
|
||||
Copyright (C) 2007-2014 Maciej Cierniak
|
||||
*)
|
||||
|
||||
|
||||
(*
|
||||
(C) youBy
|
||||
Co jest:
|
||||
- glowny przyrzad rozrzadczy
|
||||
- napelniacz zbiornika pomocniczego
|
||||
- napelniacz zbiornika sterujacego
|
||||
- zawor podskoku
|
||||
- nibyprzyspieszacz
|
||||
- tylko 16",14",12",10"
|
||||
- nieprzekladnik rura
|
||||
- przekladnik 1:1
|
||||
- przekladniki AL2
|
||||
- przeciwposlizgi
|
||||
- rapid REL2
|
||||
- HGB300
|
||||
- inne srednice
|
||||
Co brakuje:
|
||||
- dobry przyspieszacz
|
||||
- mozliwosc zasilania z wysokiego cisnienia ESt4
|
||||
- ep: EP1 i EP2
|
||||
- samoczynne ep
|
||||
- PZZ dla dodatkowego
|
||||
*)
|
||||
|
||||
interface
|
||||
|
||||
uses mctools,sysutils,friction,hamulce;//,klasy_ham;
|
||||
|
||||
CONST
|
||||
dMAX=10; //dysze
|
||||
dON = 0; //osobowy napelnianie (+ZP)
|
||||
dOO = 1; //osobowy oproznianie
|
||||
dTN = 2; //towarowy napelnianie (+ZP)
|
||||
dTO = 3; //towarowy oproznianie
|
||||
dP = 4; //zbiornik pomocniczy
|
||||
dSd = 5; //zbiornik sterujacy
|
||||
dSm = 6; //zbiornik sterujacy
|
||||
dPd = 7; //duzy przelot zamykajcego
|
||||
dPm = 8; //maly przelot zamykajacego
|
||||
dPO = 9; //zasilanie pomocniczego O
|
||||
dPT =10; //zasilanie pomocniczego T
|
||||
|
||||
//przekladniki
|
||||
p_none = 0;
|
||||
p_rapid = 1;
|
||||
p_pp = 2;
|
||||
p_al2 = 3;
|
||||
p_ppz = 4;
|
||||
P_ed = 5;
|
||||
|
||||
|
||||
|
||||
TYPE
|
||||
TPrzekladnik= class(TReservoir) //przekladnik (powtarzacz)
|
||||
private
|
||||
public
|
||||
BrakeRes: PReservoir;
|
||||
Next: PReservoir;
|
||||
procedure Update(dt:real); virtual;
|
||||
end;
|
||||
|
||||
TRura= class(TPrzekladnik) //nieprzekladnik, rura laczaca
|
||||
private
|
||||
public
|
||||
function P: real; override;
|
||||
procedure Update(dt:real); override;
|
||||
end;
|
||||
|
||||
TPrzeciwposlizg= class(TRura) //przy napelnianiu - rura, przy poslizgu - upust
|
||||
private
|
||||
Poslizg: boolean;
|
||||
public
|
||||
procedure SetPoslizg(flag: boolean);
|
||||
procedure Update(dt:real); override;
|
||||
end;
|
||||
|
||||
TRapid= class(TPrzekladnik) //przekladnik dwustopniowy
|
||||
private
|
||||
RapidStatus: boolean; //status rapidu
|
||||
RapidMult: real; //przelozenie (w dol)
|
||||
// Komora2: real;
|
||||
DN,DL: real; //srednice dysz napelniania i luzowania
|
||||
public
|
||||
procedure SetRapidParams(mult: real; size: real);
|
||||
procedure SetRapidStatus(rs: boolean);
|
||||
procedure Update(dt:real); override;
|
||||
end;
|
||||
|
||||
TPrzekCiagly= class(TPrzekladnik) //AL2
|
||||
private
|
||||
Mult: real;
|
||||
public
|
||||
procedure SetMult(m: real);
|
||||
procedure Update(dt:real); override;
|
||||
end;
|
||||
|
||||
TPrzek_PZZ= class(TPrzekladnik) //podwojny zawor zwrotny
|
||||
private
|
||||
LBP: real;
|
||||
public
|
||||
procedure SetLBP(P: real);
|
||||
procedure Update(dt:real); override;
|
||||
end;
|
||||
|
||||
TPrzekZalamany= class(TPrzekladnik) //Knicksventil
|
||||
private
|
||||
public
|
||||
end;
|
||||
|
||||
TPrzekED= class(TRura) //przy napelnianiu - rura, przy hamowaniu - upust
|
||||
private
|
||||
MaxP: real;
|
||||
public
|
||||
procedure SetP(P: real);
|
||||
procedure Update(dt:real); override;
|
||||
end;
|
||||
|
||||
TNESt3= class(TBrake)
|
||||
private
|
||||
Nozzles: array[0..dMAX] of real; //dysze
|
||||
CntrlRes: TReservoir; //zbiornik steruj¹cy
|
||||
BVM: real; //przelozenie PG-CH
|
||||
// ValveFlag: byte; //polozenie roznych zaworkow
|
||||
Zamykajacy: boolean; //pamiec zaworka zamykajacego
|
||||
// Przys_wlot: boolean; //wlot do komory przyspieszacza
|
||||
Przys_blok: boolean; //blokada przyspieszacza
|
||||
Miedzypoj: TReservoir; //pojemnosc posrednia (urojona) do napelniania ZP i ZS
|
||||
Przekladniki: array[1..3] of TPrzekladnik;
|
||||
RapidStatus: boolean;
|
||||
RapidStaly: boolean;
|
||||
LoadC: real;
|
||||
TareM, LoadM: real; //masa proznego i pelnego
|
||||
TareBP: real; //cisnienie dla proznego
|
||||
HBG300: real; //zawor ograniczajacy cisnienie
|
||||
Podskok: real; //podskok preznosci poczatkowej
|
||||
// HPBR: real; //zasilanie ZP z wysokiego cisnienia
|
||||
autom: boolean; //odluzniacz samoczynny
|
||||
LBP: real; //cisnienie hamulca pomocniczego
|
||||
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
|
||||
procedure SetSize(size: integer; params: string); //ustawianie dysz (rozmiaru ZR), przekladniki
|
||||
procedure PLC(mass: real); //wspolczynnik cisnienia przystawki wazacej
|
||||
procedure SetLP(TM, LM, TBP: real); //parametry przystawki wazacej
|
||||
procedure ForceEmptiness(); override; //wymuszenie bycia pustym
|
||||
procedure SetLBP(P: real); //cisnienie z hamulca pomocniczego
|
||||
end;
|
||||
|
||||
function d2A(d: real):real;
|
||||
|
||||
implementation
|
||||
|
||||
function d2A(d: real):real;
|
||||
begin
|
||||
d2A:=(d*d)*0.7854/1000;
|
||||
end;
|
||||
|
||||
// ------ RURA ------
|
||||
|
||||
function TRura.P: real;
|
||||
begin
|
||||
P:=Next.P;
|
||||
end;
|
||||
|
||||
procedure TRura.Update(dt: real);
|
||||
begin
|
||||
Next.Flow(dVol);
|
||||
dVol:=0;
|
||||
end;
|
||||
|
||||
// ------ PRZECIWPOSLIG ------
|
||||
|
||||
procedure TPrzeciwposlizg.SetPoslizg(flag: boolean);
|
||||
begin
|
||||
Poslizg:=flag;
|
||||
end;
|
||||
|
||||
procedure TPrzeciwposlizg.Update(dt: real);
|
||||
begin
|
||||
if (Poslizg) then
|
||||
begin
|
||||
BrakeRes.Flow(dVol);
|
||||
Next.Flow(PF(Next.P,0,d2A(10))*dt);
|
||||
end
|
||||
else
|
||||
Next.Flow(dVol);
|
||||
dVol:=0;
|
||||
end;
|
||||
|
||||
|
||||
// ------ PRZEKLADNIK ------
|
||||
|
||||
procedure TPrzekladnik.Update(dt: real);
|
||||
var BCP, BVP, dV: real;
|
||||
begin
|
||||
|
||||
BCP:=Next.P;
|
||||
BVP:=BrakeRes.P;
|
||||
|
||||
if(BCP>P)then
|
||||
dV:=-PFVd(BCP,0,d2A(10),P)*dt
|
||||
else
|
||||
if(BCP<P)then
|
||||
dV:=PFVa(BVP,BCP,d2A(10),P)*dt
|
||||
else dV:=0;
|
||||
|
||||
Next.Flow(dV);
|
||||
if dV>0 then
|
||||
BrakeRes.Flow(-dV);
|
||||
|
||||
end;
|
||||
|
||||
// ------ PRZEKLADNIK RAPID ------
|
||||
|
||||
procedure TRapid.SetRapidParams(mult: real; size: real);
|
||||
begin
|
||||
RapidMult:=mult;
|
||||
RapidStatus:=false;
|
||||
if (size>0.1) then //dopasowywanie srednicy przekladnika
|
||||
begin
|
||||
DN:=D2A(size*0.4);
|
||||
DL:=D2A(size*0.4);
|
||||
end
|
||||
else
|
||||
begin
|
||||
DN:=D2A(5);
|
||||
DL:=D2A(5);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TRapid.SetRapidStatus(rs: boolean);
|
||||
begin
|
||||
RapidStatus:=rs;
|
||||
end;
|
||||
|
||||
procedure TRapid.Update(dt: real);
|
||||
var BCP, BVP, dV, ActMult: real;
|
||||
begin
|
||||
BVP:=BrakeRes.P;
|
||||
BCP:=Next.P;
|
||||
|
||||
if(RapidStatus)then
|
||||
begin
|
||||
ActMult:=RapidMult;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ActMult:=1;
|
||||
end;
|
||||
|
||||
if(BCP*RapidMult>P*actMult)then
|
||||
dV:=-PFVd(BCP,0,DL,P*actMult/RapidMult)*dt
|
||||
else
|
||||
if(BCP*RapidMult<P*ActMult)then
|
||||
dV:=PFVa(BVP,BCP,DN,P*actMult/RapidMult)*dt
|
||||
else dV:=0;
|
||||
|
||||
Next.Flow(dV);
|
||||
if dV>0 then
|
||||
BrakeRes.Flow(-dV);
|
||||
|
||||
end;
|
||||
|
||||
// ------ PRZEK£ADNIK CI¥G£Y ------
|
||||
|
||||
procedure TPrzekCiagly.SetMult(m:real);
|
||||
begin
|
||||
Mult:=m;
|
||||
end;
|
||||
|
||||
procedure TPrzekCiagly.Update(dt: real);
|
||||
var BCP, BVP, dV: real;
|
||||
begin
|
||||
BVP:=BrakeRes.P;
|
||||
BCP:=Next.P;
|
||||
|
||||
if(BCP>P*Mult)then
|
||||
dV:=-PFVd(BCP,0,d2A(8),P*Mult)*dt
|
||||
else
|
||||
if(BCP<P*Mult)then
|
||||
dV:=PFVa(BVP,BCP,d2A(8),P*Mult)*dt
|
||||
else dV:=0;
|
||||
|
||||
Next.Flow(dV);
|
||||
if dV>0 then
|
||||
BrakeRes.Flow(-dV);
|
||||
|
||||
end;
|
||||
|
||||
// ------ PRZEK£ADNIK CI¥G£Y ------
|
||||
|
||||
procedure TPrzek_PZZ.SetLBP(P:real);
|
||||
begin
|
||||
LBP:=P;
|
||||
end;
|
||||
|
||||
procedure TPrzek_PZZ.Update(dt: real);
|
||||
var BCP, BVP, dV, Pgr: real;
|
||||
begin
|
||||
BVP:=BrakeRes.P;
|
||||
BCP:=Next.P;
|
||||
|
||||
Pgr:=Max0R(LBP,P);
|
||||
|
||||
if(BCP>Pgr)then
|
||||
dV:=-PFVd(BCP,0,d2A(8),Pgr)*dt
|
||||
else
|
||||
if(BCP<Pgr)then
|
||||
dV:=PFVa(BVP,BCP,d2A(8),Pgr)*dt
|
||||
else dV:=0;
|
||||
|
||||
Next.Flow(dV);
|
||||
if dV>0 then
|
||||
BrakeRes.Flow(-dV);
|
||||
|
||||
end;
|
||||
|
||||
// ------ PRZECIWPOSLIG ------
|
||||
|
||||
procedure TPrzekED.SetP(P: real);
|
||||
begin
|
||||
MaxP:=P;
|
||||
end;
|
||||
|
||||
procedure TPrzekED.Update(dt: real);
|
||||
begin
|
||||
if Next.P>MaxP then
|
||||
begin
|
||||
BrakeRes.Flow(dVol);
|
||||
Next.Flow(PFVd(Next.P,0,d2A(10)*dt,MaxP));
|
||||
end
|
||||
else
|
||||
Next.Flow(dVol);
|
||||
dVol:=0;
|
||||
end;
|
||||
|
||||
|
||||
// ------ OERLIKON EST NA BOGATO ------
|
||||
|
||||
function TNESt3.GetPF(PP, dt, Vel: real): real; //przeplyw miedzy komora wstepna i PG
|
||||
var dv, dv1, temp:real;
|
||||
VVP, BVP, BCP, CVP, MPP, nastG: real;
|
||||
i: byte;
|
||||
begin
|
||||
BVP:=BrakeRes.P;
|
||||
VVP:=ValveRes.P;
|
||||
// BCP:=BrakeCyl.P;
|
||||
BCP:=Przekladniki[1].P;
|
||||
CVP:=CntrlRes.P-0.0;
|
||||
MPP:=Miedzypoj.P;
|
||||
dV1:=0;
|
||||
|
||||
nastG:=(BrakeDelayFlag and bdelay_G);
|
||||
|
||||
//sprawdzanie stanu
|
||||
CheckState(BCP, dV1);
|
||||
CheckReleaser(dt);
|
||||
|
||||
//luzowanie
|
||||
if(BrakeStatus and b_hld)=b_off then
|
||||
dV:=PF(0,BCP,Nozzles[dTO]*nastG+(1-nastG)*Nozzles[dOO])*dt*(0.1+4.9*Min0R(0.2,BCP-((CVP-0.05-VVP)*BVM+0.1)))
|
||||
else dV:=0;
|
||||
// BrakeCyl.Flow(-dV);
|
||||
Przekladniki[1].Flow(-dV);
|
||||
if((BrakeStatus and b_on)=b_on)and(Przekladniki[1].P*HBG300<MaxBP)then
|
||||
dV:=PF(BVP,BCP,Nozzles[dTN]*(nastG+2*Byte(BCP<Podskok))+Nozzles[dON]*(1-nastG))*dt*(0.1+4.9*Min0R(0.2,(CVP-0.05-VVP)*BVM-BCP))
|
||||
else dV:=0;
|
||||
// BrakeCyl.Flow(-dV);
|
||||
Przekladniki[1].Flow(-dV);
|
||||
BrakeRes.Flow(dV);
|
||||
|
||||
for i:=1 to 3 do
|
||||
begin
|
||||
Przekladniki[i].Update(dt);
|
||||
if (Przekladniki[i] is TRapid) then
|
||||
begin
|
||||
RapidStatus:=(((BrakeDelayFlag and bdelay_R)=bdelay_R) and ((Abs(Vel)>70) or ((RapidStatus) and (Abs(Vel)>50)) or (RapidStaly)));
|
||||
(Przekladniki[i] as TRapid).SetRapidStatus(RapidStatus);
|
||||
end
|
||||
else
|
||||
if (Przekladniki[i] is TPrzeciwposlizg) then
|
||||
(Przekladniki[i] as TPrzeciwposlizg).SetPoslizg((BrakeStatus and b_asb)=b_asb)
|
||||
else
|
||||
if (Przekladniki[i] is TPrzekED) then
|
||||
if (Vel<-15) then
|
||||
(Przekladniki[i] as TPrzekED).SetP(0)
|
||||
else (Przekladniki[i] as TPrzekED).SetP(MaxBP*3)
|
||||
else
|
||||
if (Przekladniki[i] is TPrzekCiagly) then
|
||||
(Przekladniki[i] as TPrzekCiagly).SetMult(LoadC)
|
||||
else
|
||||
if (Przekladniki[i] is TPrzek_PZZ) then
|
||||
(Przekladniki[i] as TPrzek_PZZ).SetLBP(LBP);
|
||||
end;
|
||||
|
||||
|
||||
//przeplyw testowy miedzypojemnosci
|
||||
dV:=PF(MPP,VVP,BVs(BCP))+PF(MPP,CVP,CVs(BCP));
|
||||
if(MPP-0.05>BVP)then
|
||||
dV:=dV+PF(MPP-0.05,BVP,Nozzles[dPT]*nastG+(1-nastG)*Nozzles[dPO]);
|
||||
if MPP>VVP then dV:=dV+PF(MPP,VVP,d2A(5));
|
||||
Miedzypoj.Flow(dV*dt*0.15);
|
||||
|
||||
|
||||
//przeplyw ZS <-> PG
|
||||
temp:=CVs(BCP);
|
||||
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[dPT]*nastG+(1-nastG)*Nozzles[dPO])*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;
|
||||
Przekladniki[1].Act;
|
||||
Przekladniki[2].Act;
|
||||
Przekladniki[3].Act;
|
||||
GetPF:=dV-dV1;
|
||||
end;
|
||||
|
||||
|
||||
procedure TNESt3.EStParams(i_crc: real); //parametry charakterystyczne dla ESt
|
||||
begin
|
||||
|
||||
end;
|
||||
|
||||
|
||||
procedure TNESt3.Init(PP, HPP, LPP, BP: real; BDF: byte);
|
||||
begin
|
||||
ValveRes.CreatePress(1*PP);
|
||||
BrakeCyl.CreatePress(1*BP);
|
||||
BrakeRes.CreatePress(1*PP);
|
||||
CntrlRes:=TReservoir.Create;
|
||||
CntrlRes.CreateCap(15);
|
||||
CntrlRes.CreatePress(1*HPP);
|
||||
BrakeStatus:=Byte(BP>1)*1;
|
||||
Miedzypoj:=TReservoir.Create;
|
||||
Miedzypoj.CreateCap(5);
|
||||
Miedzypoj.CreatePress(PP);
|
||||
|
||||
BVM:=1/(HPP-0.05-LPP)*MaxBP;
|
||||
|
||||
BrakeDelayFlag:=BDF;
|
||||
|
||||
Zamykajacy:=false;
|
||||
|
||||
if not ((FM is TDisk1) or (FM is TDisk2)) then //jesli zeliwo to schodz
|
||||
RapidStaly:=false
|
||||
else
|
||||
RapidStaly:=true;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
function TNESt3.GetCRP: real;
|
||||
begin
|
||||
GetCRP:=CntrlRes.P;
|
||||
// GetCRP:=Przekladniki[1].P;
|
||||
// GetCRP:=Miedzypoj.P;
|
||||
end;
|
||||
|
||||
|
||||
procedure TNESt3.CheckState(BCP: real; var dV1: real); //glowny przyrzad rozrzadczy
|
||||
var VVP, BVP, CVP, MPP: real;
|
||||
begin
|
||||
BVP:=BrakeRes.P; //-> tu ma byc komora rozprezna
|
||||
VVP:=ValveRes.P;
|
||||
CVP:=CntrlRes.P;
|
||||
MPP:=Miedzypoj.P;
|
||||
|
||||
if(BCP<0.25)and(VVP+0.08>CVP)then Przys_blok:=false;
|
||||
|
||||
//sprawdzanie stanu
|
||||
// if ((BrakeStatus and 1)=1)and(BCP>0.25)then
|
||||
if(VVP+0.01+BCP/BVM<CVP-0.05)and(Przys_blok)then
|
||||
BrakeStatus:=(BrakeStatus or 3) //hamowanie stopniowe
|
||||
else if(VVP-0.01+(BCP-0.1)/BVM>CVP-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)/BVM<CVP-0.05)and(BCP>0.25)then //zatrzymanie luzowania
|
||||
BrakeStatus:=(BrakeStatus or 1);
|
||||
|
||||
if (BrakeStatus and 1)=0 then
|
||||
SoundFlag:=SoundFlag or sf_CylU;
|
||||
|
||||
if(VVP+0.10<CVP)and(BCP<0.25)then //poczatek hamowania
|
||||
if (not Przys_blok) then
|
||||
begin
|
||||
ValveRes.CreatePress(0.1*VVP);
|
||||
SoundFlag:=SoundFlag or sf_Acc;
|
||||
ValveRes.Act;
|
||||
Przys_blok:=true;
|
||||
end;
|
||||
|
||||
|
||||
if(BCP>0.5)then
|
||||
Zamykajacy:=true
|
||||
else if(VVP-0.6<MPP) then
|
||||
Zamykajacy:=false;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
procedure TNESt3.CheckReleaser(dt: real); //odluzniacz
|
||||
var
|
||||
VVP, CVP: real;
|
||||
begin
|
||||
VVP:=ValveRes.P;
|
||||
CVP:=CntrlRes.P;
|
||||
|
||||
//odluzniacz automatyczny
|
||||
if(BrakeStatus and b_rls=b_rls)then
|
||||
begin
|
||||
CntrlRes.Flow(+PF(CVP,0,0.02)*dt);
|
||||
if(CVP<VVP+0.3)or(not autom)then
|
||||
BrakeStatus:=BrakeStatus and 247;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function TNESt3.CVs(bp: real): real; //napelniacz sterujacego
|
||||
var CVP, MPP: real;
|
||||
begin
|
||||
CVP:=CntrlRes.P;
|
||||
MPP:=Miedzypoj.P;
|
||||
|
||||
//przeplyw ZS <-> PG
|
||||
if(MPP<CVP-0.17)then
|
||||
CVS:=0
|
||||
else
|
||||
if(MPP>CVP-0.08)then
|
||||
CVs:=Nozzles[dSD]
|
||||
else
|
||||
CVs:=Nozzles[dSm];
|
||||
end;
|
||||
|
||||
|
||||
function TNESt3.BVs(BCP: real): real; //napelniacz pomocniczego
|
||||
var CVP, MPP: real;
|
||||
begin
|
||||
CVP:=CntrlRes.P;
|
||||
MPP:=Miedzypoj.P;
|
||||
|
||||
//przeplyw ZP <-> rozdzielacz
|
||||
if(MPP<CVP-0.3)then
|
||||
BVs:=Nozzles[dP]
|
||||
else
|
||||
if(BCP<0.5) then
|
||||
if(Zamykajacy)then
|
||||
BVs:=Nozzles[dPm] //1.25
|
||||
else
|
||||
BVs:=Nozzles[dPD]
|
||||
else
|
||||
BVs:=0;
|
||||
end;
|
||||
|
||||
procedure TNESt3.PLC(mass: real);
|
||||
begin
|
||||
LoadC:=1+Byte(Mass<LoadM)*((TareBP+(MaxBP-TareBP)*(mass-TareM)/(LoadM-TareM))/MaxBP-1);
|
||||
end;
|
||||
|
||||
procedure TNESt3.ForceEmptiness();
|
||||
begin
|
||||
ValveRes.CreatePress(0);
|
||||
BrakeRes.CreatePress(0);
|
||||
Miedzypoj.CreatePress(0);
|
||||
CntrlRes.CreatePress(0);
|
||||
|
||||
BrakeStatus:=0;
|
||||
|
||||
ValveRes.Act();
|
||||
BrakeRes.Act();
|
||||
Miedzypoj.Act();
|
||||
CntrlRes.Act();
|
||||
end;
|
||||
|
||||
|
||||
procedure TNESt3.SetLP(TM, LM, TBP: real);
|
||||
begin
|
||||
TareM:=TM;
|
||||
LoadM:=LM;
|
||||
TareBP:=TBP;
|
||||
end;
|
||||
|
||||
|
||||
procedure TNESt3.SetLBP(P: real);
|
||||
begin
|
||||
LBP:=P;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
procedure TNESt3.SetSize(size: integer; params: string); //ustawianie dysz (rozmiaru ZR)
|
||||
const
|
||||
dNO1l = 1.250;
|
||||
dNT1l = 0.510;
|
||||
dOO1l = 0.907;
|
||||
dOT1l = 0.524;
|
||||
var
|
||||
i:integer;
|
||||
begin
|
||||
|
||||
if Pos('ESt3',params)>0 then
|
||||
begin
|
||||
Podskok:=0.7;
|
||||
Przekladniki[1]:=TRura.Create;
|
||||
Przekladniki[3]:=TRura.Create;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Podskok:=-1;
|
||||
Przekladniki[1]:=TRapid.Create;
|
||||
if Pos('-s216',params)>0 then
|
||||
(Przekladniki[1] as TRapid).SetRapidParams(2,16)
|
||||
else
|
||||
(Przekladniki[1] as TRapid).SetRapidParams(2,0);
|
||||
Przekladniki[3]:=TPrzeciwposlizg.Create;
|
||||
if Pos('-ED',params)>0 then
|
||||
begin
|
||||
Przekladniki[3].Free();
|
||||
(Przekladniki[1] as TRapid).SetRapidParams(2,18);
|
||||
Przekladniki[3]:=TPrzekED.Create;
|
||||
end;
|
||||
end;
|
||||
|
||||
if Pos('AL2',params)>0 then
|
||||
Przekladniki[2]:=TPrzekCiagly.Create
|
||||
else
|
||||
if Pos('PZZ',params)>0 then
|
||||
Przekladniki[2]:=TPrzek_PZZ.Create
|
||||
else
|
||||
Przekladniki[2]:=TRura.Create;
|
||||
|
||||
if (Pos('3d',params)+Pos('4d',params)>0) then autom:=false else autom:=true;
|
||||
if (Pos('HBG300',params)>0) then HBG300:=1 else HBG300:=0;
|
||||
|
||||
case size of
|
||||
16:
|
||||
begin //dON,dOO,dTN,dTO,dP,dS
|
||||
Nozzles[dON]:=5.0;//5.0;
|
||||
Nozzles[dOO]:=3.4;//3.4;
|
||||
Nozzles[dTN]:=2.0;
|
||||
Nozzles[dTO]:=1.75;
|
||||
Nozzles[dP]:=3.8;
|
||||
Nozzles[dPd]:=2.70;
|
||||
Nozzles[dPm]:=1.25;
|
||||
Nozzles[dPO]:=Nozzles[dON];
|
||||
Nozzles[dPT]:=Nozzles[dTN];
|
||||
end;
|
||||
14:
|
||||
begin //dON,dOO,dTN,dTO,dP,dS
|
||||
Nozzles[dON]:=4.3;
|
||||
Nozzles[dOO]:=2.85;
|
||||
Nozzles[dTN]:=1.83;
|
||||
Nozzles[dTO]:=1.57;
|
||||
Nozzles[dP]:=3.4;
|
||||
Nozzles[dPd]:=2.20;
|
||||
Nozzles[dPm]:=1.10;
|
||||
Nozzles[dPO]:=Nozzles[dON];
|
||||
Nozzles[dPT]:=Nozzles[dTN];
|
||||
end;
|
||||
12:
|
||||
begin //dON,dOO,dTN,dTO,dP,dS
|
||||
Nozzles[dON]:=3.7;
|
||||
Nozzles[dOO]:=2.50;
|
||||
Nozzles[dTN]:=1.65;
|
||||
Nozzles[dTO]:=1.39;
|
||||
Nozzles[dP]:=2.65;
|
||||
Nozzles[dPd]:=1.80;
|
||||
Nozzles[dPm]:=0.85;
|
||||
Nozzles[dPO]:=Nozzles[dON];
|
||||
Nozzles[dPT]:=Nozzles[dTN];
|
||||
end;
|
||||
10:
|
||||
begin //dON,dOO,dTN,dTO,dP,dS
|
||||
Nozzles[dON]:=3.1;
|
||||
Nozzles[dOO]:=2.0;
|
||||
Nozzles[dTN]:=1.35;
|
||||
Nozzles[dTO]:=1.13;
|
||||
Nozzles[dP]:=1.6;
|
||||
Nozzles[dPd]:=1.55;
|
||||
Nozzles[dPm]:=0.7;
|
||||
Nozzles[dPO]:=Nozzles[dON];
|
||||
Nozzles[dPT]:=Nozzles[dTN];
|
||||
end;
|
||||
200:
|
||||
begin //dON,dOO,dTN,dTO,dP,dS
|
||||
Nozzles[dON]:=dNO1l;
|
||||
Nozzles[dOO]:=dOO1l/1.15;
|
||||
Nozzles[dTN]:=dNT1l;
|
||||
Nozzles[dTO]:=dOT1l;
|
||||
Nozzles[dP]:=7.4;
|
||||
Nozzles[dPd]:=5.3;
|
||||
Nozzles[dPm]:=2.5;
|
||||
Nozzles[dPO]:=7.28;
|
||||
Nozzles[dPT]:=2.96;
|
||||
end;
|
||||
375:
|
||||
begin //dON,dOO,dTN,dTO,dP,dS
|
||||
Nozzles[dON]:=dNO1l;
|
||||
Nozzles[dOO]:=dOO1l/1.15;
|
||||
Nozzles[dTN]:=dNT1l;
|
||||
Nozzles[dTO]:=dOT1l;
|
||||
Nozzles[dP]:=13.0;
|
||||
Nozzles[dPd]:=9.6;
|
||||
Nozzles[dPm]:=4.4;
|
||||
Nozzles[dPO]:=9.92;
|
||||
Nozzles[dPT]:=3.99;
|
||||
end;
|
||||
150:
|
||||
begin //dON,dOO,dTN,dTO,dP,dS
|
||||
Nozzles[dON]:=dNO1l;
|
||||
Nozzles[dOO]:=dOO1l;
|
||||
Nozzles[dTN]:=dNT1l;
|
||||
Nozzles[dTO]:=dOT1l;
|
||||
Nozzles[dP]:=5.8;
|
||||
Nozzles[dPd]:=4.1;
|
||||
Nozzles[dPm]:=1.9;
|
||||
Nozzles[dPO]:=6.33;
|
||||
Nozzles[dPT]:=2.58;
|
||||
end;
|
||||
100:
|
||||
begin //dON,dOO,dTN,dTO,dP,dS
|
||||
Nozzles[dON]:=dNO1l;
|
||||
Nozzles[dOO]:=dOO1l;
|
||||
Nozzles[dTN]:=dNT1l;
|
||||
Nozzles[dTO]:=dOT1l;
|
||||
Nozzles[dP]:=4.2;
|
||||
Nozzles[dPd]:=2.9;
|
||||
Nozzles[dPm]:=1.4;
|
||||
Nozzles[dPO]:=5.19;
|
||||
Nozzles[dPT]:=2.14;
|
||||
end;
|
||||
else
|
||||
begin
|
||||
Nozzles[dON]:=0;
|
||||
Nozzles[dOO]:=0;
|
||||
Nozzles[dTN]:=0;
|
||||
Nozzles[dTO]:=0;
|
||||
Nozzles[dP]:=0;
|
||||
Nozzles[dPd]:=0;
|
||||
Nozzles[dPm]:=0;
|
||||
end;
|
||||
end;
|
||||
|
||||
Nozzles[dSd]:=1.1;
|
||||
Nozzles[dSm]:=0.9;
|
||||
|
||||
//przeliczanie z mm^2 na l/m
|
||||
for i:=0 to dMAX do
|
||||
begin
|
||||
Nozzles[i]:=d2A(Nozzles[i]); //(/1000^2*pi/4*1000)
|
||||
end;
|
||||
|
||||
for i:=1 to 3 do
|
||||
begin
|
||||
Przekladniki[i].BrakeRes:=@BrakeRes;
|
||||
Przekladniki[i].CreateCap(i);
|
||||
Przekladniki[i].CreatePress(BrakeCyl.P);
|
||||
if i<3 then
|
||||
Przekladniki[i].Next:=@Przekladniki[i+1]
|
||||
else
|
||||
Przekladniki[i].Next:=@BrakeCyl;
|
||||
end
|
||||
end;
|
||||
|
||||
end.
|
||||
484
McZapkie/Unit1.pas
Normal file
484
McZapkie/Unit1.pas
Normal file
@@ -0,0 +1,484 @@
|
||||
unit Unit1;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
ai_driver,mtable,mover,mctools,Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
|
||||
StdCtrls, ExtCtrls;
|
||||
|
||||
type
|
||||
TForm1 = class(TForm)
|
||||
Button1: TButton;
|
||||
Button2: TButton;
|
||||
Button3: TButton;
|
||||
Button4: TButton;
|
||||
Button5: TButton;
|
||||
Button6: TButton;
|
||||
Label2: TLabel;
|
||||
Label3: TLabel;
|
||||
Timer1: TTimer;
|
||||
Label4: TLabel;
|
||||
Label5: TLabel;
|
||||
Label6: TLabel;
|
||||
Label9: TLabel;
|
||||
Label10: TLabel;
|
||||
Label11: TLabel;
|
||||
Button7: TButton;
|
||||
Button8: TButton;
|
||||
Label12: TLabel;
|
||||
Label13: TLabel;
|
||||
Label14: TLabel;
|
||||
Label15: TLabel;
|
||||
Button9: TButton;
|
||||
Button10: TButton;
|
||||
Label16: TLabel;
|
||||
Label17: TLabel;
|
||||
Label18: TLabel;
|
||||
Label19: TLabel;
|
||||
Button11: TButton;
|
||||
Label20: TLabel;
|
||||
Label21: TLabel;
|
||||
Label22: TLabel;
|
||||
Label23: TLabel;
|
||||
Label24: TLabel;
|
||||
Label25: TLabel;
|
||||
lczas: TLabel;
|
||||
Label28: TLabel;
|
||||
Label29: TLabel;
|
||||
Label30: TLabel;
|
||||
Label31: TLabel;
|
||||
Label32: TLabel;
|
||||
Label33: TLabel;
|
||||
Label34: TLabel;
|
||||
Button12: TButton;
|
||||
BStart: TButton;
|
||||
Label35: TLabel;
|
||||
Label36: TLabel;
|
||||
Label37: TLabel;
|
||||
Label38: TLabel;
|
||||
Button13: TButton;
|
||||
Label39: TLabel;
|
||||
Label40: TLabel;
|
||||
Label41: TLabel;
|
||||
Label42: TLabel;
|
||||
Label43: TLabel;
|
||||
Button14: TButton;
|
||||
Button15: TButton;
|
||||
Label44: TLabel;
|
||||
Label45: TLabel;
|
||||
Label46: TLabel;
|
||||
Label47: TLabel;
|
||||
BMains: TButton;
|
||||
Label48: TLabel;
|
||||
Label49: TLabel;
|
||||
Label50: TLabel;
|
||||
Panel1: TPanel;
|
||||
Label1: TLabel;
|
||||
OpenDialog1: TOpenDialog;
|
||||
Edit1: TEdit;
|
||||
GroupBox1: TGroupBox;
|
||||
CheckBox1: TCheckBox;
|
||||
BSInc: TButton;
|
||||
BSDec: TButton;
|
||||
Label51: TLabel;
|
||||
Label52: TLabel;
|
||||
procedure Button1Click(Sender: TObject);
|
||||
procedure Button2Click(Sender: TObject);
|
||||
procedure Timer1Timer(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure Button5Click(Sender: TObject);
|
||||
procedure Button6Click(Sender: TObject);
|
||||
procedure Button7Click(Sender: TObject);
|
||||
procedure Button8Click(Sender: TObject);
|
||||
procedure Button3Click(Sender: TObject);
|
||||
procedure Button4Click(Sender: TObject);
|
||||
procedure Button9Click(Sender: TObject);
|
||||
procedure Button10Click(Sender: TObject);
|
||||
procedure Button11Click(Sender: TObject);
|
||||
procedure Button12Click(Sender: TObject);
|
||||
procedure BStartClick(Sender: TObject);
|
||||
procedure Button13MouseDown(Sender: TObject; Button: TMouseButton;
|
||||
Shift: TShiftState; X, Y: Integer);
|
||||
procedure Button14Click(Sender: TObject);
|
||||
procedure Button15Click(Sender: TObject);
|
||||
procedure BMainsClick(Sender: TObject);
|
||||
procedure CheckBox1Click(Sender: TObject);
|
||||
procedure BSIncClick(Sender: TObject);
|
||||
procedure BSDecClick(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
const
|
||||
mtno=30;
|
||||
tno:integer=0;
|
||||
|
||||
var
|
||||
Form1: TForm1;
|
||||
loc:TMoverParameters;
|
||||
wagony:array[1..mtno] of TMoverParameters;
|
||||
mechanik: TController;
|
||||
pociag: TTrainParameters;
|
||||
couplerflag:byte;
|
||||
l0,l0p:TLocation;
|
||||
ll:array[1..mtno] of TLocation;
|
||||
r0:TRotation;
|
||||
rr:array[1..mtno] of TRotation;
|
||||
Shape:TTrackShape; Track:TTrackParam;
|
||||
ExternalVoltage:real;
|
||||
ActualTime:real;
|
||||
fout: text;
|
||||
OK:boolean;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.DFM}
|
||||
|
||||
procedure TForm1.Button1Click(Sender: TObject);
|
||||
var typename,path:string;slashpos:byte;
|
||||
begin
|
||||
|
||||
couplerflag:=strtoint(Edit1.Text);
|
||||
if tno>0 then
|
||||
wagony[tno]:=TMoverParameters.Create;
|
||||
|
||||
OpenDialog1.Execute;
|
||||
path:='';
|
||||
typename:=OpenDialog1.Filename;
|
||||
repeat
|
||||
slashpos:=pos('\',typename);
|
||||
if slashpos>0 then
|
||||
typename:=copy(typename,slashpos+1,length(typename));
|
||||
until slashpos=0;
|
||||
path:=copy(opendialog1.filename,1,length(opendialog1.filename)-length(typename));
|
||||
typename:=Copy(typename,1,Pos('.chk',typename)-1);
|
||||
|
||||
if tno=0 then
|
||||
begin
|
||||
loc.Init(l0,r0,0,typename,'lokomotywa',0,'',1);
|
||||
OK:=loc.loadchkfile(path) and loc.CheckLocomotiveParameters(Go);
|
||||
if OK then
|
||||
begin
|
||||
Label1.Caption:=loc.TypeName;
|
||||
case loc.AutoRelayType of
|
||||
2: CheckBox1.Enabled:=True;
|
||||
1: CheckBox1.Checked:=True;
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
wagony[tno].Init(ll[tno],rr[tno],0,typename,IntToStr(tno),0,'',0);
|
||||
OK:=OK and (wagony[tno].loadchkfile(path) and wagony[tno].CheckLocomotiveParameters(Go));
|
||||
if OK then
|
||||
begin
|
||||
Label1.Caption:=Label1.Caption+' '+wagony[tno].TypeName;
|
||||
if tno=1 then
|
||||
ll[tno].x:=loc.Loc.x-loc.Dim.L/2-wagony[tno].Dim.L/2
|
||||
else
|
||||
ll[tno].x:=wagony[tno-1].Loc.x-wagony[tno-1].Dim.L/2-wagony[tno].Dim.L/2;
|
||||
wagony[tno].loc:=ll[tno];
|
||||
if tno=1 then
|
||||
begin
|
||||
OK:=OK and loc.attach(2,@wagony[1],couplerflag);
|
||||
OK:=OK and wagony[1].attach(1,@loc,couplerflag);
|
||||
end
|
||||
else
|
||||
begin
|
||||
OK:=OK and wagony[tno-1].attach(2,@wagony[tno],couplerflag);
|
||||
OK:=OK and wagony[tno].attach(1,@wagony[tno-1],couplerflag);
|
||||
end
|
||||
end;
|
||||
end;
|
||||
|
||||
if OK then
|
||||
begin
|
||||
BStart.Enabled:=True;
|
||||
if tno=mtno then button1.enabled:=false
|
||||
else inc(tno);
|
||||
Label49.Caption:='ilosc pojazdow '+inttostr(tno);
|
||||
end
|
||||
else
|
||||
begin
|
||||
Label1.Caption:=inttostr(conversionerror)+' '+inttostr(linecount);
|
||||
Button1.Enabled:=False;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button2Click(Sender: TObject);
|
||||
var iw:integer;
|
||||
begin
|
||||
if Timer1.Enabled then
|
||||
begin
|
||||
Timer1.Enabled:=False;
|
||||
CloseFile(fout);
|
||||
end;
|
||||
mechanik.CloseLog;
|
||||
mechanik.free;
|
||||
loc.Free;
|
||||
for iw:=1 to tno do
|
||||
wagony[iw].Free;
|
||||
Close;
|
||||
end;
|
||||
|
||||
procedure TForm1.Timer1Timer(Sender: TObject);
|
||||
var dl,dt:real; iw:integer;
|
||||
begin
|
||||
dt:=Timer1.Interval/1000;
|
||||
ActualTime:=ActualTime+dt;
|
||||
if l0.x>200 then Shape.R:=1000;
|
||||
if l0.x>1000 then Shape.R:=-500;
|
||||
if l0.x>1500 then Shape.R:=0;
|
||||
if l0.x>2000 then Shape.R:=1500;
|
||||
if l0.x>2200 then Shape.R:=3000;
|
||||
if l0.x>2400 then Shape.R:=0;
|
||||
loc.ComputeTotalForce(dt);
|
||||
for iw:=1 to tno do
|
||||
wagony[iw].ComputeTotalForce(dt);
|
||||
dl:=loc.ComputeMovement(dt,Shape,Track,ExternalVoltage,l0,r0);
|
||||
l0.x:=l0.x+dl;
|
||||
for iw:=1 to tno do
|
||||
begin
|
||||
dl:=wagony[iw].ComputeMovement(dt,Shape,Track,ExternalVoltage,ll[iw],rr[iw]);
|
||||
ll[iw].x:=ll[iw].x+dl;
|
||||
end;
|
||||
|
||||
mechanik.UpdateSituation(dt);
|
||||
|
||||
|
||||
l0p.x:=500; l0p.y:=2; l0.z:=0;
|
||||
if (l0.x>-1) and (l0.x<5) then
|
||||
loc.PutCommand('SetVelocity',60,-1,l0p);
|
||||
if (l0.x>499) and (l0.x<505) then
|
||||
loc.PutCommand('SetVelocity',-1,-1,l0);
|
||||
l0p.x:=3600;
|
||||
if (l0.x>2985) and (l0.x<3005) then
|
||||
loc.PutCommand('SetVelocity',-1,0,l0p);
|
||||
if (l0.x>3600) and (l0.x<3615) then
|
||||
loc.PutCommand('SetVelocity',0,0,l0);
|
||||
if (l0.x>3430) and (loc.Vel<0.01) and (mechanik.GetCurrentOrder=Obey_train) then
|
||||
loc.PutCommand('SetVelocity',0,0,l0);
|
||||
|
||||
if (loc.power>0) then
|
||||
begin
|
||||
Label2.Caption:='I0='+r2s(Loc.Im,0)+' A';
|
||||
Label3.Caption:=r2s(Loc.Ft/1000,0)+' kN';
|
||||
Label13.Caption:=IntToStr(Loc.MainCtrlPos);
|
||||
Label18.Caption:=IntToStr(Loc.ScndCtrlPos);
|
||||
Label20.Caption:=IntToStr(Loc.MainCtrlActualPos);
|
||||
Label21.Caption:=IntToStr(Loc.ScndCtrlActualPos);
|
||||
end
|
||||
else
|
||||
for iw:=1 to tno do
|
||||
if wagony[iw].power>0 then
|
||||
begin
|
||||
Label2.Caption:='I'+IntToStr(iw)+'='+r2s(wagony[iw].Im,0)+' A';
|
||||
Label3.Caption:=r2s(wagony[iw].Ft/1000,0)+' kN';
|
||||
Label13.Caption:=IntToStr(wagony[iw].MainCtrlPos);
|
||||
Label18.Caption:=IntToStr(wagony[iw].ScndCtrlPos);
|
||||
Label20.Caption:=IntToStr(wagony[iw].MainCtrlActualPos);
|
||||
Label21.Caption:=IntToStr(wagony[iw].ScndCtrlActualPos);
|
||||
end;
|
||||
Label4.Caption:=r2s(l0.x,0)+' m';
|
||||
Label5.Caption:=r2s(Sign(Loc.V)*Loc.Vel,0)+' km/h';
|
||||
Label6.Caption:=r2s(Loc.AccS,0)+' m/ss';
|
||||
Label9.Caption:=r2s(Loc.Fb/1000,0)+' kN';
|
||||
Label10.Caption:=r2s(Loc.Compressor,0)+' MPa';
|
||||
Label11.Caption:=r2s(Loc.PipePress,0)+' MPa';
|
||||
Label12.Caption:=r2s(Loc.BrakePress,0)+' MPa';
|
||||
|
||||
|
||||
Label14.Caption:=IntToStr(Loc.BrakeCtrlPos);
|
||||
Label15.Caption:=IntToStr(Loc.LocalBrakePos);
|
||||
|
||||
Label16.Caption:=IntToStr(Loc.showcurrent(1));
|
||||
Label17.Caption:=IntToStr(Loc.showcurrent(2));
|
||||
|
||||
if loc.SlippingWheels then
|
||||
Label19.Caption:='Poslizg!'
|
||||
else Label19.Caption:=' ';
|
||||
|
||||
|
||||
Label22.Caption:=r2s(ll[1].x,0)+' m';
|
||||
if tno>=1 then
|
||||
begin
|
||||
Label23.Caption:=r2s(Sign(wagony[1].V)*wagony[1].Vel,0)+' km/h';
|
||||
Label24.Caption:=r2s(Distance(loc.loc,wagony[1].loc,loc.dim,wagony[1].dim),0)+' m';
|
||||
end;
|
||||
Label25.Caption:=r2s(loc.nrot,0)+' 1/s';
|
||||
|
||||
Label28.Caption:=r2s(ll[2].x,0)+' m';
|
||||
|
||||
if tno>=2 then
|
||||
Label29.Caption:=r2s(sign(wagony[2].V)*wagony[2].Vel,0)+' km/h';
|
||||
|
||||
Label30.Caption:=r2s(loc.dpLocalValve/dt,0)+' MPa/s';
|
||||
Label31.Caption:=r2s(loc.dpBrake/dt,0)+' MPa/s';
|
||||
Label32.Caption:=r2s(loc.dpMainValve/dt,0)+' MPa/s';
|
||||
Label33.Caption:=r2s(loc.dpPipe/dt,0)+' MPa/s';
|
||||
|
||||
if tno>0 then Label34.Caption:=r2s(wagony[tno].PipePress,0)+' MPa';
|
||||
|
||||
Label35.Caption:=r2s(ll[3].x,0)+' m';
|
||||
if tno>0 then Label36.Caption:=r2s(sign(wagony[tno].V)*wagony[tno].Vel,0)+' km/h';
|
||||
if tno>0 then Label37.Caption:=r2s(wagony[tno].couplers[1].cforce/1000,0)+' kN';
|
||||
if tno>0 then Label38.Caption:=r2s(wagony[tno].brakepress,0)+' MPa';
|
||||
|
||||
Label39.Caption:=r2s(loc.enginePower/1000,0)+' kW';
|
||||
Label40.Caption:=i2s(trunc(loc.Rventrot*60))+' /min';
|
||||
Label41.Visible:=loc.SandDose;
|
||||
Label42.Caption:=r2s(mechanik.accdesired,0)+' m/ss';
|
||||
Label43.Caption:=r2s(mechanik.veldesired,0)+' km/h';
|
||||
if tno>0 then Label44.Caption:=r2s(ll[tno].x,0)+' m';
|
||||
Label45.Caption:=inttostr(loc.activedir);
|
||||
Label46.Caption:=inttostr(ord(mechanik.orderlist[mechanik.orderpos]));
|
||||
Label47.Caption:=inttostr(mechanik.orderpos);
|
||||
Label48.Caption:=inttostr(ord(loc.mains));
|
||||
{ if tno>0 then Label51.Caption:=wagony[1].CommandIn.Command;
|
||||
if tno>0 then Label52.Caption:=r2s(wagony[1].CommandIn.Value1,0);
|
||||
}
|
||||
Label51.Caption:=loc.CommandIn.Command;
|
||||
Label52.Caption:=r2s(loc.CommandIn.Value1,0);
|
||||
Lczas.Caption:=r2s(actualtime,0)+' s';
|
||||
writeln(fout,Actualtime,' ',{loc.v-wag.v,}loc.UnitBrakeForce,' ',loc.dpMainValve,{' ',loc.dpLocalValve,}' ',loc.accs,' ',loc.couplers[2].cforce,' ',{,l1.x}' '{,Distance(loc.loc,wagony[1].loc,loc.dim,wagony[1].dim)});
|
||||
end;
|
||||
|
||||
procedure TForm1.FormCreate(Sender: TObject);
|
||||
var iw:integer;
|
||||
begin
|
||||
Timer1.Enabled:=False;
|
||||
tno:=0;
|
||||
assignfile(fout,'log.dat');
|
||||
rewrite(fout);
|
||||
ActualTime:=0;
|
||||
loc:=TMoverParameters.Create;
|
||||
Shape.R:=0; Shape.Len:=10000; Shape.dHtrack:=0; Shape.dHrail:=0;
|
||||
Track.Width:=1435; Track.friction:=0.15; Track.CategoryFlag:=1;
|
||||
Track.QualityFlag:=25; Track.DamageFlag:=0;
|
||||
Track.VelMax:=120;
|
||||
ExternalVoltage:=3000;
|
||||
l0.x:=0; l0.y:=0; l0.z:=0;
|
||||
r0.rx:=0; r0.ry:=0; r0.rz:=0;
|
||||
for iw:=1 to mtno do
|
||||
begin
|
||||
rr[iw].rx:=0; rr[iw].ry:=0; rr[iw].rz:=0;
|
||||
ll[iw].x:=0; ll[iw].y:=0; ll[iw].z:=0;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure TForm1.Button5Click(Sender: TObject);
|
||||
begin
|
||||
loc.incbrakelevel;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button6Click(Sender: TObject);
|
||||
begin
|
||||
loc.decbrakelevel;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button7Click(Sender: TObject);
|
||||
begin
|
||||
loc.inclocalbrakelevel(1);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button8Click(Sender: TObject);
|
||||
begin
|
||||
loc.declocalbrakelevel(1);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button3Click(Sender: TObject);
|
||||
begin
|
||||
loc.incmainctrl(1);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button4Click(Sender: TObject);
|
||||
begin
|
||||
loc.decmainctrl(1);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button9Click(Sender: TObject);
|
||||
begin
|
||||
loc.DirectionForward;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button10Click(Sender: TObject);
|
||||
begin
|
||||
loc.DirectionBackward;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button11Click(Sender: TObject);
|
||||
begin
|
||||
loc.FuseOn;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button12Click(Sender: TObject);
|
||||
begin
|
||||
Loc.AntiSlippingBrake;
|
||||
end;
|
||||
|
||||
procedure TForm1.BStartClick(Sender: TObject);
|
||||
begin
|
||||
tno:=tno-1;
|
||||
Button1.Enabled:=False;
|
||||
Edit1.Enabled:=False;
|
||||
Timer1.Enabled:=True;
|
||||
mechanik:=TController.Create;
|
||||
pociag:=TTrainParameters.Create;
|
||||
pociag.init('Testowy Express',100);
|
||||
mechanik.init(l0,r0,HumanDriver,@loc,@pociag,Aggressive);
|
||||
|
||||
BStart.Enabled:=False;
|
||||
Button14.enabled:=True;
|
||||
Button15.enabled:=True;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button13MouseDown(Sender: TObject; Button: TMouseButton;
|
||||
Shift: TShiftState; X, Y: Integer);
|
||||
begin
|
||||
loc.SandDoseOn;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button14Click(Sender: TObject);
|
||||
begin
|
||||
mechanik.SetVelocity(30,120);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button15Click(Sender: TObject);
|
||||
begin
|
||||
mechanik.AIControllFlag:=not mechanik.AIControllFlag;
|
||||
if not loc.mains then
|
||||
begin
|
||||
mechanik.ChangeOrder(Prepare_Engine);
|
||||
mechanik.JumpToNextOrder;
|
||||
mechanik.ChangeOrder(Obey_train);
|
||||
mechanik.JumpToNextOrder;
|
||||
mechanik.ChangeOrder(Release_engine);
|
||||
mechanik.JumpToFirstOrder;
|
||||
mechanik.SetVelocity(60,120);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TForm1.BMainsClick(Sender: TObject);
|
||||
begin
|
||||
loc.MainSwitch;
|
||||
end;
|
||||
|
||||
procedure TForm1.CheckBox1Click(Sender: TObject);
|
||||
begin
|
||||
loc.autorelayswitch;
|
||||
end;
|
||||
|
||||
procedure TForm1.BSIncClick(Sender: TObject);
|
||||
begin
|
||||
loc.incscndctrl(1);
|
||||
end;
|
||||
|
||||
procedure TForm1.BSDecClick(Sender: TObject);
|
||||
begin
|
||||
loc.decscndctrl(1);
|
||||
end;
|
||||
|
||||
end.
|
||||
880
McZapkie/_Mover.hpp
Normal file
880
McZapkie/_Mover.hpp
Normal file
@@ -0,0 +1,880 @@
|
||||
// Borland C++ Builder
|
||||
// Copyright (c) 1995, 1999 by Borland International
|
||||
// All rights reserved
|
||||
|
||||
// (DO NOT EDIT: machine generated header) '_mover.pas' rev: 5.00
|
||||
|
||||
#ifndef _moverHPP
|
||||
#define _moverHPP
|
||||
|
||||
#pragma delphiheader begin
|
||||
#pragma option push -w-
|
||||
#pragma option push -Vx
|
||||
#include <Oerlikon_ESt.hpp> // Pascal unit
|
||||
#include <hamulce.hpp> // Pascal unit
|
||||
#include <SysUtils.hpp> // Pascal unit
|
||||
#include <mctools.hpp> // Pascal unit
|
||||
#include <SysInit.hpp> // Pascal unit
|
||||
#include <System.hpp> // Pascal unit
|
||||
|
||||
//-- user supplied -----------------------------------------------------------
|
||||
|
||||
namespace _mover
|
||||
{
|
||||
//-- type declarations -------------------------------------------------------
|
||||
struct TLocation
|
||||
{
|
||||
double X;
|
||||
double Y;
|
||||
double Z;
|
||||
} ;
|
||||
|
||||
struct TRotation
|
||||
{
|
||||
double Rx;
|
||||
double Ry;
|
||||
double Rz;
|
||||
} ;
|
||||
|
||||
struct TDimension
|
||||
{
|
||||
double W;
|
||||
double L;
|
||||
double H;
|
||||
} ;
|
||||
|
||||
struct TCommand
|
||||
{
|
||||
AnsiString Command;
|
||||
double Value1;
|
||||
double Value2;
|
||||
TLocation Location;
|
||||
} ;
|
||||
|
||||
struct TTrackShape
|
||||
{
|
||||
double R;
|
||||
double Len;
|
||||
double dHtrack;
|
||||
double dHrail;
|
||||
} ;
|
||||
|
||||
struct TTrackParam
|
||||
{
|
||||
double Width;
|
||||
double friction;
|
||||
Byte CategoryFlag;
|
||||
Byte QualityFlag;
|
||||
Byte DamageFlag;
|
||||
double Velmax;
|
||||
} ;
|
||||
|
||||
struct TTractionParam
|
||||
{
|
||||
double TractionVoltage;
|
||||
double TractionFreq;
|
||||
double TractionMaxCurrent;
|
||||
double TractionResistivity;
|
||||
} ;
|
||||
|
||||
#pragma option push -b-
|
||||
enum TBrakeSystem { Individual, Pneumatic, ElectroPneumatic };
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum TBrakeSubSystem { ss_None, ss_W, ss_K, ss_KK, ss_Hik, ss_ESt, ss_KE, ss_LSt, ss_MT, ss_Dako };
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum 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
|
||||
};
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum TBrakeHandle { NoHandle, West, FV4a, M394, M254, FVel1, FVel6, D2, Knorr, FD1, BS2, testH, St113
|
||||
};
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum TLocalBrake { NoBrake, ManualBrake, PneumaticBrake, HydraulicBrake };
|
||||
#pragma option pop
|
||||
|
||||
typedef double TBrakeDelayTable[4];
|
||||
|
||||
struct TBrakePressure
|
||||
{
|
||||
double PipePressureVal;
|
||||
double BrakePressureVal;
|
||||
double FlowSpeedVal;
|
||||
TBrakeSystem BrakeType;
|
||||
} ;
|
||||
|
||||
typedef TBrakePressure TBrakePressureTable[13];
|
||||
|
||||
#pragma option push -b-
|
||||
enum TEngineTypes { None, Dumb, WheelsDriven, ElectricSeriesMotor, ElectricInductionMotor, DieselEngine,
|
||||
SteamEngine, DieselElectric };
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum TPowerType { NoPower, BioPower, MechPower, ElectricPower, SteamPower };
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum TFuelType { Undefined, Coal, Oil };
|
||||
#pragma option pop
|
||||
|
||||
struct TGrateType
|
||||
{
|
||||
TFuelType FuelType;
|
||||
double GrateSurface;
|
||||
double FuelTransportSpeed;
|
||||
double IgnitionTemperature;
|
||||
double MaxTemperature;
|
||||
} ;
|
||||
|
||||
struct TBoilerType
|
||||
{
|
||||
double BoilerVolume;
|
||||
double BoilerHeatSurface;
|
||||
double SuperHeaterSurface;
|
||||
double MaxWaterVolume;
|
||||
double MinWaterVolume;
|
||||
double MaxPressure;
|
||||
} ;
|
||||
|
||||
struct TCurrentCollector
|
||||
{
|
||||
int CollectorsNo;
|
||||
double MinH;
|
||||
double MaxH;
|
||||
double CSW;
|
||||
double MinV;
|
||||
double MaxV;
|
||||
double InsetV;
|
||||
double MinPress;
|
||||
double MaxPress;
|
||||
} ;
|
||||
|
||||
#pragma option push -b-
|
||||
enum TPowerSource { NotDefined, InternalSource, Transducer, Generator, Accumulator, CurrentCollector,
|
||||
PowerCable, Heater };
|
||||
#pragma option pop
|
||||
|
||||
struct _mover__1
|
||||
{
|
||||
double MaxCapacity;
|
||||
TPowerSource RechargeSource;
|
||||
} ;
|
||||
|
||||
struct _mover__2
|
||||
{
|
||||
TPowerType PowerTrans;
|
||||
double SteamPressure;
|
||||
} ;
|
||||
|
||||
struct _mover__3
|
||||
{
|
||||
TGrateType Grate;
|
||||
TBoilerType Boiler;
|
||||
} ;
|
||||
|
||||
struct TPowerParameters
|
||||
{
|
||||
double MaxVoltage;
|
||||
double MaxCurrent;
|
||||
double IntR;
|
||||
TPowerSource SourceType;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
_mover__3 RHeater;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
_mover__2 RPowerCable;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
TCurrentCollector CollectorParameters;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
_mover__1 RAccumulator;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
TEngineTypes GeneratorEngine;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
double InputVoltage;
|
||||
|
||||
};
|
||||
struct
|
||||
{
|
||||
TPowerType PowerType;
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
} ;
|
||||
|
||||
struct TScheme
|
||||
{
|
||||
Byte Relay;
|
||||
double R;
|
||||
Byte Bn;
|
||||
Byte Mn;
|
||||
bool AutoSwitch;
|
||||
Byte ScndAct;
|
||||
} ;
|
||||
|
||||
typedef TScheme TSchemeTable[65];
|
||||
|
||||
struct TDEScheme
|
||||
{
|
||||
double RPM;
|
||||
double GenPower;
|
||||
double Umax;
|
||||
double Imax;
|
||||
} ;
|
||||
|
||||
typedef TDEScheme TDESchemeTable[33];
|
||||
|
||||
struct TShuntScheme
|
||||
{
|
||||
double Umin;
|
||||
double Umax;
|
||||
double Pmin;
|
||||
double Pmax;
|
||||
} ;
|
||||
|
||||
typedef TShuntScheme TShuntSchemeTable[33];
|
||||
|
||||
struct TMPTRelay
|
||||
{
|
||||
double Iup;
|
||||
double Idown;
|
||||
} ;
|
||||
|
||||
typedef TMPTRelay TMPTRelayTable[8];
|
||||
|
||||
struct TMotorParameters
|
||||
{
|
||||
double mfi;
|
||||
double mIsat;
|
||||
double mfi0;
|
||||
double fi;
|
||||
double Isat;
|
||||
double fi0;
|
||||
bool AutoSwitch;
|
||||
} ;
|
||||
|
||||
struct TSecuritySystem
|
||||
{
|
||||
Byte SystemType;
|
||||
double AwareDelay;
|
||||
double AwareMinSpeed;
|
||||
double SoundSignalDelay;
|
||||
double EmergencyBrakeDelay;
|
||||
Byte Status;
|
||||
double SystemTimer;
|
||||
double SystemSoundCATimer;
|
||||
double SystemSoundSHPTimer;
|
||||
double SystemBrakeCATimer;
|
||||
double SystemBrakeSHPTimer;
|
||||
double SystemBrakeCATestTimer;
|
||||
int VelocityAllowed;
|
||||
int NextVelocityAllowed;
|
||||
bool RadioStop;
|
||||
} ;
|
||||
|
||||
struct TTransmision
|
||||
{
|
||||
Byte NToothM;
|
||||
Byte NToothW;
|
||||
double Ratio;
|
||||
} ;
|
||||
|
||||
#pragma option push -b-
|
||||
enum TCouplerType { NoCoupler, Articulated, Bare, Chain, Screw, Automatic };
|
||||
#pragma option pop
|
||||
|
||||
class DELPHICLASS T_MoverParameters;
|
||||
struct TCoupling;
|
||||
class PASCALIMPLEMENTATION T_MoverParameters : public System::TObject
|
||||
{
|
||||
typedef System::TObject inherited;
|
||||
|
||||
public:
|
||||
double dMoveLen;
|
||||
AnsiString filename;
|
||||
Byte CategoryFlag;
|
||||
AnsiString TypeName;
|
||||
int TrainType;
|
||||
TEngineTypes EngineType;
|
||||
TPowerParameters EnginePowerSource;
|
||||
TPowerParameters SystemPowerSource;
|
||||
TPowerParameters HeatingPowerSource;
|
||||
TPowerParameters AlterHeatPowerSource;
|
||||
TPowerParameters LightPowerSource;
|
||||
TPowerParameters AlterLightPowerSource;
|
||||
double Vmax;
|
||||
double Mass;
|
||||
double Power;
|
||||
double Mred;
|
||||
double TotalMass;
|
||||
double HeatingPower;
|
||||
double LightPower;
|
||||
double BatteryVoltage;
|
||||
bool Battery;
|
||||
bool EpFuse;
|
||||
bool Signalling;
|
||||
bool DoorSignalling;
|
||||
bool Radio;
|
||||
double NominalBatteryVoltage;
|
||||
TDimension Dim;
|
||||
double Cx;
|
||||
double Floor;
|
||||
double WheelDiameter;
|
||||
double WheelDiameterL;
|
||||
double WheelDiameterT;
|
||||
double TrackW;
|
||||
double AxleInertialMoment;
|
||||
AnsiString AxleArangement;
|
||||
Byte NPoweredAxles;
|
||||
Byte NAxles;
|
||||
Byte BearingType;
|
||||
double ADist;
|
||||
double BDist;
|
||||
Byte NBpA;
|
||||
int SandCapacity;
|
||||
TBrakeSystem BrakeSystem;
|
||||
TBrakeSubSystem BrakeSubsystem;
|
||||
TBrakeValve BrakeValve;
|
||||
TBrakeHandle BrakeHandle;
|
||||
TBrakeHandle BrakeLocHandle;
|
||||
double MBPM;
|
||||
Hamulce::TBrake* Hamulec;
|
||||
Hamulce::THandle* Handle;
|
||||
Hamulce::THandle* LocHandle;
|
||||
Hamulce::TReservoir* Pipe;
|
||||
Hamulce::TReservoir* Pipe2;
|
||||
TLocalBrake LocalBrake;
|
||||
TBrakePressure BrakePressureTable[13];
|
||||
TBrakePressure BrakePressureActual;
|
||||
Byte ASBType;
|
||||
Byte TurboTest;
|
||||
double MaxBrakeForce;
|
||||
double MaxBrakePress[5];
|
||||
double P2FTrans;
|
||||
double TrackBrakeForce;
|
||||
Byte BrakeMethod;
|
||||
double HighPipePress;
|
||||
double LowPipePress;
|
||||
double DeltaPipePress;
|
||||
double CntrlPipePress;
|
||||
double BrakeVolume;
|
||||
double BrakeVVolume;
|
||||
double VeselVolume;
|
||||
int BrakeCylNo;
|
||||
double BrakeCylRadius;
|
||||
double BrakeCylDist;
|
||||
double BrakeCylMult[3];
|
||||
Byte LoadFlag;
|
||||
double BrakeCylSpring;
|
||||
double BrakeSlckAdj;
|
||||
double BrakeRigEff;
|
||||
double RapidMult;
|
||||
int BrakeValveSize;
|
||||
AnsiString BrakeValveParams;
|
||||
double Spg;
|
||||
double MinCompressor;
|
||||
double MaxCompressor;
|
||||
double CompressorSpeed;
|
||||
double BrakeDelay[4];
|
||||
Byte BrakeCtrlPosNo;
|
||||
Byte MainCtrlPosNo;
|
||||
Byte ScndCtrlPosNo;
|
||||
bool ScndInMain;
|
||||
bool MBrake;
|
||||
TSecuritySystem SecuritySystem;
|
||||
TScheme RList[65];
|
||||
int RlistSize;
|
||||
TMotorParameters MotorParam[11];
|
||||
TTransmision Transmision;
|
||||
double NominalVoltage;
|
||||
double WindingRes;
|
||||
double u;
|
||||
double CircuitRes;
|
||||
int IminLo;
|
||||
int IminHi;
|
||||
int ImaxLo;
|
||||
int ImaxHi;
|
||||
double nmax;
|
||||
double InitialCtrlDelay;
|
||||
double CtrlDelay;
|
||||
double CtrlDownDelay;
|
||||
Byte FastSerialCircuit;
|
||||
Byte AutoRelayType;
|
||||
bool CoupledCtrl;
|
||||
bool IsCoupled;
|
||||
Byte DynamicBrakeType;
|
||||
Byte RVentType;
|
||||
double RVentnmax;
|
||||
double RVentCutOff;
|
||||
int CompressorPower;
|
||||
int SmallCompressorPower;
|
||||
double dizel_Mmax;
|
||||
double dizel_nMmax;
|
||||
double dizel_Mnmax;
|
||||
double dizel_nmax;
|
||||
double dizel_nominalfill;
|
||||
double dizel_Mstand;
|
||||
double dizel_nmax_cutoff;
|
||||
double dizel_nmin;
|
||||
double dizel_minVelfullengage;
|
||||
double dizel_AIM;
|
||||
double dizel_engageDia;
|
||||
double dizel_engageMaxForce;
|
||||
double dizel_engagefriction;
|
||||
double AnPos;
|
||||
bool AnalogCtrl;
|
||||
bool AnMainCtrl;
|
||||
bool ShuntModeAllow;
|
||||
bool ShuntMode;
|
||||
bool Flat;
|
||||
double Vhyp;
|
||||
TDEScheme DElist[33];
|
||||
double Vadd;
|
||||
TMPTRelay MPTRelay[8];
|
||||
Byte RelayType;
|
||||
TShuntScheme SST[33];
|
||||
double PowerCorRatio;
|
||||
double Ftmax;
|
||||
double eimc[21];
|
||||
int MaxLoad;
|
||||
AnsiString LoadAccepted;
|
||||
AnsiString LoadQuantity;
|
||||
double OverLoadFactor;
|
||||
double LoadSpeed;
|
||||
double UnLoadSpeed;
|
||||
Byte DoorOpenCtrl;
|
||||
Byte DoorCloseCtrl;
|
||||
double DoorStayOpen;
|
||||
bool DoorClosureWarning;
|
||||
double DoorOpenSpeed;
|
||||
double DoorCloseSpeed;
|
||||
double DoorMaxShiftL;
|
||||
double DoorMaxShiftR;
|
||||
Byte DoorOpenMethod;
|
||||
bool ScndS;
|
||||
TLocation Loc;
|
||||
TRotation Rot;
|
||||
AnsiString Name;
|
||||
TCoupling Couplers[2];
|
||||
double HVCouplers[2][2];
|
||||
int ScanCounter;
|
||||
bool EventFlag;
|
||||
Byte SoundFlag;
|
||||
double DistCounter;
|
||||
double V;
|
||||
double Vel;
|
||||
double AccS;
|
||||
double AccN;
|
||||
double AccV;
|
||||
double nrot;
|
||||
double EnginePower;
|
||||
double dL;
|
||||
double Fb;
|
||||
double Ff;
|
||||
double FTrain;
|
||||
double FStand;
|
||||
double FTotal;
|
||||
double UnitBrakeForce;
|
||||
double Ntotal;
|
||||
bool SlippingWheels;
|
||||
bool SandDose;
|
||||
double Sand;
|
||||
double BrakeSlippingTimer;
|
||||
double dpBrake;
|
||||
double dpPipe;
|
||||
double dpMainValve;
|
||||
double dpLocalValve;
|
||||
double ScndPipePress;
|
||||
double BrakePress;
|
||||
double LocBrakePress;
|
||||
double PipeBrakePress;
|
||||
double PipePress;
|
||||
double EqvtPipePress;
|
||||
double Volume;
|
||||
double CompressedVolume;
|
||||
double PantVolume;
|
||||
double Compressor;
|
||||
bool CompressorFlag;
|
||||
bool PantCompFlag;
|
||||
bool CompressorAllow;
|
||||
bool ConverterFlag;
|
||||
bool ConverterAllow;
|
||||
int BrakeCtrlPos;
|
||||
double BrakeCtrlPosR;
|
||||
double BrakeCtrlPos2;
|
||||
Byte LocalBrakePos;
|
||||
Byte ManualBrakePos;
|
||||
double LocalBrakePosA;
|
||||
Byte BrakeStatus;
|
||||
bool EmergencyBrakeFlag;
|
||||
Byte BrakeDelayFlag;
|
||||
Byte BrakeDelays;
|
||||
bool DynamicBrakeFlag;
|
||||
double LimPipePress;
|
||||
double ActFlowSpeed;
|
||||
Byte DamageFlag;
|
||||
Byte DerailReason;
|
||||
TCommand CommandIn;
|
||||
AnsiString CommandOut;
|
||||
AnsiString CommandLast;
|
||||
double ValueOut;
|
||||
TTrackShape RunningShape;
|
||||
TTrackParam RunningTrack;
|
||||
double OffsetTrackH;
|
||||
double OffsetTrackV;
|
||||
bool Mains;
|
||||
Byte MainCtrlPos;
|
||||
Byte ScndCtrlPos;
|
||||
int ActiveDir;
|
||||
int CabNo;
|
||||
int DirAbsolute;
|
||||
int ActiveCab;
|
||||
double LastSwitchingTime;
|
||||
bool DepartureSignal;
|
||||
bool InsideConsist;
|
||||
TTractionParam RunningTraction;
|
||||
double enrot;
|
||||
double Im;
|
||||
double Itot;
|
||||
double IHeating;
|
||||
double ITraction;
|
||||
double TotalCurrent;
|
||||
double Mm;
|
||||
double Mw;
|
||||
double Fw;
|
||||
double Ft;
|
||||
int Imin;
|
||||
int Imax;
|
||||
double Voltage;
|
||||
Byte MainCtrlActualPos;
|
||||
Byte ScndCtrlActualPos;
|
||||
bool DelayCtrlFlag;
|
||||
double LastRelayTime;
|
||||
bool AutoRelayFlag;
|
||||
bool FuseFlag;
|
||||
bool ConvOvldFlag;
|
||||
bool StLinFlag;
|
||||
bool ResistorsFlag;
|
||||
double RventRot;
|
||||
bool UnBrake;
|
||||
double PantPress;
|
||||
bool s_CAtestebrake;
|
||||
double dizel_fill;
|
||||
double dizel_engagestate;
|
||||
double dizel_engage;
|
||||
double dizel_automaticgearstatus;
|
||||
bool dizel_enginestart;
|
||||
double dizel_engagedeltaomega;
|
||||
double eimv[21];
|
||||
double PulseForce;
|
||||
double PulseForceTimer;
|
||||
int PulseForceCount;
|
||||
double eAngle;
|
||||
int Load;
|
||||
AnsiString LoadType;
|
||||
Byte LoadStatus;
|
||||
double LastLoadChangeTime;
|
||||
bool DoorBlocked;
|
||||
bool DoorLeftOpened;
|
||||
bool DoorRightOpened;
|
||||
bool PantFrontUp;
|
||||
bool PantRearUp;
|
||||
bool PantFrontSP;
|
||||
bool PantRearSP;
|
||||
int PantFrontStart;
|
||||
int PantRearStart;
|
||||
double PantFrontVolt;
|
||||
double PantRearVolt;
|
||||
AnsiString PantSwitchType;
|
||||
AnsiString ConvSwitchType;
|
||||
bool Heating;
|
||||
int DoubleTr;
|
||||
bool PhysicActivation;
|
||||
double FrictConst1;
|
||||
double FrictConst2s;
|
||||
double FrictConst2d;
|
||||
double TotalMassxg;
|
||||
double __fastcall GetTrainsetVoltage(void);
|
||||
bool __fastcall Physic_ReActivation(void);
|
||||
double __fastcall LocalBrakeRatio(void);
|
||||
double __fastcall ManualBrakeRatio(void);
|
||||
double __fastcall PipeRatio(void);
|
||||
double __fastcall RealPipeRatio(void);
|
||||
double __fastcall BrakeVP(void);
|
||||
bool __fastcall DynamicBrakeSwitch(bool Switch);
|
||||
bool __fastcall SendCtrlBroadcast(AnsiString CtrlCommand, double ctrlvalue);
|
||||
bool __fastcall SendCtrlToNext(AnsiString CtrlCommand, double ctrlvalue, double dir);
|
||||
bool __fastcall CabActivisation(void);
|
||||
bool __fastcall CabDeactivisation(void);
|
||||
bool __fastcall IncMainCtrl(int CtrlSpeed);
|
||||
bool __fastcall DecMainCtrl(int CtrlSpeed);
|
||||
bool __fastcall IncScndCtrl(int CtrlSpeed);
|
||||
bool __fastcall DecScndCtrl(int CtrlSpeed);
|
||||
bool __fastcall AddPulseForce(int Multipler);
|
||||
bool __fastcall SandDoseOn(void);
|
||||
bool __fastcall SecuritySystemReset(void);
|
||||
void __fastcall SecuritySystemCheck(double dt);
|
||||
bool __fastcall BatterySwitch(bool State);
|
||||
bool __fastcall EpFuseSwitch(bool State);
|
||||
bool __fastcall IncBrakeLevelOld(void);
|
||||
bool __fastcall DecBrakeLevelOld(void);
|
||||
bool __fastcall IncLocalBrakeLevel(Byte CtrlSpeed);
|
||||
bool __fastcall DecLocalBrakeLevel(Byte CtrlSpeed);
|
||||
bool __fastcall IncLocalBrakeLevelFAST(void);
|
||||
bool __fastcall DecLocalBrakeLevelFAST(void);
|
||||
bool __fastcall IncManualBrakeLevel(Byte CtrlSpeed);
|
||||
bool __fastcall DecManualBrakeLevel(Byte CtrlSpeed);
|
||||
bool __fastcall EmergencyBrakeSwitch(bool Switch);
|
||||
bool __fastcall AntiSlippingBrake(void);
|
||||
bool __fastcall BrakeReleaser(Byte state);
|
||||
bool __fastcall SwitchEPBrake(Byte state);
|
||||
bool __fastcall AntiSlippingButton(void);
|
||||
bool __fastcall IncBrakePress(double &brake, double PressLimit, double dp);
|
||||
bool __fastcall DecBrakePress(double &brake, double PressLimit, double dp);
|
||||
bool __fastcall BrakeDelaySwitch(Byte BDS);
|
||||
bool __fastcall IncBrakeMult(void);
|
||||
bool __fastcall DecBrakeMult(void);
|
||||
void __fastcall UpdateBrakePressure(double dt);
|
||||
void __fastcall UpdatePipePressure(double dt);
|
||||
void __fastcall CompressorCheck(double dt);
|
||||
void __fastcall UpdateScndPipePressure(double dt);
|
||||
double __fastcall GetDVc(double dt);
|
||||
void __fastcall ComputeConstans(void);
|
||||
double __fastcall ComputeMass(void);
|
||||
double __fastcall Adhesive(double staticfriction);
|
||||
double __fastcall TractionForce(double dt);
|
||||
double __fastcall FrictionForce(double R, Byte TDamage);
|
||||
double __fastcall BrakeForce(const TTrackParam &Track);
|
||||
double __fastcall CouplerForce(Byte CouplerN, double dt);
|
||||
void __fastcall CollisionDetect(Byte CouplerN, double dt);
|
||||
double __fastcall ComputeRotatingWheel(double WForce, double dt, double n);
|
||||
bool __fastcall SetInternalCommand(AnsiString NewCommand, double NewValue1, double NewValue2);
|
||||
double __fastcall GetExternalCommand(AnsiString &Command);
|
||||
bool __fastcall RunCommand(AnsiString command, double CValue1, double CValue2);
|
||||
bool __fastcall RunInternalCommand(void);
|
||||
void __fastcall PutCommand(AnsiString NewCommand, double NewValue1, double NewValue2, const TLocation
|
||||
&NewLocation);
|
||||
bool __fastcall DirectionBackward(void);
|
||||
bool __fastcall MainSwitch(bool State);
|
||||
bool __fastcall ConverterSwitch(bool State);
|
||||
bool __fastcall CompressorSwitch(bool State);
|
||||
bool __fastcall FuseOn(void);
|
||||
bool __fastcall FuseFlagCheck(void);
|
||||
void __fastcall FuseOff(void);
|
||||
int __fastcall ShowCurrent(Byte AmpN);
|
||||
double __fastcall v2n(void);
|
||||
double __fastcall current(double n, double U);
|
||||
double __fastcall Momentum(double I);
|
||||
double __fastcall MomentumF(double I, double Iw, Byte SCP);
|
||||
bool __fastcall CutOffEngine(void);
|
||||
bool __fastcall MaxCurrentSwitch(bool State);
|
||||
bool __fastcall ResistorsFlagCheck(void);
|
||||
bool __fastcall MinCurrentSwitch(bool State);
|
||||
bool __fastcall AutoRelaySwitch(bool State);
|
||||
bool __fastcall AutoRelayCheck(void);
|
||||
bool __fastcall dizel_EngageSwitch(double state);
|
||||
bool __fastcall dizel_EngageChange(double dt);
|
||||
bool __fastcall dizel_AutoGearCheck(void);
|
||||
double __fastcall dizel_fillcheck(Byte mcp);
|
||||
double __fastcall dizel_Momentum(double dizel_fill, double n, double dt);
|
||||
bool __fastcall dizel_Update(double dt);
|
||||
bool __fastcall LoadingDone(double LSpeed, AnsiString LoadInit);
|
||||
void __fastcall ComputeTotalForce(double dt, double dt1, bool FullVer);
|
||||
double __fastcall ComputeMovement(double dt, double dt1, const TTrackShape &Shape, TTrackParam &Track
|
||||
, TTractionParam &ElectricTraction, const TLocation &NewLoc, TRotation &NewRot);
|
||||
double __fastcall FastComputeMovement(double dt, const TTrackShape &Shape, TTrackParam &Track, const
|
||||
TLocation &NewLoc, TRotation &NewRot);
|
||||
bool __fastcall ChangeOffsetH(double DeltaOffset);
|
||||
__fastcall T_MoverParameters(double VelInitial, AnsiString TypeNameInit, AnsiString NameInit, int LoadInitial
|
||||
, AnsiString LoadTypeInitial, int Cab);
|
||||
bool __fastcall LoadChkFile(AnsiString chkpath);
|
||||
bool __fastcall CheckLocomotiveParameters(bool ReadyFlag, int Dir);
|
||||
AnsiString __fastcall EngineDescription(int what);
|
||||
bool __fastcall DoorLeft(bool State);
|
||||
bool __fastcall DoorRight(bool State);
|
||||
bool __fastcall DoorBlockedFlag(void);
|
||||
bool __fastcall PantFront(bool State);
|
||||
bool __fastcall PantRear(bool State);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall T_MoverParameters(void) : System::TObject() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~T_MoverParameters(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct TCoupling
|
||||
{
|
||||
double SpringKB;
|
||||
double SpringKC;
|
||||
double beta;
|
||||
double DmaxB;
|
||||
double FmaxB;
|
||||
double DmaxC;
|
||||
double FmaxC;
|
||||
TCouplerType CouplerType;
|
||||
Byte CouplingFlag;
|
||||
int AllowedFlag;
|
||||
bool Render;
|
||||
double CoupleDist;
|
||||
T_MoverParameters* Connected;
|
||||
Byte ConnectedNr;
|
||||
double CForce;
|
||||
double Dist;
|
||||
bool CheckCollision;
|
||||
} ;
|
||||
|
||||
//-- var, const, procedure ---------------------------------------------------
|
||||
static const bool Go = true;
|
||||
static const bool Hold = false;
|
||||
static const Shortint ResArraySize = 0x40;
|
||||
static const Shortint MotorParametersArraySize = 0xa;
|
||||
static const Shortint maxcc = 0x4;
|
||||
static const Shortint LocalBrakePosNo = 0xa;
|
||||
static const Shortint MainBrakeMaxPos = 0xa;
|
||||
static const Shortint ManualBrakePosNo = 0x14;
|
||||
static const Shortint dtrack_railwear = 0x2;
|
||||
static const Shortint dtrack_freerail = 0x4;
|
||||
static const Shortint dtrack_thinrail = 0x8;
|
||||
static const Shortint dtrack_railbend = 0x10;
|
||||
static const Shortint dtrack_plants = 0x20;
|
||||
static const Shortint dtrack_nomove = 0x40;
|
||||
static const Byte dtrack_norail = 0x80;
|
||||
static const Shortint dtrain_thinwheel = 0x1;
|
||||
static const Shortint dtrain_loadshift = 0x1;
|
||||
static const Shortint dtrain_wheelwear = 0x2;
|
||||
static const Shortint dtrain_bearing = 0x4;
|
||||
static const Shortint dtrain_coupling = 0x8;
|
||||
static const Shortint dtrain_ventilator = 0x10;
|
||||
static const Shortint dtrain_loaddamage = 0x10;
|
||||
static const Shortint dtrain_engine = 0x20;
|
||||
static const Shortint dtrain_loaddestroyed = 0x20;
|
||||
static const Shortint dtrain_axle = 0x40;
|
||||
static const Byte dtrain_out = 0x80;
|
||||
#define p_elengproblem (1.000000E-02)
|
||||
#define p_elengdamage (1.000000E-01)
|
||||
#define p_coupldmg (2.000000E-02)
|
||||
#define p_derail (1.000000E-03)
|
||||
#define p_accn (1.000000E-01)
|
||||
#define p_slippdmg (1.000000E-03)
|
||||
static const Shortint ctrain_virtual = 0x0;
|
||||
static const Shortint ctrain_coupler = 0x1;
|
||||
static const Shortint ctrain_pneumatic = 0x2;
|
||||
static const Shortint ctrain_controll = 0x4;
|
||||
static const Shortint ctrain_power = 0x8;
|
||||
static const Shortint ctrain_passenger = 0x10;
|
||||
static const Shortint ctrain_scndpneumatic = 0x20;
|
||||
static const Shortint ctrain_heating = 0x40;
|
||||
static const Byte ctrain_depot = 0x80;
|
||||
static const Shortint dbrake_none = 0x0;
|
||||
static const Shortint dbrake_passive = 0x1;
|
||||
static const Shortint dbrake_switch = 0x2;
|
||||
static const Shortint dbrake_reversal = 0x4;
|
||||
static const Shortint dbrake_automatic = 0x8;
|
||||
static const Shortint s_waiting = 0x1;
|
||||
static const Shortint s_aware = 0x2;
|
||||
static const Shortint s_active = 0x4;
|
||||
static const Shortint s_CAalarm = 0x8;
|
||||
static const Shortint s_SHPalarm = 0x10;
|
||||
static const Shortint s_CAebrake = 0x20;
|
||||
static const Shortint s_SHPebrake = 0x40;
|
||||
static const Byte s_CAtest = 0x80;
|
||||
static const Shortint sound_none = 0x0;
|
||||
static const Shortint sound_loud = 0x1;
|
||||
static const Shortint sound_couplerstretch = 0x2;
|
||||
static const Shortint sound_bufferclamp = 0x4;
|
||||
static const Shortint sound_bufferbump = 0x8;
|
||||
static const Shortint sound_relay = 0x10;
|
||||
static const Shortint sound_manyrelay = 0x20;
|
||||
static const Shortint sound_brakeacc = 0x40;
|
||||
extern PACKAGE bool PhysicActivationFlag;
|
||||
static const Shortint dt_Default = 0x0;
|
||||
static const Shortint dt_EZT = 0x1;
|
||||
static const Shortint dt_ET41 = 0x2;
|
||||
static const Shortint dt_ET42 = 0x4;
|
||||
static const Shortint dt_PseudoDiesel = 0x8;
|
||||
static const Shortint dt_ET22 = 0x10;
|
||||
static const Shortint dt_SN61 = 0x20;
|
||||
static const Shortint dt_EP05 = 0x40;
|
||||
static const Byte dt_ET40 = 0x80;
|
||||
static const Word dt_181 = 0x100;
|
||||
static const Shortint eimc_s_dfic = 0x0;
|
||||
static const Shortint eimc_s_dfmax = 0x1;
|
||||
static const Shortint eimc_s_p = 0x2;
|
||||
static const Shortint eimc_s_cfu = 0x3;
|
||||
static const Shortint eimc_s_cim = 0x4;
|
||||
static const Shortint eimc_s_icif = 0x5;
|
||||
static const Shortint eimc_f_Uzmax = 0x7;
|
||||
static const Shortint eimc_f_Uzh = 0x8;
|
||||
static const Shortint eimc_f_DU = 0x9;
|
||||
static const Shortint eimc_f_I0 = 0xa;
|
||||
static const Shortint eimc_f_cfu = 0xb;
|
||||
static const Shortint eimc_p_F0 = 0xd;
|
||||
static const Shortint eimc_p_a1 = 0xe;
|
||||
static const Shortint eimc_p_Pmax = 0xf;
|
||||
static const Shortint eimc_p_Fh = 0x10;
|
||||
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 eimv_FMAXMAX = 0x0;
|
||||
static const Shortint eimv_Fmax = 0x1;
|
||||
static const Shortint eimv_ks = 0x2;
|
||||
static const Shortint eimv_df = 0x3;
|
||||
static const Shortint eimv_fp = 0x4;
|
||||
static const Shortint eimv_U = 0x5;
|
||||
static const Shortint eimv_pole = 0x6;
|
||||
static const Shortint eimv_Ic = 0x7;
|
||||
static const Shortint eimv_If = 0x8;
|
||||
static const Shortint eimv_M = 0x9;
|
||||
static const Shortint eimv_Fr = 0xa;
|
||||
static const Shortint eimv_Ipoj = 0xb;
|
||||
static const Shortint eimv_Pm = 0xc;
|
||||
static const Shortint eimv_Pe = 0xd;
|
||||
static const Shortint eimv_eta = 0xe;
|
||||
static const Shortint eimv_fkr = 0xf;
|
||||
static const Shortint eimv_Uzsmax = 0x10;
|
||||
static const Shortint eimv_Pmax = 0x11;
|
||||
static const Shortint eimv_Fzad = 0x12;
|
||||
static const Shortint eimv_Imax = 0x13;
|
||||
extern PACKAGE double __fastcall Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension
|
||||
&Dim1, const TDimension &Dim2);
|
||||
|
||||
} /* namespace _mover */
|
||||
#if !defined(NO_IMPLICIT_NAMESPACE_USE)
|
||||
using namespace _mover;
|
||||
#endif
|
||||
#pragma option pop // -w-
|
||||
#pragma option pop // -Vx
|
||||
|
||||
#pragma delphiheader end.
|
||||
//-- end unit ----------------------------------------------------------------
|
||||
#endif // _mover
|
||||
7380
McZapkie/_mover.pas
Normal file
7380
McZapkie/_mover.pas
Normal file
File diff suppressed because it is too large
Load Diff
232
McZapkie/friction.hpp
Normal file
232
McZapkie/friction.hpp
Normal file
@@ -0,0 +1,232 @@
|
||||
// Borland C++ Builder
|
||||
// Copyright (c) 1995, 1999 by Borland International
|
||||
// All rights reserved
|
||||
|
||||
// (DO NOT EDIT: machine generated header) 'friction.pas' rev: 5.00
|
||||
|
||||
#ifndef frictionHPP
|
||||
#define frictionHPP
|
||||
|
||||
#pragma delphiheader begin
|
||||
#pragma option push -w-
|
||||
#pragma option push -Vx
|
||||
#include <SysUtils.hpp> // Pascal unit
|
||||
#include <mctools.hpp> // Pascal unit
|
||||
#include <SysInit.hpp> // Pascal unit
|
||||
#include <System.hpp> // Pascal unit
|
||||
|
||||
//-- user supplied -----------------------------------------------------------
|
||||
|
||||
namespace Friction
|
||||
{
|
||||
//-- type declarations -------------------------------------------------------
|
||||
class DELPHICLASS TFricMat;
|
||||
class PASCALIMPLEMENTATION TFricMat : public System::TObject
|
||||
{
|
||||
typedef System::TObject inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetFC(double N, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TFricMat(void) : System::TObject() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TFricMat(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TP10Bg;
|
||||
class PASCALIMPLEMENTATION TP10Bg : public TFricMat
|
||||
{
|
||||
typedef TFricMat inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetFC(double N, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TP10Bg(void) : TFricMat() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TP10Bg(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TP10Bgu;
|
||||
class PASCALIMPLEMENTATION TP10Bgu : public TFricMat
|
||||
{
|
||||
typedef TFricMat inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetFC(double N, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TP10Bgu(void) : TFricMat() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TP10Bgu(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TP10yBg;
|
||||
class PASCALIMPLEMENTATION TP10yBg : public TFricMat
|
||||
{
|
||||
typedef TFricMat inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetFC(double N, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TP10yBg(void) : TFricMat() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TP10yBg(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TP10yBgu;
|
||||
class PASCALIMPLEMENTATION TP10yBgu : public TFricMat
|
||||
{
|
||||
typedef TFricMat inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetFC(double N, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TP10yBgu(void) : TFricMat() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TP10yBgu(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TP10;
|
||||
class PASCALIMPLEMENTATION TP10 : public TFricMat
|
||||
{
|
||||
typedef TFricMat inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetFC(double N, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TP10(void) : TFricMat() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TP10(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TFR513;
|
||||
class PASCALIMPLEMENTATION TFR513 : public TFricMat
|
||||
{
|
||||
typedef TFricMat inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetFC(double N, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TFR513(void) : TFricMat() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TFR513(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TFR510;
|
||||
class PASCALIMPLEMENTATION TFR510 : public TFricMat
|
||||
{
|
||||
typedef TFricMat inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetFC(double N, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TFR510(void) : TFricMat() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TFR510(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TCosid;
|
||||
class PASCALIMPLEMENTATION TCosid : public TFricMat
|
||||
{
|
||||
typedef TFricMat inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetFC(double N, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TCosid(void) : TFricMat() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TCosid(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TDisk1;
|
||||
class PASCALIMPLEMENTATION TDisk1 : public TFricMat
|
||||
{
|
||||
typedef TFricMat inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetFC(double N, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TDisk1(void) : TFricMat() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TDisk1(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TDisk2;
|
||||
class PASCALIMPLEMENTATION TDisk2 : public TFricMat
|
||||
{
|
||||
typedef TFricMat inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetFC(double N, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TDisk2(void) : TFricMat() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TDisk2(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
//-- var, const, procedure ---------------------------------------------------
|
||||
|
||||
} /* namespace Friction */
|
||||
#if !defined(NO_IMPLICIT_NAMESPACE_USE)
|
||||
using namespace Friction;
|
||||
#endif
|
||||
#pragma option pop // -w-
|
||||
#pragma option pop // -Vx
|
||||
|
||||
#pragma delphiheader end.
|
||||
//-- end unit ----------------------------------------------------------------
|
||||
#endif // friction
|
||||
174
McZapkie/friction.pas
Normal file
174
McZapkie/friction.pas
Normal file
@@ -0,0 +1,174 @@
|
||||
unit friction; {wspolczynnik tarcia roznych materialow}
|
||||
|
||||
(*
|
||||
MaSzyna EU07 - SPKS
|
||||
Friction coefficient.
|
||||
Copyright (C) 2007-2013 Maciej Cierniak
|
||||
*)
|
||||
|
||||
|
||||
(*
|
||||
(C) youBy
|
||||
Co brakuje:
|
||||
- hamulce tarczowe
|
||||
- kompozyty
|
||||
*)
|
||||
(*
|
||||
Zrobione:
|
||||
1) zadeklarowane niektore typy
|
||||
2) wzor jubaja na tarcie wstawek Bg i Bgu z zeliwa P10
|
||||
3) hamulec tarczowy marki 152A ;)
|
||||
*)
|
||||
|
||||
interface
|
||||
|
||||
//uses hamulce;
|
||||
uses mctools,sysutils;
|
||||
|
||||
TYPE
|
||||
|
||||
TFricMat = class
|
||||
public
|
||||
function GetFC(N, Vel: real): real; virtual;
|
||||
end;
|
||||
|
||||
TP10Bg = class(TFricMat)
|
||||
public
|
||||
function GetFC(N, Vel: real): real; override;
|
||||
end;
|
||||
|
||||
TP10Bgu = class(TFricMat)
|
||||
public
|
||||
function GetFC(N, Vel: real): real; override;
|
||||
end;
|
||||
|
||||
TP10yBg = class(TFricMat)
|
||||
public
|
||||
function GetFC(N, Vel: real): real; override;
|
||||
end;
|
||||
|
||||
TP10yBgu = class(TFricMat)
|
||||
public
|
||||
function GetFC(N, Vel: real): real; override;
|
||||
end;
|
||||
|
||||
TP10 = class(TFricMat)
|
||||
public
|
||||
function GetFC(N, Vel: real): real; override;
|
||||
end;
|
||||
|
||||
TFR513 = class(TFricMat)
|
||||
public
|
||||
function GetFC(N, Vel: real): real; override;
|
||||
end;
|
||||
|
||||
TFR510 = class(TFricMat)
|
||||
public
|
||||
function GetFC(N, Vel: real): real; override;
|
||||
end;
|
||||
|
||||
TCosid = class(TFricMat)
|
||||
public
|
||||
function GetFC(N, Vel: real): real; override;
|
||||
end;
|
||||
|
||||
TDisk1 = class(TFricMat)
|
||||
public
|
||||
function GetFC(N, Vel: real): real; override;
|
||||
end;
|
||||
|
||||
TDisk2 = class(TFricMat)
|
||||
public
|
||||
function GetFC(N, Vel: real): real; override;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
function TFricMat.GetFC(N, Vel: real): real;
|
||||
begin
|
||||
GetFC:=1;
|
||||
end;
|
||||
|
||||
function TP10Bg.GetFC(N, Vel: real): real;
|
||||
begin
|
||||
// GetFC:=0.60*((1.6*N+100)/(8.0*N+100))*((Vel+100)/(5*Vel+100))*(1.0032-0.0007*N-0.0001*N*N);
|
||||
// GetFC:=47/(2*Vel+100)*(2.145-0.0538*N+0.00074*N*N-0.00000536*N*N*N)/2.145;
|
||||
// GetFC:=46/(2*Vel+100)*(11.33-0.105*N)/(11.33+0.179*N);
|
||||
// GetFC:=49/(2*Vel+100)*(13.08-0.083*N)/(12.94+0.285*N);
|
||||
//if Vel<20 then Vel:=20;
|
||||
// Vel:= Vel-20;
|
||||
// GetFC:=0.52*((1*Vel+100)/(5.0*Vel+100))*(13.08-0.083*N)/(12.94+0.285*N);
|
||||
// GetFC:=Min0R(0.67*(1*(277-2.66*Vel)/(100+2.1*Vel)+0.23*(-686+8.27*Vel)/(100+1.16*Vel))*(13.08-0.083*N)/(12.94+0.285*N),0.4);
|
||||
GetFC:=exp(-0.022*N)*(0.19-0.095*exp(-Vel/25.7))+0.384*exp(-Vel/25.7)-0.028;
|
||||
end;
|
||||
|
||||
function TP10Bgu.GetFC(N, Vel: real): real;
|
||||
begin
|
||||
// GetFC:=0.60*((1.6*N+100)/(8.0*N+100))*((Vel+100)/(5*Vel+100));
|
||||
// GetFC:=47/(2*Vel+100)*(2.137-0.0514*N+0.000832*N*N-0.00000604*N*N*N)/2.137;
|
||||
// GetFC:=0.49*100/(2*Vel+100)*(11.33-0.013*N)/(11.33+0.280*N);
|
||||
// GetFC:=0.52*((Vel+100)/(5.0*Vel+100))*(11.33-0.013*N)/(11.33+0.280*N);
|
||||
//if Vel<20 then Vel:=20;
|
||||
// Vel:= Vel-20;
|
||||
// GetFC:=0.52*((0.0*Vel+120)/(5*Vel+100))*(11.33-0.013*N)/(11.33+0.280*N);
|
||||
// GetFC:=0.49*100/(3*Vel+100)*(11.33-0.013*N)/(11.33+0.280*N);
|
||||
// GetFC:=Min0R(0.67*(1*(277-2.66*Vel)/(100+2.1*Vel)+0.23*(-686+8.27*Vel)/(100+1.16*Vel))*(11.33-0.013*N)/(11.33+0.280*N),0.4);
|
||||
GetFC:=exp(-0.017*N)*(0.18-0.09*exp(-Vel/25.7))+0.381*exp(-Vel/25.7)-0.022;//0.05*exp(-0.2*N);
|
||||
end;
|
||||
|
||||
function TP10yBg.GetFC(N, Vel: real): real;
|
||||
var A,C,u0, V0: real;
|
||||
begin
|
||||
A:=2.135*exp(-0.03726*N)-0.5;
|
||||
C:=0.353-A*0.029;
|
||||
u0:=0.41-C;
|
||||
V0:=25.7+20*A;
|
||||
GetFC:=(u0+C*exp(-Vel/V0));
|
||||
end;
|
||||
|
||||
function TP10yBgu.GetFC(N, Vel: real): real;
|
||||
var A,C,u0, V0: real;
|
||||
begin
|
||||
A:=1.68*exp(-0.02735*N)-0.5;
|
||||
C:=0.353-A*0.044;
|
||||
u0:=0.41-C;
|
||||
V0:=25.7+21*A;
|
||||
GetFC:=(u0+C*exp(-Vel/V0));
|
||||
end;
|
||||
|
||||
function TP10.GetFC(N, Vel: real): real;
|
||||
begin
|
||||
GetFC:=0.60*((1.6*N+100)/(8.0*N+100))*((Vel+100)/(5*Vel+100));
|
||||
// GetFC:=43/(2*Vel+100)*(2.145-0.0538*N+0.00074*N*N-0.00000536*N*N*N)/2.145
|
||||
end;
|
||||
|
||||
|
||||
function TFR513.GetFC(N, Vel: real): real;
|
||||
begin
|
||||
GetFC:=0.3-Vel*0.00081;
|
||||
// GetFC:=43/(2*Vel+100)*(2.145-0.0538*N+0.00074*N*N-0.00000536*N*N*N)/2.145
|
||||
end;
|
||||
|
||||
function TCosid.GetFC(N, Vel: real): real;
|
||||
begin
|
||||
GetFC:=0.27;
|
||||
end;
|
||||
|
||||
function TDisk1.GetFC(N, Vel: real): real;
|
||||
begin
|
||||
GetFC:=0.2375+0.000885*N-0.000345*N*N;
|
||||
end;
|
||||
|
||||
function TDisk2.GetFC(N, Vel: real): real;
|
||||
begin
|
||||
GetFC:=0.27;
|
||||
end;
|
||||
|
||||
function TFR510.GetFC(N, Vel: real): real;
|
||||
begin
|
||||
GetFC:=0.15;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
841
McZapkie/hamulce.hpp
Normal file
841
McZapkie/hamulce.hpp
Normal file
@@ -0,0 +1,841 @@
|
||||
// Borland C++ Builder
|
||||
// Copyright (c) 1995, 1999 by Borland International
|
||||
// All rights reserved
|
||||
|
||||
// (DO NOT EDIT: machine generated header) 'hamulce.pas' rev: 5.00
|
||||
|
||||
#ifndef hamulceHPP
|
||||
#define hamulceHPP
|
||||
|
||||
#pragma delphiheader begin
|
||||
#pragma option push -w-
|
||||
#pragma option push -Vx
|
||||
#include <friction.hpp> // Pascal unit
|
||||
#include <SysUtils.hpp> // Pascal unit
|
||||
#include <mctools.hpp> // Pascal unit
|
||||
#include <SysInit.hpp> // Pascal unit
|
||||
#include <System.hpp> // Pascal unit
|
||||
|
||||
//-- user supplied -----------------------------------------------------------
|
||||
|
||||
namespace Hamulce
|
||||
{
|
||||
//-- type declarations -------------------------------------------------------
|
||||
class DELPHICLASS TReservoir;
|
||||
class PASCALIMPLEMENTATION TReservoir : public System::TObject
|
||||
{
|
||||
typedef System::TObject inherited;
|
||||
|
||||
protected:
|
||||
double Cap;
|
||||
double Vol;
|
||||
double dVol;
|
||||
|
||||
public:
|
||||
__fastcall TReservoir(void);
|
||||
void __fastcall CreateCap(double Capacity);
|
||||
void __fastcall CreatePress(double Press);
|
||||
virtual double __fastcall pa(void);
|
||||
virtual double __fastcall P(void);
|
||||
void __fastcall Flow(double dv);
|
||||
void __fastcall Act(void);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TReservoir(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef TReservoir* *PReservoir;
|
||||
|
||||
class DELPHICLASS TBrakeCyl;
|
||||
class PASCALIMPLEMENTATION TBrakeCyl : public TReservoir
|
||||
{
|
||||
typedef TReservoir inherited;
|
||||
|
||||
public:
|
||||
virtual double __fastcall pa(void);
|
||||
virtual double __fastcall P(void);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TReservoir.Create */ inline __fastcall TBrakeCyl(void) : TReservoir() { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TBrakeCyl(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TBrake;
|
||||
class PASCALIMPLEMENTATION TBrake : public System::TObject
|
||||
{
|
||||
typedef System::TObject inherited;
|
||||
|
||||
protected:
|
||||
TReservoir* BrakeCyl;
|
||||
TReservoir* BrakeRes;
|
||||
TReservoir* ValveRes;
|
||||
Byte BCN;
|
||||
double BCM;
|
||||
double BCA;
|
||||
Byte BrakeDelays;
|
||||
Byte BrakeDelayFlag;
|
||||
Friction::TFricMat* FM;
|
||||
double MaxBP;
|
||||
Byte BA;
|
||||
Byte NBpA;
|
||||
double SizeBR;
|
||||
double SizeBC;
|
||||
bool DCV;
|
||||
double ASBP;
|
||||
Byte BrakeStatus;
|
||||
Byte SoundFlag;
|
||||
|
||||
public:
|
||||
__fastcall TBrake(double i_mbp, double i_bcr, double i_bcd, double i_brc, Byte i_bcn, Byte i_BD, Byte
|
||||
i_mat, Byte i_ba, Byte i_nbpa);
|
||||
virtual double __fastcall GetFC(double Vel, double N);
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
double __fastcall GetBCF(void);
|
||||
virtual double __fastcall GetHPFlow(double HP, double dt);
|
||||
virtual double __fastcall GetBCP(void);
|
||||
double __fastcall GetBRP(void);
|
||||
double __fastcall GetVRP(void);
|
||||
virtual double __fastcall GetCRP(void);
|
||||
virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF);
|
||||
bool __fastcall SetBDF(Byte nBDF);
|
||||
void __fastcall Releaser(Byte state);
|
||||
virtual void __fastcall SetEPS(double nEPS);
|
||||
void __fastcall ASB(Byte state);
|
||||
Byte __fastcall GetStatus(void);
|
||||
void __fastcall SetASBP(double press);
|
||||
virtual void __fastcall ForceEmptiness(void);
|
||||
Byte __fastcall GetSoundFlag(void);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TBrake(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TWest;
|
||||
class PASCALIMPLEMENTATION TWest : public TBrake
|
||||
{
|
||||
typedef TBrake inherited;
|
||||
|
||||
private:
|
||||
double LBP;
|
||||
double dVP;
|
||||
double EPS;
|
||||
double TareM;
|
||||
double LoadM;
|
||||
double TareBP;
|
||||
double LoadC;
|
||||
|
||||
public:
|
||||
void __fastcall SetLBP(double P);
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF);
|
||||
virtual double __fastcall GetHPFlow(double HP, double dt);
|
||||
void __fastcall PLC(double mass);
|
||||
virtual void __fastcall SetEPS(double nEPS);
|
||||
void __fastcall SetLP(double TM, double LM, double TBP);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TWest(double i_mbp, double i_bcr, double i_bcd, double i_brc,
|
||||
Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
|
||||
, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TWest(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TESt;
|
||||
class PASCALIMPLEMENTATION TESt : public TBrake
|
||||
{
|
||||
typedef TBrake inherited;
|
||||
|
||||
private:
|
||||
TReservoir* CntrlRes;
|
||||
double BVM;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
void __fastcall EStParams(double i_crc);
|
||||
virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF);
|
||||
virtual double __fastcall GetCRP(void);
|
||||
void __fastcall CheckState(double BCP, double &dV1);
|
||||
void __fastcall CheckReleaser(double dt);
|
||||
double __fastcall CVs(double bp);
|
||||
double __fastcall BVs(double BCP);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TESt(double i_mbp, double i_bcr, double i_bcd, double i_brc,
|
||||
Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
|
||||
, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TESt(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TESt3;
|
||||
class PASCALIMPLEMENTATION TESt3 : public TESt
|
||||
{
|
||||
typedef TESt inherited;
|
||||
|
||||
private:
|
||||
double CylFlowSpeed[2][2];
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TESt3(double i_mbp, double i_bcr, double i_bcd, double i_brc,
|
||||
Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TESt(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
|
||||
, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TESt3(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TESt3AL2;
|
||||
class PASCALIMPLEMENTATION TESt3AL2 : public TESt3
|
||||
{
|
||||
typedef TESt3 inherited;
|
||||
|
||||
private:
|
||||
double TareM;
|
||||
double LoadM;
|
||||
double TareBP;
|
||||
double LoadC;
|
||||
|
||||
public:
|
||||
TReservoir* ImplsRes;
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
void __fastcall PLC(double mass);
|
||||
void __fastcall SetLP(double TM, double LM, double TBP);
|
||||
virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TESt3AL2(double i_mbp, double i_bcr, double i_bcd, double i_brc
|
||||
, Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TESt3(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
|
||||
, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TESt3AL2(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TESt4R;
|
||||
class PASCALIMPLEMENTATION TESt4R : public TESt
|
||||
{
|
||||
typedef TESt inherited;
|
||||
|
||||
private:
|
||||
bool RapidStatus;
|
||||
double RapidTemp;
|
||||
|
||||
public:
|
||||
TReservoir* ImplsRes;
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TESt4R(double i_mbp, double i_bcr, double i_bcd, double i_brc
|
||||
, Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TESt(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
|
||||
, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TESt4R(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TLSt;
|
||||
class PASCALIMPLEMENTATION TLSt : public TESt4R
|
||||
{
|
||||
typedef TESt4R inherited;
|
||||
|
||||
private:
|
||||
double CylFlowSpeed[2][2];
|
||||
double LBP;
|
||||
double RM;
|
||||
double EDFlag;
|
||||
|
||||
public:
|
||||
void __fastcall SetLBP(double P);
|
||||
void __fastcall SetRM(double RMR);
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
virtual double __fastcall GetHPFlow(double HP, double dt);
|
||||
virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF);
|
||||
virtual double __fastcall GetEDBCP(void);
|
||||
void __fastcall SetED(double EDstate);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TLSt(double i_mbp, double i_bcr, double i_bcd, double i_brc,
|
||||
Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TESt4R(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
|
||||
, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TLSt(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TEStED;
|
||||
class PASCALIMPLEMENTATION TEStED : public TLSt
|
||||
{
|
||||
typedef TLSt inherited;
|
||||
|
||||
private:
|
||||
double Nozzles[11];
|
||||
bool Zamykajacy;
|
||||
bool Przys_blok;
|
||||
TReservoir* Miedzypoj;
|
||||
|
||||
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);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TEStED(double i_mbp, double i_bcr, double i_bcd, double i_brc
|
||||
, Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TLSt(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
|
||||
, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TEStED(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TEStEP2;
|
||||
class PASCALIMPLEMENTATION TEStEP2 : public TLSt
|
||||
{
|
||||
typedef TLSt inherited;
|
||||
|
||||
private:
|
||||
double TareM;
|
||||
double LoadM;
|
||||
double TareBP;
|
||||
double LoadC;
|
||||
double EPS;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF);
|
||||
void __fastcall PLC(double mass);
|
||||
virtual void __fastcall SetEPS(double nEPS);
|
||||
void __fastcall SetLP(double TM, double LM, double TBP);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TEStEP2(double i_mbp, double i_bcr, double i_bcd, double i_brc
|
||||
, Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TLSt(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
|
||||
, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TEStEP2(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TCV1;
|
||||
class PASCALIMPLEMENTATION TCV1 : public TBrake
|
||||
{
|
||||
typedef TBrake inherited;
|
||||
|
||||
private:
|
||||
TReservoir* CntrlRes;
|
||||
double BVM;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF);
|
||||
virtual double __fastcall GetCRP(void);
|
||||
void __fastcall CheckState(double BCP, double &dV1);
|
||||
double __fastcall CVs(double bp);
|
||||
double __fastcall BVs(double BCP);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TCV1(double i_mbp, double i_bcr, double i_bcd, double i_brc,
|
||||
Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
|
||||
, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TCV1(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TCV1R;
|
||||
class PASCALIMPLEMENTATION TCV1R : public TCV1
|
||||
{
|
||||
typedef TCV1 inherited;
|
||||
|
||||
private:
|
||||
TReservoir* ImplsRes;
|
||||
bool RapidStatus;
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TCV1R(double i_mbp, double i_bcr, double i_bcd, double i_brc,
|
||||
Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TCV1(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
|
||||
, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TCV1R(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TCV1L_TR;
|
||||
class PASCALIMPLEMENTATION TCV1L_TR : public TCV1
|
||||
{
|
||||
typedef TCV1 inherited;
|
||||
|
||||
private:
|
||||
TReservoir* ImplsRes;
|
||||
double LBP;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF);
|
||||
void __fastcall SetLBP(double P);
|
||||
virtual double __fastcall GetHPFlow(double HP, double dt);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TCV1L_TR(double i_mbp, double i_bcr, double i_bcd, double i_brc
|
||||
, Byte i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TCV1(i_mbp, i_bcr, i_bcd, i_brc, i_bcn
|
||||
, i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TCV1L_TR(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TKE;
|
||||
class PASCALIMPLEMENTATION TKE : public TBrake
|
||||
{
|
||||
typedef TBrake inherited;
|
||||
|
||||
private:
|
||||
bool RapidStatus;
|
||||
TReservoir* ImplsRes;
|
||||
TReservoir* CntrlRes;
|
||||
TReservoir* Brak2Res;
|
||||
double BVM;
|
||||
double TareM;
|
||||
double LoadM;
|
||||
double TareBP;
|
||||
double LoadC;
|
||||
double RM;
|
||||
double LBP;
|
||||
|
||||
public:
|
||||
void __fastcall SetRM(double RMR);
|
||||
virtual double __fastcall GetPF(double PP, double dt, double Vel);
|
||||
virtual void __fastcall Init(double PP, double HPP, double LPP, double BP, Byte BDF);
|
||||
virtual double __fastcall GetHPFlow(double HP, double dt);
|
||||
virtual double __fastcall GetCRP(void);
|
||||
void __fastcall CheckState(double BCP, double &dV1);
|
||||
void __fastcall CheckReleaser(double dt);
|
||||
double __fastcall CVs(double bp);
|
||||
double __fastcall BVs(double BCP);
|
||||
void __fastcall PLC(double mass);
|
||||
void __fastcall SetLP(double TM, double LM, double TBP);
|
||||
void __fastcall SetLBP(double P);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TBrake.Create */ inline __fastcall TKE(double i_mbp, double i_bcr, double i_bcd, double i_brc, Byte
|
||||
i_bcn, Byte i_BD, Byte i_mat, Byte i_ba, Byte i_nbpa) : TBrake(i_mbp, i_bcr, i_bcd, i_brc, i_bcn,
|
||||
i_BD, i_mat, i_ba, i_nbpa) { }
|
||||
#pragma option pop
|
||||
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TKE(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS THandle;
|
||||
class PASCALIMPLEMENTATION THandle : public System::TObject
|
||||
{
|
||||
typedef System::TObject inherited;
|
||||
|
||||
public:
|
||||
bool Time;
|
||||
bool TimeEP;
|
||||
double Sounds[5];
|
||||
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);
|
||||
virtual void __fastcall SetReductor(double nAdj);
|
||||
virtual double __fastcall GetSound(Byte i);
|
||||
virtual double __fastcall GetPos(Byte i);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall THandle(void) : System::TObject() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~THandle(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TFV4a;
|
||||
class PASCALIMPLEMENTATION TFV4a : public THandle
|
||||
{
|
||||
typedef THandle inherited;
|
||||
|
||||
private:
|
||||
double CP;
|
||||
double TP;
|
||||
double RP;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetPF(double i_bcp, double pp, double hp, double dt, double ep);
|
||||
virtual void __fastcall Init(double press);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TFV4a(void) : THandle() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TFV4a(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TFV4aM;
|
||||
class PASCALIMPLEMENTATION TFV4aM : public THandle
|
||||
{
|
||||
typedef THandle inherited;
|
||||
|
||||
private:
|
||||
double CP;
|
||||
double TP;
|
||||
double RP;
|
||||
double XP;
|
||||
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);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TFV4aM(void) : THandle() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TFV4aM(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TM394;
|
||||
class PASCALIMPLEMENTATION TM394 : public THandle
|
||||
{
|
||||
typedef THandle inherited;
|
||||
|
||||
private:
|
||||
double CP;
|
||||
double RedAdj;
|
||||
|
||||
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 GetCP(void);
|
||||
virtual double __fastcall GetPos(Byte i);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TM394(void) : THandle() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TM394(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TH14K1;
|
||||
class PASCALIMPLEMENTATION TH14K1 : public THandle
|
||||
{
|
||||
typedef THandle inherited;
|
||||
|
||||
private:
|
||||
double CP;
|
||||
double RedAdj;
|
||||
|
||||
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 GetCP(void);
|
||||
virtual double __fastcall GetPos(Byte i);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TH14K1(void) : THandle() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TH14K1(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TSt113;
|
||||
class PASCALIMPLEMENTATION TSt113 : public TH14K1
|
||||
{
|
||||
typedef TH14K1 inherited;
|
||||
|
||||
private:
|
||||
double EPS;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetPF(double i_bcp, double pp, double hp, double dt, double ep);
|
||||
virtual double __fastcall GetCP(void);
|
||||
virtual double __fastcall GetPos(Byte i);
|
||||
virtual void __fastcall Init(double press);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TSt113(void) : TH14K1() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TSt113(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS Ttest;
|
||||
class PASCALIMPLEMENTATION Ttest : public THandle
|
||||
{
|
||||
typedef THandle inherited;
|
||||
|
||||
private:
|
||||
double CP;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetPF(double i_bcp, double pp, double hp, double dt, double ep);
|
||||
virtual void __fastcall Init(double press);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall Ttest(void) : THandle() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~Ttest(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TFD1;
|
||||
class PASCALIMPLEMENTATION TFD1 : public THandle
|
||||
{
|
||||
typedef THandle inherited;
|
||||
|
||||
private:
|
||||
double MaxBP;
|
||||
double BP;
|
||||
|
||||
public:
|
||||
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);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TFD1(void) : THandle() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TFD1(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TH1405;
|
||||
class PASCALIMPLEMENTATION TH1405 : public THandle
|
||||
{
|
||||
typedef THandle inherited;
|
||||
|
||||
private:
|
||||
double MaxBP;
|
||||
double BP;
|
||||
|
||||
public:
|
||||
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);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TH1405(void) : THandle() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TH1405(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TFVel6;
|
||||
class PASCALIMPLEMENTATION TFVel6 : public THandle
|
||||
{
|
||||
typedef THandle inherited;
|
||||
|
||||
private:
|
||||
double EPS;
|
||||
|
||||
public:
|
||||
virtual double __fastcall GetPF(double i_bcp, double pp, double hp, double dt, double ep);
|
||||
virtual double __fastcall GetCP(void);
|
||||
virtual double __fastcall GetPos(Byte i);
|
||||
virtual double __fastcall GetSound(Byte i);
|
||||
virtual void __fastcall Init(double press);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TFVel6(void) : THandle() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TFVel6(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
//-- var, const, procedure ---------------------------------------------------
|
||||
static const Shortint LocalBrakePosNo = 0xa;
|
||||
static const Shortint MainBrakeMaxPos = 0xa;
|
||||
static const Shortint bdelay_G = 0x1;
|
||||
static const Shortint bdelay_P = 0x2;
|
||||
static const Shortint bdelay_R = 0x4;
|
||||
static const Shortint bdelay_M = 0x8;
|
||||
static const Byte bdelay_GR = 0x80;
|
||||
static const Shortint b_off = 0x0;
|
||||
static const Shortint b_hld = 0x1;
|
||||
static const Shortint b_on = 0x2;
|
||||
static const Shortint b_rfl = 0x4;
|
||||
static const Shortint b_rls = 0x8;
|
||||
static const Shortint b_ep = 0x10;
|
||||
static const Shortint b_asb = 0x20;
|
||||
static const Byte b_dmg = 0x80;
|
||||
static const Shortint df_on = 0x1;
|
||||
static const Shortint df_off = 0x2;
|
||||
static const Shortint df_br = 0x4;
|
||||
static const Shortint df_vv = 0x8;
|
||||
static const Shortint df_bc = 0x10;
|
||||
static const Shortint df_cv = 0x20;
|
||||
static const Shortint df_PP = 0x40;
|
||||
static const Byte df_RR = 0x80;
|
||||
static const Shortint s_fv4a_b = 0x0;
|
||||
static const Shortint s_fv4a_u = 0x1;
|
||||
static const Shortint s_fv4a_e = 0x2;
|
||||
static const Shortint s_fv4a_x = 0x3;
|
||||
static const Shortint s_fv4a_t = 0x4;
|
||||
static const Shortint bp_P10 = 0x0;
|
||||
static const Shortint bp_P10Bg = 0x2;
|
||||
static const Shortint bp_P10Bgu = 0x1;
|
||||
static const Shortint bp_LLBg = 0x4;
|
||||
static const Shortint bp_LLBgu = 0x3;
|
||||
static const Shortint bp_LBg = 0x6;
|
||||
static const Shortint bp_LBgu = 0x5;
|
||||
static const Shortint bp_KBg = 0x8;
|
||||
static const Shortint bp_KBgu = 0x7;
|
||||
static const Shortint bp_D1 = 0x9;
|
||||
static const Shortint bp_D2 = 0xa;
|
||||
static const Shortint bp_FR513 = 0xb;
|
||||
static const Shortint bp_Cosid = 0xc;
|
||||
static const Shortint bp_PKPBg = 0xd;
|
||||
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 sf_Acc = 0x1;
|
||||
static const Shortint sf_BR = 0x2;
|
||||
static const Shortint sf_CylB = 0x4;
|
||||
static const Shortint sf_CylU = 0x8;
|
||||
static const Shortint sf_rel = 0x10;
|
||||
static const Shortint sf_ep = 0x20;
|
||||
static const Shortint bh_MIN = 0x0;
|
||||
static const Shortint bh_MAX = 0x1;
|
||||
static const Shortint bh_FS = 0x2;
|
||||
static const Shortint bh_RP = 0x3;
|
||||
static const Shortint bh_NP = 0x4;
|
||||
static const Shortint bh_MB = 0x5;
|
||||
static const Shortint bh_FB = 0x6;
|
||||
static const Shortint bh_EB = 0x7;
|
||||
static const Shortint bh_EPR = 0x8;
|
||||
static const Shortint bh_EPN = 0x9;
|
||||
static const Shortint bh_EPB = 0xa;
|
||||
#define SpgD (7.917000E-01)
|
||||
#define SpO (5.067000E-01)
|
||||
extern PACKAGE double BPT[9][2];
|
||||
extern PACKAGE double BPT_394[7][2];
|
||||
static const Shortint i_bcpno = 0x6;
|
||||
extern PACKAGE double __fastcall PF(double P1, double P2, double S, double DP);
|
||||
extern PACKAGE double __fastcall PF1(double P1, double P2, double S);
|
||||
extern PACKAGE double __fastcall PFVa(double PH, double PL, double S, double LIM, double DP);
|
||||
extern PACKAGE double __fastcall PFVd(double PH, double PL, double S, double LIM, double DP);
|
||||
|
||||
} /* namespace Hamulce */
|
||||
#if !defined(NO_IMPLICIT_NAMESPACE_USE)
|
||||
using namespace Hamulce;
|
||||
#endif
|
||||
#pragma option pop // -w-
|
||||
#pragma option pop // -Vx
|
||||
|
||||
#pragma delphiheader end.
|
||||
//-- end unit ----------------------------------------------------------------
|
||||
#endif // hamulce
|
||||
3014
McZapkie/hamulce.pas
Normal file
3014
McZapkie/hamulce.pas
Normal file
File diff suppressed because it is too large
Load Diff
61
McZapkie/klasy_ham.pas
Normal file
61
McZapkie/klasy_ham.pas
Normal file
@@ -0,0 +1,61 @@
|
||||
unit klasy_ham; {fizyka hamulcow dla symulatora}
|
||||
|
||||
(*
|
||||
MaSzyna EU07 - SPKS
|
||||
Brakes. Basic classes.
|
||||
Copyright (C) 2007-2013 Maciej Cierniak
|
||||
*)
|
||||
|
||||
|
||||
interface
|
||||
|
||||
uses mctools,sysutils;
|
||||
|
||||
//CONST;
|
||||
|
||||
TYPE
|
||||
TRurka= class //bezposrednie polaczenie, co wleci to wyleci
|
||||
private
|
||||
Vol: real;
|
||||
Cap: real;
|
||||
|
||||
public
|
||||
function Update(dt: real);
|
||||
procedure Flow(dV: real);
|
||||
end;
|
||||
|
||||
PRurka= ^TRurka;
|
||||
|
||||
TTrojnik= class(TRurka)
|
||||
private
|
||||
Wyjscie1: PRurka;
|
||||
Wyjscie2: PRurka;
|
||||
Wyjscie3: PRurka;
|
||||
public
|
||||
end;
|
||||
|
||||
TZbiornik= class(TRurka)
|
||||
private
|
||||
Wyjscie_jeden: PRurka;
|
||||
public
|
||||
end;
|
||||
|
||||
TPowtarzacz= class(TRurka)
|
||||
private
|
||||
public
|
||||
end;
|
||||
|
||||
TPrzekladnik= class(TPowtarzacz)
|
||||
private
|
||||
public
|
||||
end;
|
||||
|
||||
function PF(P1,P2,S:real):real;
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
||||
95
McZapkie/mctools.hpp
Normal file
95
McZapkie/mctools.hpp
Normal file
@@ -0,0 +1,95 @@
|
||||
// Borland C++ Builder
|
||||
// Copyright (c) 1995, 1999 by Borland International
|
||||
// All rights reserved
|
||||
|
||||
// (DO NOT EDIT: machine generated header) 'mctools.pas' rev: 5.00
|
||||
|
||||
#ifndef mctoolsHPP
|
||||
#define mctoolsHPP
|
||||
|
||||
#pragma delphiheader begin
|
||||
#pragma option push -w-
|
||||
#pragma option push -Vx
|
||||
#include <SysInit.hpp> // Pascal unit
|
||||
#include <System.hpp> // Pascal unit
|
||||
|
||||
//-- user supplied -----------------------------------------------------------
|
||||
|
||||
namespace Mctools
|
||||
{
|
||||
//-- type declarations -------------------------------------------------------
|
||||
typedef Set<char, 0, 255> TableChar;
|
||||
|
||||
//-- var, const, procedure ---------------------------------------------------
|
||||
#define _EOL (System::Set<char, 0, 255> () << '\xa' << '\xd' )
|
||||
static const char _SPACE = '\x20';
|
||||
#define _Spacesigns (System::Set<char, 0, 255> () << '\x9' << '\xa' << '\xd' << '\x29' << '\x2a' << '\x2d' \
|
||||
<< '\x49' << '\x4a' << '\x4d' << '\x69' << '\x6a' << '\x6d' << '\x89' << '\x8a' << '\x8d' << '\xa9' \
|
||||
<< '\xaa' << '\xad' << '\xc9' << '\xca' << '\xcd' << '\xe9' << '\xea' << '\xed' )
|
||||
static const Shortint CutLeft = 0xffffffff;
|
||||
static const Shortint CutRight = 0x1;
|
||||
static const Shortint CutBoth = 0x0;
|
||||
extern PACKAGE int ConversionError;
|
||||
extern PACKAGE int LineCount;
|
||||
extern PACKAGE bool DebugModeFlag;
|
||||
extern PACKAGE bool FreeFlyModeFlag;
|
||||
extern PACKAGE double Xmin;
|
||||
extern PACKAGE double Ymin;
|
||||
extern PACKAGE double Xmax;
|
||||
extern PACKAGE double Ymax;
|
||||
extern PACKAGE double Xaspect;
|
||||
extern PACKAGE double Yaspect;
|
||||
extern PACKAGE double Hstep;
|
||||
extern PACKAGE double Vstep;
|
||||
extern PACKAGE int Vsize;
|
||||
extern PACKAGE int Hsize;
|
||||
extern PACKAGE AnsiString __fastcall Ups(AnsiString s);
|
||||
extern PACKAGE AnsiString __fastcall b2s(Byte b);
|
||||
extern PACKAGE AnsiString __fastcall i2s(int i);
|
||||
extern PACKAGE AnsiString __fastcall l2s(int l);
|
||||
extern PACKAGE AnsiString __fastcall r2s(double r, Byte SWidth);
|
||||
extern PACKAGE Byte __fastcall s2b(AnsiString s);
|
||||
extern PACKAGE int __fastcall s2i(AnsiString s);
|
||||
extern PACKAGE int __fastcall s2l(AnsiString s);
|
||||
extern PACKAGE double __fastcall s2r(AnsiString s);
|
||||
extern PACKAGE Byte __fastcall s2bE(AnsiString s);
|
||||
extern PACKAGE int __fastcall s2iE(AnsiString s);
|
||||
extern PACKAGE int __fastcall s2lE(AnsiString s);
|
||||
extern PACKAGE double __fastcall s2rE(AnsiString s);
|
||||
extern PACKAGE Byte __fastcall Max0(Byte x1, Byte x2);
|
||||
extern PACKAGE Byte __fastcall Min0(Byte x1, Byte x2);
|
||||
extern PACKAGE double __fastcall Max0R(double x1, double x2);
|
||||
extern PACKAGE double __fastcall Min0R(double x1, double x2);
|
||||
extern PACKAGE int __fastcall Sign(double x);
|
||||
extern PACKAGE bool __fastcall TestFlag(int Flag, int Value);
|
||||
extern PACKAGE bool __fastcall SetFlag(Byte &Flag, int Value);
|
||||
extern PACKAGE bool __fastcall iSetFlag(int &Flag, int Value);
|
||||
extern PACKAGE bool __fastcall FuzzyLogic(double Test, double Threshold, double Probability);
|
||||
extern PACKAGE bool __fastcall FuzzyLogicAI(double Test, double Threshold, double Probability);
|
||||
extern PACKAGE AnsiString __fastcall ReadWord(TextFile &infile);
|
||||
extern PACKAGE AnsiString __fastcall Cut_Space(AnsiString s, int Just);
|
||||
extern PACKAGE AnsiString __fastcall ExtractKeyWord(AnsiString InS, AnsiString KeyWord);
|
||||
extern PACKAGE AnsiString __fastcall DUE(AnsiString S);
|
||||
extern PACKAGE AnsiString __fastcall DWE(AnsiString S);
|
||||
extern PACKAGE AnsiString __fastcall Ld2Sp(AnsiString S);
|
||||
extern PACKAGE AnsiString __fastcall Tab2Sp(AnsiString S);
|
||||
extern PACKAGE void __fastcall ComputeArc(double X0, double Y0, double Xn, double Yn, double R, double
|
||||
L, double dL, double &phi, double &Xout, double &Yout);
|
||||
extern PACKAGE void __fastcall ComputeALine(double X0, double Y0, double Xn, double Yn, double L, double
|
||||
R, double &Xout, double &Yout);
|
||||
extern PACKAGE double __fastcall Xhor(double h);
|
||||
extern PACKAGE double __fastcall Yver(double v);
|
||||
extern PACKAGE int __fastcall Horiz(double X);
|
||||
extern PACKAGE int __fastcall Vert(double Y);
|
||||
extern PACKAGE void __fastcall ClearPendingExceptions(void);
|
||||
|
||||
} /* namespace Mctools */
|
||||
#if !defined(NO_IMPLICIT_NAMESPACE_USE)
|
||||
using namespace Mctools;
|
||||
#endif
|
||||
#pragma option pop // -w-
|
||||
#pragma option pop // -Vx
|
||||
|
||||
#pragma delphiheader end.
|
||||
//-- end unit ----------------------------------------------------------------
|
||||
#endif // mctools
|
||||
497
McZapkie/mctools.pas
Normal file
497
McZapkie/mctools.pas
Normal file
@@ -0,0 +1,497 @@
|
||||
unit mctools;
|
||||
{rozne takie duperele do operacji na stringach w paszczalu, pewnie w delfi sa lepsze}
|
||||
{konwersja zmiennych na stringi, funkcje matematyczne, logiczne, lancuchowe, I/O etc}
|
||||
|
||||
interface
|
||||
|
||||
|
||||
const
|
||||
{Ra: te sta³e nie s¹ u¿ywane...
|
||||
_FileName = ['a'..'z','A'..'Z',':','\','.','*','?','0'..'9','_','-'];
|
||||
_RealNum = ['0'..'9','-','+','.','E','e'];
|
||||
_Integer = ['0'..'9','-']; //Ra: to siê gryzie z STLport w Builder 6
|
||||
_Plus_Int = ['0'..'9'];
|
||||
_All = [' '..'þ'];
|
||||
_Delimiter= [',',';']+_EOL;
|
||||
_Delimiter_Space=_Delimiter+[' '];
|
||||
}
|
||||
_EOL = [#13,#10];
|
||||
_SPACE = ' ';
|
||||
_Spacesigns=[' ']+[#9]+_EOL;
|
||||
CutLeft=-1; CutRight=1; CutBoth=0; {Cut_Space}
|
||||
|
||||
var
|
||||
ConversionError: integer=0;
|
||||
LineCount: integer=0;
|
||||
DebugModeFlag: boolean=False;
|
||||
FreeFlyModeFlag: boolean=False;
|
||||
|
||||
type
|
||||
TableChar = Set Of Char; {MCTUTIL}
|
||||
|
||||
{konwersje}
|
||||
function b2s(b:byte):string;
|
||||
function i2s(i:integer):string;
|
||||
function l2s(l:longint):string;
|
||||
function r2s(r:real; SWidth:byte):string;
|
||||
function s2b(s:string):byte;
|
||||
function s2i(s:string):integer;
|
||||
function s2l(s:string):longint;
|
||||
function s2r(s:string):real;
|
||||
function s2bE(s:string):byte;
|
||||
function s2iE(s:string):integer;
|
||||
function s2lE(s:string):longint;
|
||||
function s2rE(s:string):real;
|
||||
|
||||
{funkcje matematyczne}
|
||||
function Max0(x1,x2:byte) : byte;
|
||||
function Min0(x1,x2:byte) : byte;
|
||||
|
||||
function Max0R(x1,x2:real) : real;
|
||||
function Min0R(x1,x2:real) : real;
|
||||
|
||||
function Sign(x:real) : integer;
|
||||
|
||||
{funkcje logiczne}
|
||||
function TestFlag(Flag:integer; Value:integer):boolean;
|
||||
function SetFlag(var Flag:byte; Value:integer):boolean;
|
||||
function iSetFlag(var Flag:integer; Value:integer):boolean;
|
||||
|
||||
function FuzzyLogic(Test,Threshold,Probability:real):boolean;
|
||||
{jesli Test>Threshold to losowanie}
|
||||
function FuzzyLogicAI(Test,Threshold,Probability:real):boolean;
|
||||
{to samo ale zawsze niezaleznie od DebugFlag}
|
||||
|
||||
{operacje na stringach}
|
||||
Function ReadWord(var infile:text):string; {czyta slowo z wiersza pliku tekstowego}
|
||||
Function Ups (s:string ): string ;
|
||||
Function Cut_Space(s:string; Just:integer) : string;
|
||||
Function ExtractKeyWord(InS:String; KeyWord:string) : String; {wyciaga slowo kluczowe i lancuch do pierwszej spacji}
|
||||
Function DUE(S:String) : String; {Delete Until Equal sign}
|
||||
Function DWE(S:String) : String; {Delete While Equal sign}
|
||||
Function Ld2Sp(S:String): String; {Low dash to Space sign}
|
||||
Function Tab2Sp(S:String): String; {Tab to Space sign}
|
||||
|
||||
{procedury, zmienne i funkcje graficzne}
|
||||
procedure ComputeArc(X0,Y0,Xn,Yn,R,L:real;dL:real; var phi,Xout,Yout:real);
|
||||
{wylicza polozenie Xout Yout i orientacje phi punktu na elemencie dL luku}
|
||||
procedure ComputeALine(X0,Y0,Xn,Yn,L,R:real; var Xout,Yout:real);
|
||||
|
||||
|
||||
var
|
||||
Xmin,Ymin,Xmax,Ymax:real;
|
||||
Xaspect,Yaspect:real;
|
||||
Hstep,Vstep: real;
|
||||
Vsize,Hsize:integer;
|
||||
|
||||
function Xhor( h:real) :real;
|
||||
{ Converts horizontal screen coordinate into real X-coordinate. }
|
||||
|
||||
function Yver( v:real) :real;
|
||||
{ Converts vertical screen coordinate into real Y-coordinate. }
|
||||
|
||||
function Horiz(X:real):longint;
|
||||
|
||||
function Vert(Y:real):longint;
|
||||
|
||||
procedure ClearPendingExceptions;
|
||||
|
||||
{------------------------------------------------}
|
||||
Implementation
|
||||
{================================================}
|
||||
|
||||
function Ups (s:string ): string ;
|
||||
var
|
||||
jatka : integer; swy:string;
|
||||
begin
|
||||
swy:='';
|
||||
for jatka:=1 to length(s) do swy:=swy+UpCase(s[jatka]);
|
||||
Ups:=swy;
|
||||
end; {=Ups=}
|
||||
|
||||
function b2s(b:byte):string;
|
||||
var
|
||||
s:string;
|
||||
begin
|
||||
Str(b:2,s);
|
||||
b2s:=s;
|
||||
end; {=b2s=}
|
||||
|
||||
function i2s(i:integer):string;
|
||||
var
|
||||
s:string;
|
||||
begin
|
||||
Str(i:3,s);
|
||||
i2s:=s;
|
||||
end; {=i2s=}
|
||||
|
||||
function l2s(l:longint):string;
|
||||
var
|
||||
s:string;
|
||||
begin
|
||||
Str(l:4,s);
|
||||
l2s:=s;
|
||||
end; {=l2s=}
|
||||
|
||||
function r2s(r:real; SWidth:byte):string;
|
||||
var
|
||||
s:string;
|
||||
absr:real; {rr:integer;}
|
||||
begin
|
||||
absr:=Abs(r);
|
||||
if SWidth<8 then SWidth:=8;
|
||||
if absr > 0.0001 then
|
||||
begin {rr:=(Round(ln(1/absr)/ln(10)-1+Swidth/2));}
|
||||
if absr < 100 then
|
||||
Str(r:Swidth:(Round(ln(1/absr)/ln(10)-1+Swidth/2)),s)
|
||||
else Str(r:Swidth:1,s)
|
||||
end
|
||||
else Str(r:Swidth,s);
|
||||
{ if r>0 then s:=insert('+'s,3);}
|
||||
r2s:=s;
|
||||
end; {=r2s=}
|
||||
|
||||
function s2b(s:string):byte;
|
||||
var e:integer;
|
||||
b:byte;
|
||||
begin
|
||||
Val(s,b,e);
|
||||
s2b:=b;
|
||||
end;
|
||||
|
||||
function s2i(s:string):integer;
|
||||
var e:integer;
|
||||
i:integer;
|
||||
begin
|
||||
Val(s,i,e);
|
||||
s2i:=i;
|
||||
end;
|
||||
|
||||
function s2l(s:string):longint;
|
||||
var e:integer;
|
||||
l:longint;
|
||||
begin
|
||||
Val(s,l,e);
|
||||
s2l:=l;
|
||||
end;
|
||||
|
||||
function s2r(s:string):real;
|
||||
var e:integer;
|
||||
r:real;
|
||||
begin
|
||||
Val(s,r,e);
|
||||
s2r:=r;
|
||||
end;
|
||||
|
||||
|
||||
function s2bE(s:string):byte;
|
||||
var e:integer;
|
||||
b:byte;
|
||||
begin
|
||||
s2bE:=0;
|
||||
Val(s,b,e);
|
||||
if e>0 then
|
||||
ConversionError:=e
|
||||
else s2bE:=b;
|
||||
end;
|
||||
|
||||
function s2iE(s:string):integer;
|
||||
var e:integer;
|
||||
i:integer;
|
||||
begin
|
||||
s2iE:=0;
|
||||
Val(s,i,e);
|
||||
if e>0 then
|
||||
ConversionError:=e
|
||||
else s2iE:=i;
|
||||
end;
|
||||
|
||||
function s2lE(s:string):longint;
|
||||
var e:integer;
|
||||
l:longint;
|
||||
begin
|
||||
s2lE:=0;
|
||||
Val(s,l,e);
|
||||
if e>0 then
|
||||
ConversionError:=e
|
||||
else s2lE:=l;
|
||||
end;
|
||||
|
||||
function s2rE(s:string):real;
|
||||
var e:integer;
|
||||
r:real;
|
||||
begin
|
||||
s2rE:=0;
|
||||
Val(s,r,e);
|
||||
if e>0 then
|
||||
ConversionError:=e
|
||||
else s2rE:=r;
|
||||
end;
|
||||
|
||||
|
||||
function Max0(x1,x2:byte) : byte;
|
||||
begin
|
||||
if x1>x2 then
|
||||
Max0:=x1
|
||||
else
|
||||
Max0:=x2;
|
||||
end;
|
||||
|
||||
function Min0(x1,x2:byte) : byte;
|
||||
begin
|
||||
if x1<x2 then
|
||||
Min0:=x1
|
||||
else
|
||||
Min0:=x2;
|
||||
end;
|
||||
|
||||
function Max0R(x1,x2:real) : real;
|
||||
begin
|
||||
if x1>x2 then
|
||||
Max0R:=x1
|
||||
else
|
||||
Max0R:=x2;
|
||||
end;
|
||||
|
||||
function Min0R(x1,x2:real) : real;
|
||||
begin
|
||||
if x1<x2 then
|
||||
Min0R:=x1
|
||||
else
|
||||
Min0R:=x2;
|
||||
end;
|
||||
|
||||
function Sign(x:real) : integer;
|
||||
begin
|
||||
Sign:=0;
|
||||
if x>0 then Sign:=1;
|
||||
if x<0 then Sign:=-1;
|
||||
end;
|
||||
|
||||
function TestFlag(Flag:integer; Value:integer):boolean;
|
||||
begin
|
||||
if (Flag and Value)=Value then
|
||||
TestFlag:=True
|
||||
else TestFlag:=False;
|
||||
end;
|
||||
|
||||
function SetFlag(var Flag:byte; Value:integer):boolean;
|
||||
begin
|
||||
SetFlag:=False;
|
||||
if Value>0 then
|
||||
if (Flag and Value)=0 then
|
||||
begin
|
||||
Flag:=Flag+Value;
|
||||
SetFlag:=True
|
||||
end;
|
||||
if Value<0 then
|
||||
if (Flag and Abs(Value))=Abs(Value) then
|
||||
begin
|
||||
Flag:=Flag+Value;
|
||||
SetFlag:=True
|
||||
end;
|
||||
end;
|
||||
|
||||
function iSetFlag(var Flag:integer; Value:integer):boolean;
|
||||
begin
|
||||
iSetFlag:=False;
|
||||
if Value>0 then
|
||||
if (Flag and Value)=0 then
|
||||
begin
|
||||
Flag:=Flag+Value;
|
||||
iSetFlag:=True; //true, gdy by³o wczeœniej 0 i zosta³o ustawione
|
||||
end;
|
||||
if Value<0 then
|
||||
if (Flag and Abs(Value))=Abs(Value) then
|
||||
begin
|
||||
Flag:=Flag+Value; //Value jest ujemne, czyli zerowanie flagi
|
||||
iSetFlag:=True; //true, gdy by³o wczeœniej 1 i zosta³o wyzerowane
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function FuzzyLogic(Test,Threshold,Probability:real):boolean;
|
||||
begin
|
||||
if (Test>Threshold) and (not DebugModeFlag) then
|
||||
FuzzyLogic:=(Random<Probability*Threshold/Test) {im wiekszy Test tym wieksza szansa}
|
||||
else FuzzyLogic:=False;
|
||||
end;
|
||||
|
||||
function FuzzyLogicAI(Test,Threshold,Probability:real):boolean;
|
||||
begin
|
||||
if (Test>Threshold) then
|
||||
FuzzyLogicAI:=(Random<Probability*Threshold/Test) {im wiekszy Test tym wieksza szansa}
|
||||
else FuzzyLogicAI:=False;
|
||||
end;
|
||||
|
||||
Function ReadWord(var infile:text):string;
|
||||
var s:string; c:char; nextword:boolean;
|
||||
begin
|
||||
s:='';
|
||||
nextword:=False;
|
||||
while (not eof(infile)) and (not nextword) do
|
||||
begin
|
||||
read(infile,c);
|
||||
if c in _SpaceSigns then
|
||||
if s<>'' then
|
||||
nextword:=True;
|
||||
if not (c in _Spacesigns) then
|
||||
s:=s+c;
|
||||
end;
|
||||
ReadWord:=s;
|
||||
end;
|
||||
|
||||
|
||||
Function Cut_Space(s:string; Just:integer) : string;
|
||||
var ii:byte;
|
||||
begin
|
||||
case Just of
|
||||
CutLeft : begin
|
||||
ii:=0;
|
||||
while (ii<length(s)) and (s[ii+1]=_SPACE) do
|
||||
inc(ii);
|
||||
S:=Copy(s,ii+1,length(s)-ii);
|
||||
end;
|
||||
CutRight: begin
|
||||
ii:=length(s);
|
||||
while(ii>0) and (s[ii]=_SPACE) do
|
||||
dec(ii);
|
||||
S:=Copy(s,1,ii);
|
||||
end;
|
||||
CutBoth : begin
|
||||
S:=Cut_Space(S,CutLeft);
|
||||
S:=Cut_Space(S,CutRight);
|
||||
end;
|
||||
end;
|
||||
Cut_Space:=S;
|
||||
end;
|
||||
{Cut_Space}
|
||||
|
||||
Function ExtractKeyWord(InS:String; KeyWord:string) : String;
|
||||
var s:string; kwp:byte;
|
||||
begin
|
||||
Ins:=Ins+' ';
|
||||
kwp:=Pos(KeyWord,InS);
|
||||
if kwp>0 then
|
||||
begin
|
||||
s:=Copy(InS,kwp,Length(Ins));
|
||||
s:=Copy(s,1,Pos(' ',s)-1);
|
||||
end
|
||||
else s:='';
|
||||
ExtractKeyWord:=s;
|
||||
end;
|
||||
|
||||
Function DUE(S:String) : String; {Delete Until Equal sign}
|
||||
begin
|
||||
DUE:=Copy(S,Pos('=',S)+1,Length(S));
|
||||
end;
|
||||
|
||||
Function DWE(S:String) : String; {Delete While Equal sign}
|
||||
var ep:byte;
|
||||
begin
|
||||
ep:=Pos('=',S);
|
||||
if ep>0 then
|
||||
DWE:=Copy(S,1,ep-1)
|
||||
else DWE:=S;
|
||||
end;
|
||||
|
||||
Function Ld2Sp(S:String): String; {Low dash to Space sign}
|
||||
var b:byte; s2:string;
|
||||
begin
|
||||
s2:='';
|
||||
for b:=1 to length(S) do
|
||||
if S[b]='_' then
|
||||
s2:=s2+' '
|
||||
else
|
||||
s2:=s2+S[b];
|
||||
Ld2Sp:=s2;
|
||||
end;
|
||||
|
||||
Function Tab2Sp(S:String): String; {Tab to Space sign}
|
||||
var b:byte; s2:string;
|
||||
begin
|
||||
s2:='';
|
||||
for b:=1 to length(S) do
|
||||
if S[b]=#9 then
|
||||
s2:=s2+' '
|
||||
else
|
||||
s2:=s2+S[b];
|
||||
Tab2Sp:=s2;
|
||||
end;
|
||||
|
||||
|
||||
procedure ComputeArc(X0,Y0,Xn,Yn,R,L:real;dL:real; var phi,Xout,Yout:real);
|
||||
{wylicza polozenie Xout Yout i orientacje phi punktu na elemencie dL luku}
|
||||
var dX,dY,Xc,Yc,gamma,alfa,AbsR:real;
|
||||
begin
|
||||
if (R<>0) and (L<>0) then
|
||||
begin
|
||||
AbsR:=Abs(R);
|
||||
dX:=Xn-X0;
|
||||
dY:=Yn-Y0;
|
||||
if dX<>0 then gamma:=arctan(dY/dX)
|
||||
else if dY>0 then gamma:=Pi/2
|
||||
else gamma:=3*Pi/2;
|
||||
alfa:=L/R;
|
||||
phi:=gamma-(alfa+Pi*Round(R/AbsR))/2;
|
||||
Xc:=X0-AbsR*cos(phi);
|
||||
Yc:=Y0-AbsR*sin(phi);
|
||||
phi:=phi+alfa*dL/L;
|
||||
Xout:=AbsR*cos(phi)+Xc;
|
||||
Yout:=AbsR*sin(phi)+Yc;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ComputeALine(X0,Y0,Xn,Yn,L,R:real; var Xout,Yout:real);
|
||||
var dX,dY,gamma,alfa:real;
|
||||
{ pX,pY : real;}
|
||||
begin
|
||||
alfa:=0; //ABu: bo nie bylo zainicjowane
|
||||
dX:=Xn-X0;
|
||||
dY:=Yn-Y0;
|
||||
if dX<>0 then gamma:=arctan(dY/dX)
|
||||
else if dY>0 then gamma:=Pi/2
|
||||
else gamma:=3*Pi/2;
|
||||
if R<>0 then alfa:=L/R;
|
||||
Xout:=X0+L*cos(alfa/2-gamma);
|
||||
Yout:=Y0+L*sin(alfa/2-gamma);
|
||||
end;
|
||||
|
||||
{graficzne:}
|
||||
|
||||
|
||||
function Xhor( h:real) :real;
|
||||
begin
|
||||
Xhor:= h*Hstep + Xmin;
|
||||
end;
|
||||
|
||||
function Yver( v:real) :real;
|
||||
begin
|
||||
Yver:= (Vsize-v)*Vstep + Ymin;
|
||||
end;
|
||||
|
||||
function Horiz(X:real):longint;
|
||||
begin
|
||||
x:= (x-Xmin) / Hstep;
|
||||
if x > -MaxInt then
|
||||
if x < MaxInt then Horiz:=Round(x)
|
||||
else Horiz:= MaxInt
|
||||
else Horiz:= -MaxInt;
|
||||
end;
|
||||
|
||||
function Vert(Y:real):longint;
|
||||
begin
|
||||
y:= (y-Ymin) / Vstep;
|
||||
if y > -MaxInt then
|
||||
if y < MaxInt then Vert:=Vsize-Round(y)
|
||||
else Vert:= MaxInt
|
||||
else Vert:= -MaxInt
|
||||
end;
|
||||
|
||||
procedure ClearPendingExceptions;
|
||||
//resetuje b³êdy FPU, wymagane dla Trunc()
|
||||
asm
|
||||
FNCLEX
|
||||
end;
|
||||
|
||||
end.
|
||||
127
McZapkie/mtable.hpp
Normal file
127
McZapkie/mtable.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
// Borland C++ Builder
|
||||
// Copyright (c) 1995, 1999 by Borland International
|
||||
// All rights reserved
|
||||
|
||||
// (DO NOT EDIT: machine generated header) 'mtable.pas' rev: 5.00
|
||||
|
||||
#ifndef mtableHPP
|
||||
#define mtableHPP
|
||||
|
||||
#pragma delphiheader begin
|
||||
#pragma option push -w-
|
||||
#pragma option push -Vx
|
||||
#include <SysUtils.hpp> // Pascal unit
|
||||
#include <mctools.hpp> // Pascal unit
|
||||
#include <SysInit.hpp> // Pascal unit
|
||||
#include <System.hpp> // Pascal unit
|
||||
|
||||
//-- user supplied -----------------------------------------------------------
|
||||
|
||||
namespace Mtable
|
||||
{
|
||||
//-- type declarations -------------------------------------------------------
|
||||
struct TMTableLine
|
||||
{
|
||||
double km;
|
||||
double vmax;
|
||||
AnsiString StationName;
|
||||
AnsiString StationWare;
|
||||
Byte TrackNo;
|
||||
int Ah;
|
||||
int Am;
|
||||
int Dh;
|
||||
int Dm;
|
||||
double tm;
|
||||
int WaitTime;
|
||||
} ;
|
||||
|
||||
typedef TMTableLine TMTable[101];
|
||||
|
||||
class DELPHICLASS TTrainParameters;
|
||||
typedef TTrainParameters* *PTrainParameters;
|
||||
|
||||
class PASCALIMPLEMENTATION TTrainParameters : public System::TObject
|
||||
{
|
||||
typedef System::TObject inherited;
|
||||
|
||||
public:
|
||||
AnsiString TrainName;
|
||||
double TTVmax;
|
||||
AnsiString Relation1;
|
||||
AnsiString Relation2;
|
||||
double BrakeRatio;
|
||||
AnsiString LocSeries;
|
||||
double LocLoad;
|
||||
TMTableLine TimeTable[101];
|
||||
int StationCount;
|
||||
int StationIndex;
|
||||
AnsiString NextStationName;
|
||||
double LastStationLatency;
|
||||
int Direction;
|
||||
double __fastcall CheckTrainLatency(void);
|
||||
AnsiString __fastcall ShowRelation();
|
||||
double __fastcall WatchMTable(double DistCounter);
|
||||
AnsiString __fastcall NextStop();
|
||||
bool __fastcall IsStop(void);
|
||||
bool __fastcall IsTimeToGo(double hh, double mm);
|
||||
bool __fastcall UpdateMTable(double hh, double mm, AnsiString NewName);
|
||||
__fastcall TTrainParameters(AnsiString NewTrainName);
|
||||
void __fastcall NewName(AnsiString NewTrainName);
|
||||
bool __fastcall LoadTTfile(AnsiString scnpath, int iPlus, double vMax);
|
||||
bool __fastcall DirectionChange(void);
|
||||
void __fastcall StationIndexInc(void);
|
||||
public:
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TTrainParameters(void) : System::TObject() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TTrainParameters(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
class DELPHICLASS TMTableTime;
|
||||
class PASCALIMPLEMENTATION TMTableTime : public System::TObject
|
||||
{
|
||||
typedef System::TObject inherited;
|
||||
|
||||
public:
|
||||
double GameTime;
|
||||
int dd;
|
||||
int hh;
|
||||
int mm;
|
||||
int srh;
|
||||
int srm;
|
||||
int ssh;
|
||||
int ssm;
|
||||
double mr;
|
||||
void __fastcall UpdateMTableTime(double deltaT);
|
||||
__fastcall TMTableTime(int InitH, int InitM, int InitSRH, int InitSRM, int InitSSH, int InitSSM);
|
||||
public:
|
||||
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Create */ inline __fastcall TMTableTime(void) : System::TObject() { }
|
||||
#pragma option pop
|
||||
#pragma option push -w-inl
|
||||
/* TObject.Destroy */ inline __fastcall virtual ~TMTableTime(void) { }
|
||||
#pragma option pop
|
||||
|
||||
};
|
||||
|
||||
|
||||
//-- var, const, procedure ---------------------------------------------------
|
||||
static const Shortint MaxTTableSize = 0x64;
|
||||
static const char hrsd = '\x2e';
|
||||
extern PACKAGE TMTableTime* GlobalTime;
|
||||
|
||||
} /* namespace Mtable */
|
||||
#if !defined(NO_IMPLICIT_NAMESPACE_USE)
|
||||
using namespace Mtable;
|
||||
#endif
|
||||
#pragma option pop // -w-
|
||||
#pragma option pop // -Vx
|
||||
|
||||
#pragma delphiheader end.
|
||||
//-- end unit ----------------------------------------------------------------
|
||||
#endif // mtable
|
||||
521
McZapkie/mtable.pas
Normal file
521
McZapkie/mtable.pas
Normal file
@@ -0,0 +1,521 @@
|
||||
unit mtable;
|
||||
|
||||
interface uses mctools,sysutils;
|
||||
|
||||
const MaxTTableSize=100; //mo¿na by to robiæ dynamicznie
|
||||
hrsd= '.';
|
||||
Type
|
||||
//Ra: pozycja zerowa rozk³adu chyba nie ma sensu
|
||||
//Ra: numeracja przystanków jest 1..StationCount
|
||||
|
||||
TMTableLine=record
|
||||
km:real; //kilometraz linii
|
||||
vmax:real; //predkosc rozkladowa przed przystankiem
|
||||
//StationName:string[32]; //nazwa stacji ('_' zamiast spacji)
|
||||
//StationWare:string[32]; //typ i wyposazenie stacji, oddz. przecinkami}
|
||||
StationName:string; //nazwa stacji ('_' zamiast spacji)
|
||||
StationWare:string; //typ i wyposazenie stacji, oddz. przecinkami}
|
||||
TrackNo:byte; //ilosc torow szlakowych
|
||||
Ah,Am:integer; //godz. i min. przyjazdu, -1 gdy bez postoju
|
||||
Dh,Dm:integer; //godz. i min. odjazdu
|
||||
tm:real; //czas jazdy do tej stacji w min. (z kolumny)
|
||||
WaitTime:integer; //czas postoju (liczony plus 6 sekund)
|
||||
end;
|
||||
|
||||
TMTable = array[0..MaxTTableSize] of TMTableLine;
|
||||
|
||||
PTrainParameters= ^TTrainParameters;
|
||||
|
||||
TTrainParameters = class(TObject)
|
||||
TrainName:string;
|
||||
TTVmax:real;
|
||||
Relation1,Relation2: string; //nazwy stacji danego odcinka
|
||||
BrakeRatio: real;
|
||||
LocSeries: string; //seria (typ) pojazdu
|
||||
LocLoad: real;
|
||||
TimeTable: TMTable;
|
||||
StationCount: integer; //iloœæ przystanków (0-techniczny)
|
||||
StationIndex: integer; //numer najbli¿szego (aktualnego) przystanku
|
||||
NextStationName: string;
|
||||
LastStationLatency: real;
|
||||
Direction: integer; {kierunek jazdy w/g kilometrazu}
|
||||
function CheckTrainLatency: real;
|
||||
{todo: str hh:mm to int i z powrotem}
|
||||
function ShowRelation: string;
|
||||
function WatchMTable(DistCounter:real): real;
|
||||
function NextStop:string;
|
||||
function IsStop:boolean;
|
||||
function IsTimeToGo(hh,mm:real):boolean;
|
||||
function UpdateMTable(hh,mm:real; NewName: string): boolean;
|
||||
constructor Init(NewTrainName:string);
|
||||
procedure NewName(NewTrainName:string);
|
||||
function LoadTTfile(scnpath:string;iPlus:Integer;vMax:real):boolean;
|
||||
function DirectionChange():boolean;
|
||||
procedure StationIndexInc();
|
||||
end;
|
||||
|
||||
TMTableTime = class(TObject)
|
||||
GameTime: real;
|
||||
dd,hh,mm: integer;
|
||||
srh,srm : integer; {wschod slonca}
|
||||
ssh,ssm : integer; {zachod slonca}
|
||||
mr:real;
|
||||
procedure UpdateMTableTime(deltaT:real);
|
||||
constructor Init(InitH,InitM,InitSRH,InitSRM,InitSSH,InitSSM:integer);
|
||||
end;
|
||||
|
||||
var GlobalTime: TMTableTime;
|
||||
|
||||
implementation
|
||||
|
||||
function CompareTime(t1h,t1m,t2h,t2m:real):real; {roznica czasu w minutach}
|
||||
//zwraca ró¿nicê czasu
|
||||
//jeœli pierwsza jest aktualna, a druga rozk³adowa, to ujemna oznacza opó¿nienie
|
||||
//na d³u¿sz¹ metê trzeba uwzglêdniæ datê, jakby opó¿nienia mia³y przekraczaæ 12h (towarowych)
|
||||
var
|
||||
t:real;
|
||||
begin
|
||||
if (t2h<0) then
|
||||
CompareTime:=0
|
||||
else
|
||||
begin
|
||||
t:=(t2h-t1h)*60+t2m-t1m; //jeœli t2=00:05, a t1=23:50, to ró¿nica wyjdzie ujemna
|
||||
if (t<-720) then //jeœli ró¿nica przekracza 12h na minus
|
||||
t:=t+1440 //to dodanie doby minut
|
||||
else
|
||||
if (t>720) then //jeœli przekracza 12h na plus
|
||||
t:=t-1440; //to odjêcie doby minut
|
||||
CompareTime:=t;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TTrainParameters.CheckTrainLatency: real;
|
||||
begin
|
||||
if (LastStationLatency>1.0) or (LastStationLatency<-1.0) then
|
||||
CheckTrainLatency:=LastStationLatency {spoznienie + lub do przodu - z tolerancja 1 min}
|
||||
else
|
||||
CheckTrainLatency:=0
|
||||
end;
|
||||
|
||||
function TTrainParameters.WatchMTable(DistCounter:real): real;
|
||||
{zwraca odlegloϾ do najblizszej stacji z zatrzymaniem}
|
||||
var dist:real;
|
||||
begin
|
||||
if Direction=1 then
|
||||
dist:=TimeTable[StationIndex].km-TimeTable[0].km-DistCounter
|
||||
else
|
||||
dist:=TimeTable[0].km-TimeTable[StationIndex].km-DistCounter;
|
||||
WatchMTable:=dist;
|
||||
end;
|
||||
|
||||
function TTrainParameters.NextStop:string;
|
||||
//pobranie nazwy nastêpnego miejsca zatrzymania
|
||||
begin
|
||||
if StationIndex<=StationCount
|
||||
then
|
||||
NextStop:='PassengerStopPoint:'+NextStationName //nazwa nastêpnego przystanku
|
||||
else
|
||||
NextStop:='[End of route]'; //¿e niby koniec
|
||||
end;
|
||||
|
||||
function TTrainParameters.IsStop:boolean;
|
||||
//zapytanie, czy zatrzymywaæ na nastêpnym punkcie rozk³adu
|
||||
begin
|
||||
if (StationIndex<StationCount) then
|
||||
IsStop:=TimeTable[StationIndex].Ah>=0 //-1 to brak postoju
|
||||
else
|
||||
IsStop:=true; //na ostatnim siê zatrzymaæ zawsze
|
||||
end;
|
||||
|
||||
function TTrainParameters.UpdateMTable(hh,mm:real;NewName:string):boolean;
|
||||
{odfajkowanie dojechania do stacji (NewName) i przeliczenie opóŸnienia}
|
||||
var OK:boolean;
|
||||
begin
|
||||
OK:=false;
|
||||
if StationIndex<=StationCount then //Ra: "<=", bo ostatni przystanek jest traktowany wyj¹tkowo
|
||||
begin
|
||||
if NewName=NextStationName then //jeœli dojechane do nastêpnego
|
||||
begin //Ra: wywo³anie mo¿e byæ powtarzane, jak stoi na W4
|
||||
if TimeTable[StationIndex+1].km-TimeTable[StationIndex].km<0 then //to jest bez sensu
|
||||
Direction:=-1
|
||||
else
|
||||
Direction:=1; //prowizorka bo moze byc zmiana kilometrazu
|
||||
//ustalenie, czy opóŸniony (porównanie z czasem odjazdu)
|
||||
LastStationLatency:=CompareTime(hh,mm,TimeTable[StationIndex].Dh,TimeTable[StationIndex].Dm);
|
||||
//inc(StationIndex); //przejœcie do nastêpnej pozycji StationIndex<=StationCount
|
||||
if StationIndex<StationCount then //Ra: "<", bo dodaje 1 przy przejœciu do nastêpnej stacji
|
||||
begin //jeœli nie ostatnia stacja
|
||||
NextStationName:=TimeTable[StationIndex+1].StationName; //zapamiêtanie nazwy
|
||||
TTVmax:=TimeTable[StationIndex+1].vmax; //Ra: nowa prêdkoœæ rozk³adowa na kolejnym odcinku
|
||||
end
|
||||
else //gdy ostatnia stacja
|
||||
NextStationName:=''; //nie ma nastêpnej stacji
|
||||
OK:=true;
|
||||
end;
|
||||
end;
|
||||
UpdateMTable:=OK; {czy jest nastepna stacja}
|
||||
end;
|
||||
|
||||
procedure TTrainParameters.StationIndexInc();
|
||||
begin
|
||||
Inc(StationIndex); //przejœcie do nastêpnej pozycji StationIndex<=StationCount
|
||||
end;
|
||||
|
||||
function TTrainParameters.IsTimeToGo(hh,mm:real):boolean;
|
||||
//sprawdzenie, czy mo¿na ju¿ odjechaæ z aktualnego zatrzymania
|
||||
//StationIndex to numer nastêpnego po dodarciu do aktualnego
|
||||
begin
|
||||
if (StationIndex<1) then
|
||||
IsTimeToGo:=true //przed pierwsz¹ jechaæ
|
||||
else if (StationIndex<StationCount) then
|
||||
begin //oprócz ostatniego przystanku
|
||||
if (TimeTable[StationIndex].Ah<0) then //odjazd z poprzedniego
|
||||
IsTimeToGo:=true //czas przyjazdu nie by³ podany - przelot
|
||||
else
|
||||
IsTimeToGo:=CompareTime(hh,mm,TimeTable[StationIndex].Dh,TimeTable[StationIndex].Dm)<=0;
|
||||
end
|
||||
else //gdy rozk³ad siê skoñczy³
|
||||
IsTimeToGo:=false; //dalej nie jechaæ
|
||||
end;
|
||||
|
||||
function TTrainParameters.ShowRelation:string;
|
||||
{zwraca informacjê o relacji}
|
||||
begin
|
||||
//if (Relation1=TimeTable[1].StationName) and (Relation2=TimeTable[StationCount].StationName)
|
||||
if (Relation1<>'') and (Relation2<>'')
|
||||
then ShowRelation:=Relation1+' - '+Relation2
|
||||
else ShowRelation:='';
|
||||
end;
|
||||
|
||||
constructor TTrainParameters.Init(NewTrainName:string);
|
||||
{wstêpne ustawienie parametrów rozk³adu jazdy}
|
||||
begin
|
||||
NewName(NewTrainName);
|
||||
end;
|
||||
|
||||
procedure TTrainParameters.NewName(NewTrainName:string);
|
||||
{wstêpne ustawienie parametrów rozk³adu jazdy}
|
||||
var i:integer;
|
||||
begin
|
||||
TrainName:=NewTrainName;
|
||||
StationCount:=0;
|
||||
StationIndex:=0;
|
||||
NextStationName:='nowhere';
|
||||
LastStationLatency:=0;
|
||||
Direction:=1;
|
||||
Relation1:=''; Relation2:='';
|
||||
for i:=0 to MaxTTableSize do
|
||||
with timeTable[i] do
|
||||
begin
|
||||
km:=0; vmax:=-1; StationName:='nowhere'; StationWare:='';
|
||||
TrackNo:=1; Ah:=-1; Am:=-1; Dh:=-1; Dm:=-1; tm:=0; WaitTime:=0;
|
||||
end;
|
||||
TTVmax:=100; {wykasowac}
|
||||
end;
|
||||
|
||||
function TTrainParameters.LoadTTfile(scnpath:string;iPlus:Integer;vMax:real):boolean;
|
||||
//wczytanie pliku-tabeli z rozk³adem przesuniêtym o (fPlus); (vMax) nie ma znaczenia
|
||||
var
|
||||
lines,s:string;
|
||||
fin:text;
|
||||
EndTable:boolean;
|
||||
vActual:real;
|
||||
i,time:Integer; //do zwiêkszania czasu
|
||||
|
||||
procedure UpdateVelocity(StationCount:integer;vActual:real);
|
||||
//zapisywanie prêdkoœci maksymalnej do wczeœniejszych odcinków
|
||||
//wywo³ywane z numerem ostatniego przetworzonego przystanku
|
||||
var i:integer;
|
||||
begin
|
||||
i:=StationCount;
|
||||
//TTVmax:=vActual; {PROWIZORKA!!!}
|
||||
while (i>=0) and (TimeTable[i].vmax=-1) do
|
||||
begin
|
||||
TimeTable[i].vmax:=vActual; //prêdkoœæ dojazdu do przystanku i
|
||||
dec(i); //ewentualnie do poprzedniego te¿
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
ClearPendingExceptions;
|
||||
ConversionError:=0;
|
||||
EndTable:=False;
|
||||
if (TrainName='') then
|
||||
begin //jeœli pusty rozk³ad
|
||||
//UpdateVelocity(StationCount,vMax); //ograniczenie do prêdkoœci startowej
|
||||
end
|
||||
else
|
||||
begin
|
||||
ConversionError:=666;
|
||||
vActual:=-1;
|
||||
s:=scnpath+TrainName+'.txt';
|
||||
//Ra 2014-09: ustaliæ zasady wyznaczenia pierwotnego pliku przy przesuniêtych rozk³adach (kolejny poci¹g dostaje numer +2)
|
||||
assignfile(fin,s);
|
||||
s:='';
|
||||
{$I-}
|
||||
reset(fin);
|
||||
{$I+}
|
||||
if IOresult<>0 then
|
||||
begin
|
||||
vMax:=s2r(TrainName); //nie ma pliku ale jest liczba
|
||||
if (vMax>10)and(vMax<200) then
|
||||
begin
|
||||
TTVmax:=vMax; //Ra 2014-07: zamiast rozk³adu mo¿na podaæ Vmax
|
||||
UpdateVelocity(StationCount,vMax); //ograniczenie do prêdkoœci startowej
|
||||
ConversionError:=0;
|
||||
end
|
||||
else
|
||||
ConversionError:=-8; {Ra: ten b³¹d jest niepotrzebny}
|
||||
end
|
||||
else
|
||||
begin {analiza rozk³adu jazdy}
|
||||
ConversionError:=0;
|
||||
while not (eof(fin) or (ConversionError<>0) or EndTable) do
|
||||
begin
|
||||
readln(fin,lines); {wczytanie linii}
|
||||
if Pos('___________________',lines)>0 then {linia pozioma górna}
|
||||
if ReadWord(fin)='[' then {lewy pion}
|
||||
if ReadWord(fin)='Rodzaj' then {"Rodzaj i numer pociagu"}
|
||||
repeat
|
||||
until (ReadWord(fin)='|') or (eof(fin)); {œrodkowy pion}
|
||||
s:=ReadWord(fin); {nazwa poci¹gu}
|
||||
//if LowerCase(s)<>ExtractFileName(TrainName) then {musi byæ taka sama, jak nazwa pliku}
|
||||
//ConversionError:=-7 {b³¹d niezgodnoœci}
|
||||
TrainName:=s; //nadanie nazwy z pliku TXT (bez œcie¿ki do pliku)
|
||||
//else
|
||||
begin {czytaj naglowek}
|
||||
repeat
|
||||
until (Pos('_______|',ReadWord(fin))>0) or eof(fin);
|
||||
repeat
|
||||
until (ReadWord(fin)='[') or (eof(fin)); {pierwsza linia z relacj¹}
|
||||
repeat
|
||||
s:=ReadWord(fin);
|
||||
until (s<>'|') or eof(fin);
|
||||
if s<>'|' then Relation1:=s
|
||||
else ConversionError:=-5;
|
||||
repeat
|
||||
until (Readword(fin)='Relacja') or (eof(fin)); {druga linia z relacj¹}
|
||||
repeat
|
||||
until (ReadWord(fin)='|') or (eof(fin));
|
||||
Relation2:=ReadWord(fin);
|
||||
repeat
|
||||
until Readword(fin)='Wymagany';
|
||||
repeat
|
||||
until (ReadWord(fin)='|') or (eoln(fin));
|
||||
s:=ReadWord(fin);
|
||||
s:=Copy(s,1,Pos('%',s)-1);
|
||||
BrakeRatio:=s2rE(s);
|
||||
repeat
|
||||
until Readword(fin)='Seria';
|
||||
repeat
|
||||
until (ReadWord(fin)='|') or (eof(fin));
|
||||
LocSeries:=ReadWord(fin);
|
||||
LocLoad:=s2rE(ReadWord(fin));
|
||||
repeat
|
||||
until (Pos('[______________',ReadWord(fin))>0) or (eof(fin));
|
||||
while not eof(fin) and not EndTable do
|
||||
begin
|
||||
inc(StationCount);
|
||||
repeat
|
||||
s:=ReadWord(fin);
|
||||
until (s='[') or (eof(fin));
|
||||
with TimeTable[StationCount] do
|
||||
begin
|
||||
if s='[' then
|
||||
s:=ReadWord(fin)
|
||||
else ConversionError:=-4;
|
||||
if Pos('|',s)=0 then
|
||||
begin
|
||||
km:=s2rE(s);
|
||||
s:=ReadWord(fin);
|
||||
end;
|
||||
if Pos('|_____|',s)>0 then {zmiana predkosci szlakowej}
|
||||
UpdateVelocity(StationCount,vActual)
|
||||
else
|
||||
begin
|
||||
s:=ReadWord(fin);
|
||||
if Pos('|',s)=0 then
|
||||
vActual:=s2rE(s);
|
||||
end;
|
||||
while Pos('|',s)=0 do
|
||||
s:=Readword(fin);
|
||||
StationName:=ReadWord(fin);
|
||||
repeat
|
||||
s:=ReadWord(fin);
|
||||
until (s='1') or (s='2') or eof(fin);
|
||||
TrackNo:=s2bE(s);
|
||||
s:=ReadWord(fin);
|
||||
if s<>'|' then
|
||||
begin
|
||||
if Pos(hrsd,s)>0 then
|
||||
begin
|
||||
ah:=s2iE(Copy(s,1,Pos(hrsd,s)-1)); //godzina przyjazdu
|
||||
am:=s2iE(Copy(s,Pos(hrsd,s)+1,Length(s))); //minuta przyjazdu
|
||||
end
|
||||
else
|
||||
begin
|
||||
ah:=TimeTable[StationCount-1].ah; //godzina z poprzedniej pozycji
|
||||
am:=s2iE(s); //bo tylko minuty podane
|
||||
end;
|
||||
end;
|
||||
repeat
|
||||
s:=ReadWord(fin);
|
||||
until (s<>'|') or (eof(fin));
|
||||
if s<>']' then
|
||||
tm:=s2rE(s);
|
||||
repeat
|
||||
s:=ReadWord(fin);
|
||||
until (s='[') or eof(fin);
|
||||
s:=ReadWord(fin);
|
||||
if Pos('|',s)=0 then
|
||||
begin
|
||||
{tu s moze byc miejscem zmiany predkosci szlakowej}
|
||||
s:=ReadWord(fin);
|
||||
end;
|
||||
if Pos('|_____|',s)>0 then {zmiana predkosci szlakowej}
|
||||
UpdateVelocity(StationCount,vActual)
|
||||
else
|
||||
begin
|
||||
s:=ReadWord(fin);
|
||||
if Pos('|',s)=0 then
|
||||
vActual:=s2rE(s);
|
||||
end;
|
||||
while Pos('|',s)=0 do
|
||||
s:=Readword(fin);
|
||||
StationWare:=ReadWord(fin);
|
||||
repeat
|
||||
s:=ReadWord(fin);
|
||||
until (s='1') or (s='2') or eof(fin);
|
||||
TrackNo:=s2bE(s);
|
||||
s:=ReadWord(fin);
|
||||
if s<>'|' then
|
||||
begin
|
||||
if Pos(hrsd,s)>0 then
|
||||
begin
|
||||
dh:=s2iE(Copy(s,1,Pos(hrsd,s)-1)); //godzina odjazdu
|
||||
dm:=s2iE(Copy(s,Pos(hrsd,s)+1,Length(s))); //minuta odjazdu
|
||||
end
|
||||
else
|
||||
begin
|
||||
dh:=TimeTable[StationCount-1].dh; //godzina z poprzedniej pozycji
|
||||
dm:=s2iE(s); //bo tylko minuty podane
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
dh:=ah; //odjazd o tej samej, co przyjazd (dla ostatniego te¿)
|
||||
dm:=am; //bo s¹ u¿ywane do wyliczenia opóŸnienia po dojechaniu
|
||||
end;
|
||||
if (ah>=0) then
|
||||
WaitTime:=Trunc(CompareTime(ah,am,dh,dm)+0.1);
|
||||
repeat
|
||||
s:=ReadWord(fin);
|
||||
until (s<>'|') or (eof(fin));
|
||||
if s<>']' then
|
||||
tm:=s2rE(s);
|
||||
repeat
|
||||
s:=ReadWord(fin);
|
||||
until (Pos('[',s)>0) or eof(fin);
|
||||
if Pos('_|_',s)=0 then
|
||||
s:=Readword(fin);
|
||||
if Pos('|',s)=0 then
|
||||
begin
|
||||
{tu s moze byc miejscem zmiany predkosci szlakowej}
|
||||
s:=ReadWord(fin);
|
||||
end;
|
||||
if Pos('|_____|',s)>0 then {zmiana predkosci szlakowej}
|
||||
UpdateVelocity(StationCount,vActual)
|
||||
else
|
||||
begin
|
||||
s:=ReadWord(fin);
|
||||
if Pos('|',s)=0 then
|
||||
vActual:=s2rE(s);
|
||||
end;
|
||||
while Pos('|',s)=0 do
|
||||
s:=Readword(fin);
|
||||
while (Pos(']',s)=0) do
|
||||
s:=ReadWord(fin);
|
||||
if Pos('_|_',s)>0 then EndTable:=True;
|
||||
end; {timetableline}
|
||||
end;
|
||||
end;
|
||||
end; {while eof}
|
||||
close(fin);
|
||||
end;
|
||||
end;
|
||||
if ConversionError=0 then
|
||||
begin
|
||||
if (TimeTable[1].StationName=Relation1) then //jeœli nazwa pierwszego zgodna z relacj¹
|
||||
if (TimeTable[1].Ah<0) then //a nie podany czas przyjazdu
|
||||
begin //to mamy zatrzymanie na pierwszym, a nie przelot
|
||||
TimeTable[1].Ah:=TimeTable[1].Dh;
|
||||
TimeTable[1].Am:=TimeTable[1].Dm;
|
||||
end
|
||||
//NextStationName:=TimeTable[1].StationName;
|
||||
{ TTVmax:=TimeTable[1].vmax; }
|
||||
end;
|
||||
if (iPlus<>0) then //je¿eli jest przesuniêcie rozk³adu
|
||||
for i:=1 to StationCount do //bez with, bo ciê¿ko siê przenosi na C++
|
||||
begin
|
||||
if (TimeTable[i].Ah>=0) then
|
||||
begin
|
||||
time:=iPlus+TimeTable[i].Ah*60+TimeTable[i].Am; //nowe minuty
|
||||
TimeTable[i].Am:=time mod 60;
|
||||
TimeTable[i].Ah:=(time div 60) mod 60;
|
||||
end;
|
||||
if (TimeTable[i].Dh>=0) then
|
||||
begin
|
||||
time:=iPlus+TimeTable[i].Dh*60+TimeTable[i].Dm; //nowe minuty
|
||||
TimeTable[i].Dm:=time mod 60;
|
||||
TimeTable[i].Dh:=(time div 60) mod 60;
|
||||
end;
|
||||
end;
|
||||
LoadTTfile:=(ConversionError=0);
|
||||
end;
|
||||
|
||||
procedure TMTableTime.UpdateMTableTime(deltaT:real);
|
||||
//dodanie czasu (deltaT) w sekundach, z przeliczeniem godziny
|
||||
begin
|
||||
mr:=mr+deltaT; //dodawanie sekund
|
||||
while mr>60.0 do //przeliczenie sekund do w³aœciwego przedzia³u
|
||||
begin
|
||||
mr:=mr-60.0;
|
||||
inc(mm);
|
||||
end;
|
||||
while mm>59 do //przeliczenie minut do w³aœciwego przedzia³u
|
||||
begin
|
||||
mm:=mm-60;
|
||||
inc(hh);
|
||||
end;
|
||||
while hh>23 do //przeliczenie godzin do w³aœciwego przedzia³u
|
||||
begin
|
||||
hh:=hh-24;
|
||||
inc(dd); //zwiêkszenie numeru dnia
|
||||
end;
|
||||
GameTime:=GameTime+deltaT;
|
||||
end;
|
||||
|
||||
constructor TMTableTime.Init(InitH,InitM,InitSRH,InitSRM,InitSSH,InitSSM:integer);
|
||||
begin
|
||||
GameTime:=0.0;
|
||||
dd:=0;
|
||||
hh:=InitH;
|
||||
mm:=InitM;
|
||||
srh:=InitSRH;
|
||||
srm:=InitSRM;
|
||||
ssh:=InitSSH;
|
||||
ssm:=InitSSM;
|
||||
end;
|
||||
|
||||
function TTrainParameters.DirectionChange():boolean;
|
||||
//sprawdzenie, czy po zatrzymaniu wykonaæ kolejne komendy
|
||||
begin
|
||||
DirectionChange:=false; //przed pierwsz¹ bez zmiany
|
||||
if (StationIndex>0) and (StationIndex<StationCount) then //dla ostatniej stacji nie
|
||||
if (Pos('@',TimeTable[StationIndex].StationWare)>0) then
|
||||
DirectionChange:=true;
|
||||
end;
|
||||
|
||||
|
||||
END.
|
||||
|
||||
338
McZapkie/unit2.pas
Normal file
338
McZapkie/unit2.pas
Normal file
@@ -0,0 +1,338 @@
|
||||
unit Unit1;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
ai_driver,mtable,mover,mctools,Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
|
||||
StdCtrls, ExtCtrls;
|
||||
|
||||
type
|
||||
TForm1 = class(TForm)
|
||||
Button1: TButton;
|
||||
Label1: TLabel;
|
||||
Button2: TButton;
|
||||
Button3: TButton;
|
||||
Button4: TButton;
|
||||
Button5: TButton;
|
||||
Button6: TButton;
|
||||
Label2: TLabel;
|
||||
Label3: TLabel;
|
||||
Timer1: TTimer;
|
||||
Label4: TLabel;
|
||||
Label5: TLabel;
|
||||
Label6: TLabel;
|
||||
Label7: TLabel;
|
||||
Label8: TLabel;
|
||||
Label9: TLabel;
|
||||
Label10: TLabel;
|
||||
Label11: TLabel;
|
||||
Button7: TButton;
|
||||
Button8: TButton;
|
||||
Label12: TLabel;
|
||||
Label13: TLabel;
|
||||
Label14: TLabel;
|
||||
Label15: TLabel;
|
||||
Button9: TButton;
|
||||
Button10: TButton;
|
||||
Label16: TLabel;
|
||||
Label17: TLabel;
|
||||
Label18: TLabel;
|
||||
Label19: TLabel;
|
||||
Button11: TButton;
|
||||
Label20: TLabel;
|
||||
Label21: TLabel;
|
||||
Label22: TLabel;
|
||||
Label23: TLabel;
|
||||
Label24: TLabel;
|
||||
Label25: TLabel;
|
||||
lczas: TLabel;
|
||||
Label26: TLabel;
|
||||
Label27: TLabel;
|
||||
Label28: TLabel;
|
||||
Label29: TLabel;
|
||||
Label30: TLabel;
|
||||
Label31: TLabel;
|
||||
Label32: TLabel;
|
||||
Label33: TLabel;
|
||||
Label34: TLabel;
|
||||
Button12: TButton;
|
||||
BStart: TButton;
|
||||
Label35: TLabel;
|
||||
Label36: TLabel;
|
||||
Label37: TLabel;
|
||||
Label38: TLabel;
|
||||
Button13: TButton;
|
||||
Label39: TLabel;
|
||||
Label40: TLabel;
|
||||
Label41: TLabel;
|
||||
Button14: TButton;
|
||||
Button15: TButton;
|
||||
Label42: TLabel;
|
||||
Label43: TLabel;
|
||||
procedure Button1Click(Sender: TObject);
|
||||
procedure Button2Click(Sender: TObject);
|
||||
procedure Timer1Timer(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure Button5Click(Sender: TObject);
|
||||
procedure Button6Click(Sender: TObject);
|
||||
procedure Button7Click(Sender: TObject);
|
||||
procedure Button8Click(Sender: TObject);
|
||||
procedure Button3Click(Sender: TObject);
|
||||
procedure Button4Click(Sender: TObject);
|
||||
procedure Button9Click(Sender: TObject);
|
||||
procedure Button10Click(Sender: TObject);
|
||||
procedure Button11Click(Sender: TObject);
|
||||
procedure Button12Click(Sender: TObject);
|
||||
procedure BStartClick(Sender: TObject);
|
||||
procedure Button13MouseDown(Sender: TObject; Button: TMouseButton;
|
||||
Shift: TShiftState; X, Y: Integer);
|
||||
procedure Button14Click(Sender: TObject);
|
||||
procedure Button15Click(Sender: TObject);
|
||||
private
|
||||
{ Private declarations }
|
||||
public
|
||||
{ Public declarations }
|
||||
end;
|
||||
|
||||
var
|
||||
Form1: TForm1;
|
||||
loc,wag,wag2,wag3:TMoverParameters;
|
||||
mechanik: TController;
|
||||
pociag: TTrainParameters;
|
||||
l0,l1,l2,l3:TLocation;
|
||||
r0,r1,r2,r3:TRotation;
|
||||
Shape:TTrackShape; Track:TTrackParam;
|
||||
ExternalVoltage:real;
|
||||
ActualTime:real;
|
||||
fout: text;
|
||||
|
||||
implementation
|
||||
|
||||
{$R *.DFM}
|
||||
|
||||
procedure TForm1.Button1Click(Sender: TObject);
|
||||
begin
|
||||
assignfile(fout,'log.dat');
|
||||
rewrite(fout);
|
||||
ActualTime:=0;
|
||||
loc:=TMoverParameters.Create;
|
||||
wag:=TMoverParameters.Create;
|
||||
wag2:=TMoverParameters.Create;
|
||||
wag3:=TMoverParameters.Create;
|
||||
mechanik:=TController.Create;
|
||||
pociag:=TTrainParameters.Create;
|
||||
Shape.R:=0; Shape.Len:=10000; Shape.dHtrack:=0; Shape.dHrail:=0;
|
||||
Track.Width:=1435; Track.friction:=0.15; Track.CategoryFlag:=1;
|
||||
Track.QualityFlag:=25; Track.DamageFlag:=0;
|
||||
Track.VelMax:=120;
|
||||
ExternalVoltage:=3000;
|
||||
l0.x:=0; l0.y:=0; l0.z:=0;
|
||||
l1.x:=-14.0235; l1.y:=0; l1.z:=0;
|
||||
l2.x:=-27.3634; l2.y:=0; l2.z:=0;
|
||||
l3.x:=-40.7032; l3.y:=0; l3.z:=0;
|
||||
r0.rx:=0; r0.ry:=0; r0.rz:=0;
|
||||
r1.rx:=0; r1.ry:=0; r1.rz:=0;
|
||||
r2.rx:=0; r2.ry:=0; r2.rz:=0;
|
||||
r3.rx:=0; r3.ry:=0; r3.rz:=0;
|
||||
{ loc.Init(l1,r1,0,'en57','456',0,'Human',1); }
|
||||
loc.Init(l0,r0,60,'eu07','456',0,'',1);
|
||||
wag.Init(l1,r1,60,'Falns_440v','52-51-342027-2',30,'',0);
|
||||
wag2.Init(l2,r2,60,'Falns_440v','52-51-322311-5',30,'',0);
|
||||
wag3.Init(l3,r3,60,'Falns_440v','52-51-410025-3',30,'',0);
|
||||
pociag.init('Testowy Express',100);
|
||||
mechanik.init(l1,r1,True,@loc,@pociag,Aggressive);
|
||||
if (loc.loadchkfile('') and wag.loadchkfile('') and wag2.loadchkfile('') and wag3.loadchkfile(''))
|
||||
and (loc.CheckLocomotiveParameters(Go) and wag.CheckLocomotiveParameters(Go) and wag2.CheckLocomotiveParameters(Go) and wag3.CheckLocomotiveParameters(Go)) then
|
||||
begin
|
||||
Label1.Caption:='OK';
|
||||
loc.attach(2,@wag,3);
|
||||
wag.attach(1,@loc,3);
|
||||
wag.attach(2,@wag2,3);
|
||||
wag2.attach(1,@wag,3);
|
||||
wag2.attach(2,@wag3,3);
|
||||
wag3.attach(1,@wag2,3);
|
||||
Timer1.Enabled:=True;
|
||||
end
|
||||
else Label1.Caption:=inttostr(conversionerror)+' '+inttostr(linecount);
|
||||
Button1.Visible:=False;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button2Click(Sender: TObject);
|
||||
begin
|
||||
if Timer1.Enabled then
|
||||
begin
|
||||
Timer1.Enabled:=False;
|
||||
CloseFile(fout);
|
||||
end;
|
||||
loc.Free;
|
||||
wag.Free;
|
||||
wag2.free;
|
||||
wag3.free;
|
||||
mechanik.free;
|
||||
Close;
|
||||
end;
|
||||
|
||||
procedure TForm1.Timer1Timer(Sender: TObject);
|
||||
var dl,dt:real;
|
||||
begin
|
||||
dt:=Timer1.Interval/1000;
|
||||
ActualTime:=ActualTime+dt;
|
||||
loc.ComputeTotalForce(dt,Shape,Track,ExternalVoltage);
|
||||
wag.ComputeTotalForce(dt,Shape,Track,ExternalVoltage);
|
||||
wag2.ComputeTotalForce(dt,Shape,Track,ExternalVoltage);
|
||||
wag3.ComputeTotalForce(dt,Shape,Track,ExternalVoltage);
|
||||
dl:=loc.ComputeMovement(dt,Shape,Track,ExternalVoltage,l0,r0);
|
||||
l0.x:=l0.x+dl;
|
||||
dl:=wag.ComputeMovement(dt,Shape,Track,ExternalVoltage,l1,r1);
|
||||
l1.x:=l1.x+dl;
|
||||
dl:=wag2.ComputeMovement(dt,Shape,Track,ExternalVoltage,l2,r2);
|
||||
l2.x:=l2.x+dl;
|
||||
dl:=wag3.ComputeMovement(dt,Shape,Track,ExternalVoltage,l3,r3);
|
||||
l3.x:=l3.x+dl;
|
||||
|
||||
if l0.x<500 then mechanik.UpdateSituation(500-l0.x,dt)
|
||||
else
|
||||
if l0.x<2500 then mechanik.UpdateSituation(-1,dt)
|
||||
else
|
||||
if l0.x<3500 then mechanik.UpdateSituation(3500-l0.x,dt);
|
||||
if (l0.x>499) and (l0.x<505) then
|
||||
mechanik.SetVelocity(-1,-1,0);
|
||||
if (l0.x>2499) and (l0.x<2510) then
|
||||
mechanik.SetVelocity(-1,0,0);
|
||||
|
||||
Label2.Caption:=r2s(Loc.Im,0)+' A';
|
||||
Label3.Caption:=r2s(Loc.Ft/1000,0)+' kN';
|
||||
Label4.Caption:=r2s(l0.x,0)+' m';
|
||||
Label5.Caption:=r2s(Sign(Loc.V)*Loc.Vel,0)+' km/h';
|
||||
Label6.Caption:=r2s(Loc.AccS,0)+' m/ss';
|
||||
Label7.Caption:=r2s(Loc.couplers[1].cforce/1000,0)+' kN';
|
||||
Label8.Caption:=r2s(Loc.couplers[2].cforce/1000,0)+' kN';
|
||||
Label9.Caption:=r2s(Loc.Fb/1000,0)+' kN';
|
||||
Label10.Caption:=r2s(Loc.Compressor,0)+' MPa';
|
||||
Label11.Caption:=r2s(Loc.PipePress,0)+' MPa';
|
||||
Label12.Caption:=r2s(Loc.BrakePress,0)+' MPa';
|
||||
|
||||
Label13.Caption:=IntToStr(Loc.MainCtrlPos);
|
||||
Label14.Caption:=IntToStr(Loc.BrakeCtrlPos);
|
||||
Label15.Caption:=IntToStr(Loc.LocalBrakePos);
|
||||
|
||||
Label16.Caption:=IntToStr(Loc.showcurrent(1));
|
||||
Label17.Caption:=IntToStr(Loc.showcurrent(2));
|
||||
Label18.Caption:=IntToStr(Loc.ScndCtrlPos);
|
||||
if loc.SlippingWheels then
|
||||
Label19.Caption:='Poslizg!'
|
||||
else Label19.Caption:=' ';
|
||||
|
||||
Label20.Caption:=IntToStr(Loc.MainCtrlActualPos);
|
||||
Label21.Caption:=IntToStr(Loc.ScndCtrlActualPos);
|
||||
|
||||
Label22.Caption:=r2s(l1.x,0)+' m';
|
||||
Label23.Caption:=r2s(Sign(wag.V)*wag.Vel,0)+' km/h';
|
||||
Label24.Caption:=r2s(Distance(loc.loc,wag.loc,loc.dim,wag.dim),0)+' m';
|
||||
Label25.Caption:=r2s(loc.nrot,0)+' 1/s';
|
||||
|
||||
Label26.Caption:=r2s(wag.couplers[1].cforce/1000,0)+' kN';
|
||||
Label27.Caption:=r2s(wag.couplers[2].cforce/1000,0)+' kN';
|
||||
|
||||
Label28.Caption:=r2s(l2.x,0)+' m';
|
||||
Label29.Caption:=r2s(sign(wag2.V)*wag2.Vel,0)+' km/h';
|
||||
|
||||
Label30.Caption:=r2s(loc.dpLocalValve/dt,0)+' MPa/s';
|
||||
Label31.Caption:=r2s(loc.dpBrake/dt,0)+' MPa/s';
|
||||
Label32.Caption:=r2s(loc.dpMainValve/dt,0)+' MPa/s';
|
||||
Label33.Caption:=r2s(loc.dpPipe/dt,0)+' MPa/s';
|
||||
|
||||
Label34.Caption:=r2s(wag2.PipePress,0)+' MPa';
|
||||
|
||||
Label35.Caption:=r2s(l3.x,0)+' m';
|
||||
Label36.Caption:=r2s(sign(wag3.V)*wag3.Vel,0)+' km/h';
|
||||
Label37.Caption:=r2s(wag3.couplers[1].cforce/1000,0)+' kN';
|
||||
Label38.Caption:=r2s(wag3.brakepress,0)+' MPa';
|
||||
|
||||
Label39.Caption:=r2s(loc.enginePower/1000,0)+' kW';
|
||||
Label40.Caption:=i2s(trunc(loc.Rventrot*60))+' /min';
|
||||
Label41.Visible:=loc.SandDose;
|
||||
Label42.Caption:=r2s(mechanik.accdesired,0)+' m/ss';
|
||||
Label43.Caption:=r2s(mechanik.veldesired,0)+' km/h';
|
||||
Lczas.Caption:=r2s(actualtime,0)+' s';
|
||||
end;
|
||||
|
||||
procedure TForm1.FormCreate(Sender: TObject);
|
||||
begin
|
||||
Timer1.Enabled:=False;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button5Click(Sender: TObject);
|
||||
begin
|
||||
loc.incbrakelevel(1);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button6Click(Sender: TObject);
|
||||
begin
|
||||
loc.decbrakelevel(1);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button7Click(Sender: TObject);
|
||||
begin
|
||||
loc.inclocalbrakelevel(1);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button8Click(Sender: TObject);
|
||||
begin
|
||||
loc.declocalbrakelevel(1);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button3Click(Sender: TObject);
|
||||
begin
|
||||
loc.incmainctrl(1);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button4Click(Sender: TObject);
|
||||
begin
|
||||
loc.decmainctrl(1);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button9Click(Sender: TObject);
|
||||
begin
|
||||
loc.DirectionForward;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button10Click(Sender: TObject);
|
||||
begin
|
||||
loc.DirectionBackward;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button11Click(Sender: TObject);
|
||||
begin
|
||||
loc.FuseOn;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button12Click(Sender: TObject);
|
||||
begin
|
||||
Loc.AntiSlippingBrake;
|
||||
end;
|
||||
|
||||
procedure TForm1.BStartClick(Sender: TObject);
|
||||
begin
|
||||
loc.activedir:=1;
|
||||
{ if mechanik.OrderDirectionChange(1) then }
|
||||
mechanik.SetVelocity(60,0,0);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button13MouseDown(Sender: TObject; Button: TMouseButton;
|
||||
Shift: TShiftState; X, Y: Integer);
|
||||
begin
|
||||
loc.SandDoseOn;
|
||||
end;
|
||||
|
||||
procedure TForm1.Button14Click(Sender: TObject);
|
||||
begin
|
||||
mechanik.SetVelocity(30,120,0);
|
||||
end;
|
||||
|
||||
procedure TForm1.Button15Click(Sender: TObject);
|
||||
begin
|
||||
mechanik.SetVelocity(0,120,0);
|
||||
end;
|
||||
|
||||
end.
|
||||
182
MdlMngr.cpp
Normal file
182
MdlMngr.cpp
Normal file
@@ -0,0 +1,182 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak and others
|
||||
|
||||
*/
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#include "Texture.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "MdlMngr.h"
|
||||
#include "Globals.h"
|
||||
|
||||
#define SeekFiles AnsiString("*.t3d")
|
||||
|
||||
TModel3d* __fastcall TMdlContainer::LoadModel(char *newName,bool dynamic)
|
||||
{//wczytanie modelu do kontenerka
|
||||
SafeDeleteArray(Name);
|
||||
SafeDelete(Model);
|
||||
Name=new char[strlen(newName)+1];
|
||||
strcpy(Name,newName);
|
||||
Model=new TModel3d();
|
||||
if (!Model->LoadFromFile(Name,dynamic)) //np. "models\\pkp/head1-y.t3d"
|
||||
SafeDelete(Model);
|
||||
return Model;
|
||||
};
|
||||
|
||||
TMdlContainer *TModelsManager::Models;
|
||||
int TModelsManager::Count;
|
||||
const MAX_MODELS=1000;
|
||||
|
||||
void __fastcall TModelsManager::Init()
|
||||
{
|
||||
Models=new TMdlContainer[MAX_MODELS];
|
||||
Count=0;
|
||||
}
|
||||
/*
|
||||
__fastcall TModelsManager::TModelsManager()
|
||||
{
|
||||
// Models= NULL;
|
||||
Models= new TMdlContainer[MAX_MODELS];
|
||||
Count= 0;
|
||||
};
|
||||
|
||||
__fastcall TModelsManager::~TModelsManager()
|
||||
{
|
||||
Free();
|
||||
};
|
||||
*/
|
||||
void __fastcall TModelsManager::Free()
|
||||
{
|
||||
SafeDeleteArray(Models);
|
||||
}
|
||||
|
||||
|
||||
TModel3d* __fastcall TModelsManager::LoadModel(char *Name,bool dynamic)
|
||||
{//wczytanie modelu do tablicy
|
||||
TModel3d *mdl=NULL;
|
||||
if (Count>=MAX_MODELS)
|
||||
Error("FIXME: Too many models, program will now crash :)");
|
||||
else
|
||||
{
|
||||
mdl=Models[Count].LoadModel(Name,dynamic);
|
||||
if (mdl) Count++; //jeśli błąd wczytania modelu, to go nie wliczamy
|
||||
}
|
||||
return mdl;
|
||||
}
|
||||
|
||||
TModel3d* __fastcall 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 są 2
|
||||
//dla "node...model" może być typowy model statyczny ze ścieżką, domyślnie w "\scenery\" albo "\models"
|
||||
//albo może być model z "\dynamic\", jeśli potrzebujemy wstawić auto czy wagon nieruchomo
|
||||
// - ze ścieżki z której jest wywołany, np. dir="scenery\bud\" albo dir="dynamic\pkp\st44_v1\" plus name="model.t3d"
|
||||
// - z domyślnej ścieżki dla modeli, np. "scenery\" albo "models\" plus name="bud\dombale.t3d" (dir="")
|
||||
// - konkretnie podanej ścieżki np. name="\scenery\bud\dombale.t3d" (dir="")
|
||||
//wywołania:
|
||||
// - konwersja wszystkiego do E3D, podawana dokładna ścieżka, tekstury tam, gdzie plik
|
||||
// - wczytanie kabiny, dokładna ścieżka, tekstury z katalogu modelu
|
||||
// - wczytanie ładunku, ścieżka dokładna, tekstury z katalogu modelu
|
||||
// - wczytanie modelu, ścieżka dokładna, tekstury z katalogu modelu
|
||||
// - wczytanie przedsionków, ścieżka dokładna, tekstury z katalogu modelu
|
||||
// - wczytanie uproszczonego wnętrza, ścieżka dokładna, tekstury z katalogu modelu
|
||||
// - niebo animowane, ścieżka brana ze wpisu, tekstury nieokreślone
|
||||
// - wczytanie modelu animowanego - Init() - sprawdzić
|
||||
char buf[255];
|
||||
AnsiString buftp=Global::asCurrentTexturePath; //zapamiętanie aktualnej ścieżki do tekstur, bo będzie tyczmasowo zmieniana
|
||||
/*
|
||||
// Ra: niby tak jest lepiej, ale działa gorzej, więc przywrócone jest oryginalne
|
||||
//nawet jeśli model będzie pobrany z tablicy, to trzeba ustalić ścieżkę dla tekstur
|
||||
if (dynamic) //na razie tak, bo nie wiadomo, jaki może mieć wpływ na pozostałe modele
|
||||
{//dla pojazdów podana jest zawsze pełna ścieżka do modelu
|
||||
strcpy(buf,Name);
|
||||
if (strchr(Name,'/')!=NULL)
|
||||
{//pobieranie tekstur z katalogu, w którym jest model
|
||||
Global::asCurrentTexturePath=Global::asCurrentTexturePath+AnsiString(Name);
|
||||
Global::asCurrentTexturePath.Delete(Global::asCurrentTexturePath.Pos("/")+1,Global::asCurrentTexturePath.Length());
|
||||
}
|
||||
}
|
||||
else
|
||||
{//dla modeli scenerii trzeba ustalić ścieżkę
|
||||
if (strchr(Name,'\\')==NULL)
|
||||
{//jeśli nie ma lewego ukośnika w ścieżce, a jest prawy, to zmienić ścieżkę dla tekstur na tę z modelem
|
||||
strcpy(buf,"models\\"); //Ra: było by lepiej katalog dodać w parserze
|
||||
//strcpy(buf,"scenery\\"); //Ra: było by lepiej katalog dodać w parserze
|
||||
strcat(buf,Name);
|
||||
if (strchr(Name,'/')!=NULL)
|
||||
{//jeszcze musi być prawy ukośnik
|
||||
Global::asCurrentTexturePath=Global::asCurrentTexturePath+AnsiString(Name);
|
||||
Global::asCurrentTexturePath.Delete(Global::asCurrentTexturePath.Pos("/")+1,Global::asCurrentTexturePath.Length());
|
||||
}
|
||||
}
|
||||
else
|
||||
{//jeśli jest lewy ukośnik, to ścieżkę do tekstur zmienić tylko dla pojazdów
|
||||
strcpy(buf,Name);
|
||||
}
|
||||
}
|
||||
StrLower(buf);
|
||||
for (int i=0;i<Count;i++)
|
||||
{//bezsensowne przeszukanie tabeli na okoliczność wystąpienia modelu
|
||||
if (strcmp(buf,Models[i].Name)==0)
|
||||
{
|
||||
Global::asCurrentTexturePath=buftp; //odtworzenie ścieżki do tekstur
|
||||
return (Models[i].Model); //model znaleziony
|
||||
}
|
||||
};
|
||||
*/
|
||||
if (strchr(Name,'\\')==NULL)
|
||||
{
|
||||
strcpy(buf,"models\\"); //Ra: było by lepiej katalog dodać w parserze
|
||||
strcat(buf,Name);
|
||||
if (strchr(Name,'/')!=NULL)
|
||||
{
|
||||
Global::asCurrentTexturePath= Global::asCurrentTexturePath+AnsiString(Name);
|
||||
Global::asCurrentTexturePath.Delete(Global::asCurrentTexturePath.Pos("/")+1,Global::asCurrentTexturePath.Length());
|
||||
}
|
||||
}
|
||||
else
|
||||
{strcpy(buf,Name);
|
||||
if (dynamic) //na razie tak, bo nie wiadomo, jaki może mieć wpływ na pozostałe modele
|
||||
if (strchr(Name,'/')!=NULL)
|
||||
{//pobieranie tekstur z katalogu, w którym jest model
|
||||
Global::asCurrentTexturePath= Global::asCurrentTexturePath+AnsiString(Name);
|
||||
Global::asCurrentTexturePath.Delete(Global::asCurrentTexturePath.Pos("/")+1,Global::asCurrentTexturePath.Length());
|
||||
}
|
||||
}
|
||||
StrLower(buf);
|
||||
for (int i=0; i<Count; i++)
|
||||
{
|
||||
if (strcmp(buf,Models[i].Name)==0)
|
||||
{
|
||||
Global::asCurrentTexturePath= buftp;
|
||||
return (Models[i].Model);
|
||||
}
|
||||
};
|
||||
TModel3d* tmpModel=LoadModel(buf,dynamic); //model nie znaleziony, to wczytać
|
||||
Global::asCurrentTexturePath=buftp; //odtworzenie ścieżki do tekstur
|
||||
return (tmpModel); //NULL jeśli błąd
|
||||
};
|
||||
|
||||
/*
|
||||
TModel3d __fastcall TModelsManager::GetModel(char *Name, AnsiString asReplacableTexture)
|
||||
{
|
||||
GLuint ReplacableTextureID= 0;
|
||||
TModel3d NewModel;
|
||||
|
||||
NewModel= *GetNextModel(Name);
|
||||
|
||||
if (asReplacableTexture!=AnsiString("none"))
|
||||
ReplacableTextureID= TTexturesManager::GetTextureID(asReplacableTexture.c_str());
|
||||
|
||||
NewModel.ReplacableSkinID=ReplacableTextureID;
|
||||
|
||||
return NewModel;
|
||||
};
|
||||
*/
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
34
MdlMngr.h
Normal file
34
MdlMngr.h
Normal file
@@ -0,0 +1,34 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef MdlMngrH
|
||||
#define MdlMngrH
|
||||
|
||||
|
||||
#include "Model3d.h"
|
||||
#include "usefull.h"
|
||||
|
||||
class TMdlContainer
|
||||
{
|
||||
friend class TModelsManager;
|
||||
__fastcall TMdlContainer() { Name= NULL; Model= NULL; };
|
||||
__fastcall ~TMdlContainer() { SafeDeleteArray(Name); SafeDelete(Model); };
|
||||
TModel3d* __fastcall LoadModel(char *newName,bool dynamic);
|
||||
TModel3d *Model;
|
||||
char *Name;
|
||||
};
|
||||
|
||||
class TModelsManager
|
||||
{//klasa statyczna, nie ma obiektu
|
||||
private:
|
||||
static TMdlContainer *Models;
|
||||
static int Count;
|
||||
static TModel3d* __fastcall LoadModel(char *Name,bool dynamic);
|
||||
public:
|
||||
// __fastcall TModelsManager();
|
||||
// __fastcall ~TModelsManager();
|
||||
static void __fastcall Init();
|
||||
static void __fastcall Free();
|
||||
//McZapkie: dodalem sciezke, notabene Path!=Patch :)
|
||||
static TModel3d* __fastcall GetModel(const char *Name,bool dynamic=false);
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
176
MemCell.cpp
Normal file
176
MemCell.cpp
Normal file
@@ -0,0 +1,176 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Driver.h"
|
||||
#include "mctools.hpp"
|
||||
#include "MemCell.h"
|
||||
#include "Event.h"
|
||||
#include "parser.h"
|
||||
|
||||
#include "Usefull.h"
|
||||
#include "Globals.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
__fastcall TMemCell::TMemCell(vector3 *p)
|
||||
{
|
||||
fValue1=fValue2=0;
|
||||
szText=new char[256]; //musi byæ dla automatycznie tworzonych komórek dla odcinków izolowanych
|
||||
vPosition=p?*p:vector3(0,0,0); //ustawienie wspó³rzêdnych, bo do TGroundNode nie ma dostêpu
|
||||
bCommand=false; //komenda wys³ana
|
||||
OnSent=NULL;
|
||||
}
|
||||
|
||||
__fastcall TMemCell::~TMemCell()
|
||||
{
|
||||
SafeDeleteArray(szText);
|
||||
}
|
||||
|
||||
void __fastcall TMemCell::Init()
|
||||
{
|
||||
}
|
||||
|
||||
void __fastcall TMemCell::UpdateValues(char *szNewText, double fNewValue1, double fNewValue2, int CheckMask)
|
||||
{
|
||||
if (CheckMask&update_memadd)
|
||||
{//dodawanie wartoœci
|
||||
if (TestFlag(CheckMask,update_memstring))
|
||||
strcat(szText,szNewText);
|
||||
if (TestFlag(CheckMask,update_memval1))
|
||||
fValue1+=fNewValue1;
|
||||
if (TestFlag(CheckMask,update_memval2))
|
||||
fValue2+=fNewValue2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TestFlag(CheckMask,update_memstring))
|
||||
strcpy(szText,szNewText);
|
||||
if (TestFlag(CheckMask,update_memval1))
|
||||
fValue1=fNewValue1;
|
||||
if (TestFlag(CheckMask,update_memval2))
|
||||
fValue2=fNewValue2;
|
||||
}
|
||||
if (TestFlag(CheckMask,update_memstring))
|
||||
CommandCheck();//jeœli zmieniony tekst, próbujemy rozpoznaæ komendê
|
||||
}
|
||||
|
||||
TCommandType __fastcall TMemCell::CommandCheck()
|
||||
{//rozpoznanie komendy
|
||||
if (strcmp(szText,"SetVelocity")==0) //najpopularniejsze
|
||||
{eCommand=cm_SetVelocity;
|
||||
bCommand=false; //ta komenda nie jest wysy³ana
|
||||
}
|
||||
else if (strcmp(szText,"ShuntVelocity")==0) //w tarczach manewrowych
|
||||
{eCommand=cm_ShuntVelocity;
|
||||
bCommand=false; //ta komenda nie jest wysy³ana
|
||||
}
|
||||
else if (strcmp(szText,"Change_direction")==0) //zdarza siê
|
||||
{eCommand=cm_ChangeDirection;
|
||||
bCommand=true; //do wys³ania
|
||||
}
|
||||
else if (strcmp(szText,"OutsideStation")==0) //zdarza siê
|
||||
{eCommand=cm_OutsideStation;
|
||||
bCommand=false; //tego nie powinno byæ w komórce
|
||||
}
|
||||
else if (strncmp(szText,"PassengerStopPoint:",19)==0) //porównanie pocz¹tków
|
||||
{eCommand=cm_PassengerStopPoint;
|
||||
bCommand=false; //tego nie powinno byæ w komórce
|
||||
}
|
||||
else if (strcmp(szText,"SetProximityVelocity")==0) //nie powinno tego byæ
|
||||
{eCommand=cm_SetProximityVelocity;
|
||||
bCommand=false; //ta komenda nie jest wysy³ana
|
||||
}
|
||||
else
|
||||
{eCommand=cm_Unknown; //ci¹g nierozpoznany (nie jest komend¹)
|
||||
bCommand=true; //do wys³ania
|
||||
}
|
||||
return eCommand;
|
||||
}
|
||||
|
||||
bool __fastcall TMemCell::Load(cParser *parser)
|
||||
{
|
||||
std::string token;
|
||||
parser->getTokens(1,false); //case sensitive
|
||||
*parser >> token;
|
||||
SafeDeleteArray(szText);
|
||||
szText=new char[256]; //musi byæ bufor do ³¹czenia tekstów
|
||||
strcpy(szText,token.c_str());
|
||||
parser->getTokens();
|
||||
*parser >> fValue1;
|
||||
parser->getTokens();
|
||||
*parser >> fValue2;
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
if (token.compare("none")!=0) //gdy ró¿ne od "none"
|
||||
asTrackName=AnsiString(token.c_str()); //sprawdzane przez IsEmpty()
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
if (token.compare("endmemcell")!=0)
|
||||
Error("endmemcell statement missing");
|
||||
CommandCheck();
|
||||
return true;
|
||||
}
|
||||
|
||||
void __fastcall TMemCell::PutCommand(TController *Mech, vector3 *Loc)
|
||||
{//wys³anie zawartoœci komórki do AI
|
||||
if (Mech)
|
||||
Mech->PutCommand(szText,fValue1,fValue2,Loc);
|
||||
}
|
||||
|
||||
bool __fastcall TMemCell::Compare(char *szTestText,double fTestValue1,double fTestValue2,int CheckMask)
|
||||
{//porównanie zawartoœci komórki pamiêci z podanymi wartoœciami
|
||||
if (TestFlag(CheckMask,conditional_memstring))
|
||||
{//porównaæ teksty
|
||||
char *pos=StrPos(szTestText,"*"); //zwraca wskaŸnik na pozycjê albo NULL
|
||||
if (pos)
|
||||
{//porównanie fragmentu ³añcucha
|
||||
int i=pos-szTestText; //iloœæ porównywanych znaków
|
||||
if (i) //jeœli nie jest pierwszym znakiem
|
||||
if (AnsiString(szTestText,i)!=AnsiString(szText,i))
|
||||
return false; //pocz¹tki o d³ugoœci (i) s¹ ró¿ne
|
||||
}
|
||||
else
|
||||
if (AnsiString(szTestText)!=AnsiString(szText))
|
||||
return false; //³¹ñcuchy s¹ ró¿ne
|
||||
}
|
||||
//tekst zgodny, porównaæ resztê
|
||||
return ((!TestFlag(CheckMask,conditional_memval1) || (fValue1==fTestValue1)) &&
|
||||
(!TestFlag(CheckMask,conditional_memval2) || (fValue2==fTestValue2)));
|
||||
};
|
||||
|
||||
bool __fastcall TMemCell::Render()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __fastcall TMemCell::IsVelocity()
|
||||
{//sprawdzenie, czy event odczytu tej komórki ma byæ do skanowania, czy do kolejkowania
|
||||
if (eCommand==cm_SetVelocity) return true;
|
||||
if (eCommand==cm_ShuntVelocity) return true;
|
||||
return (eCommand==cm_SetProximityVelocity);
|
||||
};
|
||||
|
||||
void __fastcall TMemCell::StopCommandSent()
|
||||
{//
|
||||
if (!bCommand) return;
|
||||
bCommand=false;
|
||||
if (OnSent) //jeœli jest event
|
||||
Global::AddToQuery(OnSent,NULL);
|
||||
};
|
||||
|
||||
void __fastcall TMemCell::AssignEvents(TEvent *e)
|
||||
{//powi¹zanie eventu
|
||||
OnSent=e;
|
||||
};
|
||||
43
MemCell.h
Normal file
43
MemCell.h
Normal file
@@ -0,0 +1,43 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef MemCellH
|
||||
#define MemCellH
|
||||
|
||||
#include "Classes.h"
|
||||
#include "dumb3d.h"
|
||||
using namespace Math3D;
|
||||
|
||||
class TMemCell
|
||||
{
|
||||
private:
|
||||
vector3 vPosition;
|
||||
char *szText;
|
||||
double fValue1;
|
||||
double fValue2;
|
||||
TCommandType eCommand;
|
||||
bool bCommand; //czy zawiera komendê dla zatrzymanego AI
|
||||
TEvent *OnSent; //event dodawany do kolejki po wys³aniu komendy zatrzymuj¹cej sk³ad
|
||||
public:
|
||||
AnsiString asTrackName; //McZapkie-100302 - zeby nazwe toru na ktory jest Putcommand wysylane pamietac
|
||||
__fastcall TMemCell(vector3 *p);
|
||||
__fastcall ~TMemCell();
|
||||
void __fastcall Init();
|
||||
void __fastcall UpdateValues(char *szNewText, double fNewValue1, double fNewValue2, int CheckMask);
|
||||
bool __fastcall Load(cParser *parser);
|
||||
void __fastcall PutCommand(TController *Mech, vector3 *Loc);
|
||||
bool __fastcall Compare(char *szTestText, double fTestValue1, double fTestValue2, int CheckMask);
|
||||
bool __fastcall Render();
|
||||
inline char* __fastcall Text() {return szText;};
|
||||
inline double __fastcall Value1() {return fValue1;};
|
||||
inline double __fastcall Value2() {return fValue2;};
|
||||
inline vector3 __fastcall Position() {return vPosition;};
|
||||
inline TCommandType __fastcall Command() {return eCommand;};
|
||||
inline bool __fastcall StopCommand() {return bCommand;};
|
||||
void __fastcall StopCommandSent();
|
||||
TCommandType __fastcall CommandCheck();
|
||||
bool __fastcall IsVelocity();
|
||||
void __fastcall AssignEvents(TEvent *e);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
2077
Model3d.cpp
Normal file
2077
Model3d.cpp
Normal file
File diff suppressed because it is too large
Load Diff
365
Model3d.h
Normal file
365
Model3d.h
Normal file
@@ -0,0 +1,365 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef Model3dH
|
||||
#define Model3dH
|
||||
|
||||
#include "opengl/glew.h"
|
||||
#include "Parser.h"
|
||||
#include "dumb3d.h"
|
||||
using namespace Math3D;
|
||||
#include "Float3d.h"
|
||||
#include "VBO.h"
|
||||
|
||||
struct GLVERTEX
|
||||
{
|
||||
vector3 Point;
|
||||
vector3 Normal;
|
||||
float tu,tv;
|
||||
};
|
||||
|
||||
class TStringPack
|
||||
{
|
||||
char *data;
|
||||
//+0 - 4 bajty: typ kromki
|
||||
//+4 - 4 bajty: długość łącznie z nagłówkiem
|
||||
//+8 - obszar łańcuchów znakowych, każdy zakończony zerem
|
||||
int *index;
|
||||
//+0 - 4 bajty: typ kromki
|
||||
//+4 - 4 bajty: długość łącznie z nagłówkiem
|
||||
//+8 - tabela indeksów
|
||||
public:
|
||||
char* String(int n);
|
||||
char* StringAt(int n) {return data+9+n;};
|
||||
__fastcall TStringPack() {data=NULL; index=NULL;};
|
||||
void __fastcall Init(char *d) {data=d;};
|
||||
void __fastcall InitIndex(int *i) {index=i;};
|
||||
};
|
||||
|
||||
class TMaterialColor
|
||||
{
|
||||
public:
|
||||
__fastcall TMaterialColor() {};
|
||||
__fastcall TMaterialColor(char V)
|
||||
{
|
||||
r=g=b=V;
|
||||
};
|
||||
// __fastcall TMaterialColor(double R, double G, double B)
|
||||
__fastcall TMaterialColor(char R, char G, char B)
|
||||
{
|
||||
r=R; g=G; b=B;
|
||||
};
|
||||
|
||||
char r,g,b;
|
||||
};
|
||||
|
||||
/*
|
||||
struct TMaterial
|
||||
{
|
||||
int ID;
|
||||
AnsiString Name;
|
||||
//McZapkie-240702: lepiej uzywac wartosci float do opisu koloru bo funkcje opengl chyba tego na ogol uzywaja
|
||||
float Ambient[4];
|
||||
float Diffuse[4];
|
||||
float Specular[4];
|
||||
float Transparency;
|
||||
GLuint TextureID;
|
||||
};
|
||||
*/
|
||||
/*
|
||||
struct THitBoxContainer
|
||||
{
|
||||
TPlane Planes[6];
|
||||
int Index;
|
||||
inline void __fastcall Reset() { Planes[0]= TPlane(vector3(0,0,0),0.0f); };
|
||||
inline bool __fastcall Inside(vector3 Point)
|
||||
{
|
||||
bool Hit= true;
|
||||
|
||||
if (Planes[0].Defined())
|
||||
for (int i=0; i<6; i++)
|
||||
{
|
||||
if (Planes[i].GetSide(Point)>0)
|
||||
{
|
||||
Hit= false;
|
||||
break;
|
||||
};
|
||||
|
||||
}
|
||||
else return(false);
|
||||
return(Hit);
|
||||
};
|
||||
};
|
||||
*/
|
||||
|
||||
/* Ra: tego nie będziemy już używać, bo można wycisnąć więcej
|
||||
typedef enum
|
||||
{smt_Unknown, //nieznany
|
||||
smt_Mesh, //siatka
|
||||
smt_Point,
|
||||
smt_FreeSpotLight, //punkt świetlny
|
||||
smt_Text, //generator tekstu
|
||||
smt_Stars //wiele punktów świetlnych
|
||||
} TSubModelType;
|
||||
*/
|
||||
//Ra: specjalne typy submodeli, poza tym GL_TRIANGLES itp.
|
||||
const int TP_ROTATOR=256;
|
||||
const int TP_FREESPOTLIGHT=257;
|
||||
const int TP_STARS=258;
|
||||
const int TP_TEXT=259;
|
||||
|
||||
enum TAnimType //rodzaj animacji
|
||||
{at_None, //brak
|
||||
at_Rotate, //obrót względem wektora o kąt
|
||||
at_RotateXYZ, //obrót względem osi o kąty
|
||||
at_Translate, //przesunięcie
|
||||
at_SecondsJump, //sekundy z przeskokiem
|
||||
at_MinutesJump, //minuty z przeskokiem
|
||||
at_HoursJump, //godziny z przeskokiem 12h/360°
|
||||
at_Hours24Jump, //godziny z przeskokiem 24h/360°
|
||||
at_Seconds, //sekundy płynnie
|
||||
at_Minutes, //minuty płynnie
|
||||
at_Hours, //godziny płynnie 12h/360°
|
||||
at_Hours24, //godziny płynnie 24h/360°
|
||||
at_Billboard, //obrót w pionie do kamery
|
||||
at_Wind, //ruch pod wpływem wiatru
|
||||
at_Sky, //animacja nieba
|
||||
at_IK=0x100, //odwrotna kinematyka - submodel sterujący (np. staw skokowy)
|
||||
at_IK11=0x101, //odwrotna kinematyka - submodel nadrzędny do sterowango (np. stopa)
|
||||
at_IK21=0x102, //odwrotna kinematyka - submodel nadrzędny do sterowango (np. podudzie)
|
||||
at_IK22=0x103, //odwrotna kinematyka - submodel nadrzędny do nadrzędnego sterowango (np. udo)
|
||||
at_Digital=0x200, //dziesięciocyfrowy licznik mechaniczny (z cylindrami)
|
||||
at_DigiClk=0x201, //zegar cyfrowy jako licznik na dziesięciościanach
|
||||
at_Undefined=0x800000FF //animacja chwilowo nieokreślona
|
||||
};
|
||||
|
||||
class TModel3d;
|
||||
class TSubModelInfo;
|
||||
|
||||
class TSubModel
|
||||
{//klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
||||
//Ra: ta klasa ma mieć wielkość 256 bajtów, aby pokryła się z formatem binarnym
|
||||
//Ra: nie przestawiać zmiennych, bo wczytują się z pliku binarnego!
|
||||
private:
|
||||
TSubModel *Next;
|
||||
TSubModel *Child;
|
||||
int eType; //Ra: modele binarne dają więcej możliwości niż mesh złożony z trójkątów
|
||||
int iName; //numer łańcucha z nazwą submodelu, albo -1 gdy anonimowy
|
||||
public: //chwilowo
|
||||
TAnimType b_Anim;
|
||||
private:
|
||||
int iFlags; //flagi informacyjne:
|
||||
//bit 0: =1 faza rysowania zależy od wymiennej tekstury 0
|
||||
//bit 1: =1 faza rysowania zależy od wymiennej tekstury 1
|
||||
//bit 2: =1 faza rysowania zależy od wymiennej tekstury 2
|
||||
//bit 3: =1 faza rysowania zależy od wymiennej tekstury 3
|
||||
//bit 4: =1 rysowany w fazie nieprzezroczystych (stała tekstura albo brak)
|
||||
//bit 5: =1 rysowany w fazie przezroczystych (stała tekstura)
|
||||
//bit 7: =1 ta sama tekstura, co poprzedni albo nadrzędny
|
||||
//bit 8: =1 wierzchołki wyświetlane z indeksów
|
||||
//bit 9: =1 wczytano z pliku tekstowego (jest właścicielem tablic)
|
||||
//bit 13: =1 wystarczy przesunięcie zamiast mnożenia macierzy (trzy jedynki)
|
||||
//bit 14: =1 wymagane przechowanie macierzy (animacje)
|
||||
//bit 15: =1 wymagane przechowanie macierzy (transform niejedynkowy)
|
||||
union
|
||||
{//transform, nie każdy submodel musi mieć
|
||||
float4x4 *fMatrix; //pojedyncza precyzja wystarcza
|
||||
//matrix4x4 *dMatrix; //do testu macierz podwójnej precyzji
|
||||
int iMatrix; //w pliku binarnym jest numer matrycy
|
||||
};
|
||||
int iNumVerts; //ilość wierzchołków (1 dla FreeSpotLight)
|
||||
int iVboPtr; //początek na liście wierzchołków albo indeksów
|
||||
int iTexture; //numer nazwy tekstury, -1 wymienna, 0 brak
|
||||
float fVisible; //próg jasności światła do załączenia submodelu
|
||||
float fLight; //próg jasności światła do zadziałania selfillum
|
||||
float f4Ambient[4];
|
||||
float f4Diffuse[4]; //float ze względu na glMaterialfv()
|
||||
float f4Specular[4];
|
||||
float f4Emision[4];
|
||||
float fWireSize; //nie używane, ale wczytywane
|
||||
float fSquareMaxDist;
|
||||
float fSquareMinDist;
|
||||
//McZapkie-050702: parametry dla swiatla:
|
||||
float fNearAttenStart;
|
||||
float fNearAttenEnd;
|
||||
int bUseNearAtten; //te 3 zmienne okreslaja rysowanie aureoli wokol zrodla swiatla
|
||||
int iFarAttenDecay; //ta zmienna okresla typ zaniku natezenia swiatla (0:brak, 1,2: potega 1/R)
|
||||
float fFarDecayRadius; //normalizacja j.w.
|
||||
float fCosFalloffAngle; //cosinus kąta stożka pod którym widać światło
|
||||
float fCosHotspotAngle; //cosinus kąta stożka pod którym widać aureolę i zwiększone natężenie światła
|
||||
float fCosViewAngle; //cos kata pod jakim sie teraz patrzy
|
||||
//Ra: dalej są zmienne robocze, można je przestawiać z zachowaniem rozmiaru klasy
|
||||
int TextureID; //numer tekstury, -1 wymienna, 0 brak
|
||||
int bWire; //nie używane, ale wczytywane
|
||||
//short TexAlpha; //Ra: nie używane już
|
||||
GLuint uiDisplayList; //roboczy numer listy wyświetlania
|
||||
float Opacity; //nie używane, ale wczytywane
|
||||
//ABu: te same zmienne, ale zdublowane dla Render i RenderAlpha,
|
||||
//bo sie chrzanilo przemieszczanie obiektow.
|
||||
//Ra: już się nie chrzani
|
||||
float f_Angle;
|
||||
float3 v_RotateAxis;
|
||||
float3 v_Angles;
|
||||
public: //chwilowo
|
||||
float3 v_TransVector;
|
||||
float8 *Vertices; //roboczy wskaźnik - wczytanie T3D do VBO
|
||||
int iAnimOwner; //roboczy numer egzemplarza, który ustawił animację
|
||||
TAnimType b_aAnim; //kody animacji oddzielnie, bo zerowane
|
||||
public:
|
||||
float4x4 *mAnimMatrix; //macierz do animacji kwaternionowych (należy do AnimContainer)
|
||||
char space[8]; //wolne miejsce na przyszłe zmienne (zmniejszyć w miarę potrzeby)
|
||||
public:
|
||||
TSubModel **smLetter; //wskaźnik na tablicę submdeli do generoania tekstu (docelowo zapisać do E3D)
|
||||
TSubModel *Parent; //nadrzędny, np. do wymnażania macierzy
|
||||
int iVisible; //roboczy stan widoczności
|
||||
//AnsiString asTexture; //robocza nazwa tekstury do zapisania w pliku binarnym
|
||||
//AnsiString asName; //robocza nazwa
|
||||
char *pTexture; //robocza nazwa tekstury do zapisania w pliku binarnym
|
||||
char *pName; //robocza nazwa
|
||||
private:
|
||||
//int __fastcall SeekFaceNormal(DWORD *Masks, int f,DWORD dwMask,vector3 *pt,GLVERTEX *Vertices);
|
||||
int __fastcall SeekFaceNormal(DWORD *Masks,int f,DWORD dwMask,float3 *pt,float8 *Vertices);
|
||||
void __fastcall RaAnimation(TAnimType a);
|
||||
public:
|
||||
static int iInstance; //identyfikator egzemplarza, który aktualnie renderuje model
|
||||
static GLuint *ReplacableSkinId;
|
||||
static int iAlpha; //maska bitowa dla danego przebiegu
|
||||
static double fSquareDist;
|
||||
static TModel3d* pRoot;
|
||||
static AnsiString* pasText; //tekst dla wyświetlacza (!!!! do przemyślenia)
|
||||
__fastcall TSubModel();
|
||||
__fastcall ~TSubModel();
|
||||
void __fastcall FirstInit();
|
||||
int __fastcall Load(cParser& Parser, TModel3d *Model,int Pos,bool dynamic);
|
||||
void __fastcall ChildAdd(TSubModel *SubModel);
|
||||
void __fastcall NextAdd(TSubModel *SubModel);
|
||||
TSubModel* __fastcall NextGet() {return Next;};
|
||||
TSubModel* __fastcall ChildGet() {return Child;};
|
||||
int __fastcall TriangleAdd(TModel3d *m,int tex,int tri);
|
||||
float8* __fastcall TrianglePtr(int tex,int pos,int *la,int *ld,int*ls);
|
||||
//float8* __fastcall TrianglePtr(const char *tex,int tri);
|
||||
//void __fastcall SetRotate(vector3 vNewRotateAxis,float fNewAngle);
|
||||
void __fastcall SetRotate(float3 vNewRotateAxis,float fNewAngle);
|
||||
void __fastcall SetRotateXYZ(vector3 vNewAngles);
|
||||
void __fastcall SetRotateXYZ(float3 vNewAngles);
|
||||
void __fastcall SetTranslate(vector3 vNewTransVector);
|
||||
void __fastcall SetTranslate(float3 vNewTransVector);
|
||||
void __fastcall SetRotateIK1(float3 vNewAngles);
|
||||
TSubModel* __fastcall GetFromName(AnsiString search,bool i=true);
|
||||
TSubModel* __fastcall GetFromName(char *search,bool i=true);
|
||||
void __fastcall RenderDL();
|
||||
void __fastcall RenderAlphaDL();
|
||||
void __fastcall RenderVBO();
|
||||
void __fastcall RenderAlphaVBO();
|
||||
//inline matrix4x4* __fastcall GetMatrix() {return dMatrix;};
|
||||
inline float4x4* __fastcall GetMatrix() {return fMatrix;};
|
||||
//matrix4x4* __fastcall GetTransform() {return Matrix;};
|
||||
inline void __fastcall Hide() {iVisible=0;};
|
||||
void __fastcall RaArrayFill(CVertNormTex *Vert);
|
||||
//void __fastcall Render();
|
||||
int __fastcall FlagsCheck();
|
||||
void __fastcall WillBeAnimated() {if (this) iFlags|=0x4000;};
|
||||
void __fastcall InitialRotate(bool doit);
|
||||
void __fastcall DisplayLists();
|
||||
void __fastcall Info();
|
||||
void __fastcall InfoSet(TSubModelInfo *info);
|
||||
void __fastcall BinInit(TSubModel *s,float4x4 *m,float8 *v,TStringPack *t,TStringPack *n=NULL,bool dynamic=false);
|
||||
void __fastcall ReplacableSet(GLuint *r,int a)
|
||||
{ReplacableSkinId=r; iAlpha=a;};
|
||||
void __fastcall TextureNameSet(const char *n);
|
||||
void __fastcall NameSet(const char *n);
|
||||
//Ra: funkcje do budowania terenu z E3D
|
||||
int __fastcall Flags() {return iFlags;};
|
||||
void __fastcall UnFlagNext() {iFlags&=0x00FFFFFF;};
|
||||
void __fastcall ColorsSet(int *a,int *d,int*s);
|
||||
inline float3 Translation1Get()
|
||||
{return fMatrix?*(fMatrix->TranslationGet())+v_TransVector:v_TransVector;}
|
||||
inline float3 Translation2Get()
|
||||
{return *(fMatrix->TranslationGet())+Child->Translation1Get();}
|
||||
void __fastcall ParentMatrix(float4x4 *m);
|
||||
float __fastcall MaxY(const float4x4 &m);
|
||||
void __fastcall AdjustDist();
|
||||
};
|
||||
|
||||
class TSubModelInfo
|
||||
{//klasa z informacjami o submodelach, do tworzenia pliku binarnego
|
||||
public:
|
||||
TSubModel *pSubModel; //wskaźnik na submodel
|
||||
int iTransform; //numer transformu (-1 gdy brak)
|
||||
int iName; //numer nazwy
|
||||
int iTexture; //numer tekstury
|
||||
int iNameLen; //długość nazwy
|
||||
int iTextureLen; //długość tekstury
|
||||
int iNext,iChild; //numer następnego i potomnego
|
||||
static int iTotalTransforms; //ilość transformów
|
||||
static int iTotalNames; //ilość nazw
|
||||
static int iTotalTextures; //ilość tekstur
|
||||
static int iCurrent; //aktualny obiekt
|
||||
static TSubModelInfo* pTable; //tabele obiektów pomocniczych
|
||||
__fastcall TSubModelInfo()
|
||||
{pSubModel=NULL;
|
||||
iTransform=iName=iTexture=iNext=iChild=-1; //nie ma
|
||||
iNameLen=iTextureLen=0;
|
||||
}
|
||||
void __fastcall Reset()
|
||||
{pTable=this; //ustawienie wskaźnika tabeli obiektów
|
||||
iTotalTransforms=iTotalNames=iTotalTextures=iCurrent=0; //zerowanie liczników
|
||||
}
|
||||
__fastcall ~TSubModelInfo() {};
|
||||
};
|
||||
|
||||
class TModel3d : public CMesh
|
||||
{
|
||||
private:
|
||||
//TMaterial *Materials;
|
||||
//int MaterialsCount; //Ra: nie używane
|
||||
//bool TractionPart; //Ra: nie używane
|
||||
TSubModel *Root; //drzewo submodeli
|
||||
int iFlags; //Ra: czy submodele mają przezroczyste tekstury
|
||||
public: //Ra: tymczasowo
|
||||
int iNumVerts; //ilość wierzchołków (gdy nie ma VBO, to m_nVertexCount=0)
|
||||
private:
|
||||
TStringPack Textures; //nazwy tekstur
|
||||
TStringPack Names; //nazwy submodeli
|
||||
int *iModel; //zawartość pliku binarnego
|
||||
int iSubModelsCount; //Ra: używane do tworzenia binarnych
|
||||
AnsiString asBinary; //nazwa pod którą zapisać model binarny
|
||||
public:
|
||||
inline TSubModel* __fastcall GetSMRoot() {return(Root);};
|
||||
//double Radius; //Ra: nie używane
|
||||
__fastcall TModel3d();
|
||||
__fastcall TModel3d(char *FileName);
|
||||
__fastcall ~TModel3d();
|
||||
TSubModel* __fastcall GetFromName(const char *sName);
|
||||
//TMaterial* __fastcall GetMaterialFromName(char *sName);
|
||||
TSubModel* __fastcall AddToNamed(const char *Name, TSubModel *SubModel);
|
||||
void __fastcall AddTo(TSubModel *tmp,TSubModel *SubModel);
|
||||
void __fastcall LoadFromTextFile(char *FileName,bool dynamic);
|
||||
void __fastcall LoadFromBinFile(char *FileName,bool dynamic);
|
||||
bool __fastcall LoadFromFile(char *FileName,bool dynamic);
|
||||
void __fastcall SaveToBinFile(char *FileName);
|
||||
void __fastcall BreakHierarhy();
|
||||
//renderowanie specjalne
|
||||
void __fastcall Render(double fSquareDistance,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
void __fastcall RenderAlpha(double fSquareDistance,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
void __fastcall RaRender(double fSquareDistance,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
void __fastcall RaRenderAlpha(double fSquareDistance,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
//jeden kąt obrotu
|
||||
void __fastcall Render(vector3 pPosition,double fAngle=0,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
void __fastcall RenderAlpha(vector3 pPosition,double fAngle=0,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
void __fastcall RaRender(vector3 pPosition,double fAngle=0,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
void __fastcall RaRenderAlpha(vector3 pPosition,double fAngle=0,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
//trzy kąty obrotu
|
||||
void __fastcall Render(vector3* vPosition,vector3* vAngle,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
void __fastcall RenderAlpha(vector3* vPosition,vector3* vAngle,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
void __fastcall RaRender(vector3* vPosition,vector3* vAngle,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
void __fastcall RaRenderAlpha(vector3* vPosition,vector3* vAngle,GLuint *ReplacableSkinId=NULL,int iAlpha=0x30300030);
|
||||
//inline int __fastcall GetSubModelsCount() { return (SubModelsCount); };
|
||||
int __fastcall Flags() {return iFlags;};
|
||||
void __fastcall Init();
|
||||
char* __fastcall NameGet() {return Root?Root->pName:NULL;};
|
||||
int __fastcall TerrainCount();
|
||||
TSubModel* __fastcall TerrainSquare(int n);
|
||||
void __fastcall TerrainRenderVBO(int n);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
590
Mover.cpp
Normal file
590
Mover.cpp
Normal file
@@ -0,0 +1,590 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "Mover.h"
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
// Ra: tu nale¿y przenosiæ funcje z mover.pas, które nie s¹ z niego wywo³ywane.
|
||||
// Jeœli jakieœ zmienne nie s¹ u¿ywane w mover.pas, te¿ mo¿na je przenosiæ.
|
||||
// Przeniesienie wszystkiego na raz zrobi³o by zbyt wielki chaos do ogarniêcia.
|
||||
|
||||
const dEpsilon=0.01; //1cm (zale¿y od typu sprzêgu...)
|
||||
|
||||
__fastcall TMoverParameters::TMoverParameters(double VelInitial,AnsiString TypeNameInit,AnsiString NameInit,
|
||||
int LoadInitial,AnsiString LoadTypeInitial,int Cab)
|
||||
: T_MoverParameters(VelInitial,TypeNameInit,NameInit,LoadInitial,LoadTypeInitial,Cab)
|
||||
{//g³ówny konstruktor
|
||||
DimHalf.x=0.5*Dim.W; //po³owa szerokoœci, OX jest w bok?
|
||||
DimHalf.y=0.5*Dim.L; //po³owa d³ugoœci, OY jest do przodu?
|
||||
DimHalf.z=0.5*Dim.H; //po³owa wysokoœci, OZ jest w górê?
|
||||
//BrakeLevelSet(-2); //Pascal ustawia na 0, przestawimy na odciêcie (CHK jest jeszcze nie wczytane!)
|
||||
bPantKurek3=true; //domyœlnie zbiornik pantografu po³¹czony jest ze zbiornikiem g³ównym
|
||||
iProblem=0; //pojazd w pe³ni gotowy do ruchu
|
||||
iLights[0]=iLights[1]=0; //œwiat³a zgaszone
|
||||
};
|
||||
|
||||
|
||||
double __fastcall TMoverParameters::Distance(const TLocation &Loc1,const TLocation &Loc2,const TDimension &Dim1,const TDimension &Dim2)
|
||||
{//zwraca odleg³oœæ pomiêdzy pojazdami (Loc1) i (Loc2) z uwzglêdnieneim ich d³ugoœci (kule!)
|
||||
return hypot(Loc2.X-Loc1.X,Loc1.Y-Loc2.Y)-0.5*(Dim2.L+Dim1.L);
|
||||
};
|
||||
|
||||
double __fastcall TMoverParameters::Distance(const vector3 &s1, const vector3 &s2, const vector3 &d1, const vector3 &d2)
|
||||
{//obliczenie odleg³oœci prostopad³oœcianów o œrodkach (s1) i (s2) i wymiarach (d1) i (d2)
|
||||
//return 0.0; //bêdzie zg³aszaæ warning - funkcja do usuniêcia, chyba ¿e siê przyda...
|
||||
};
|
||||
|
||||
double __fastcall TMoverParameters::CouplerDist(Byte Coupler)
|
||||
{//obliczenie odleg³oœci pomiêdzy sprzêgami (kula!)
|
||||
return Couplers[Coupler].CoupleDist=Distance(Loc,Couplers[Coupler].Connected->Loc,Dim,Couplers[Coupler].Connected->Dim); //odleg³oœæ pomiêdzy sprzêgami (kula!)
|
||||
};
|
||||
|
||||
bool __fastcall TMoverParameters::Attach(Byte ConnectNo,Byte ConnectToNr,TMoverParameters *ConnectTo,Byte CouplingType,bool Forced)
|
||||
{//³¹czenie do swojego sprzêgu (ConnectNo) pojazdu (ConnectTo) stron¹ (ConnectToNr)
|
||||
//Ra: zwykle wykonywane dwukrotnie, dla ka¿dego pojazdu oddzielnie
|
||||
//Ra: trzeba by odró¿niæ wymóg dociœniêcia od uszkodzenia sprzêgu przy podczepianiu AI do sk³adu
|
||||
if (ConnectTo) //jeœli nie pusty
|
||||
{
|
||||
if (ConnectToNr!=2) Couplers[ConnectNo].ConnectedNr=ConnectToNr; //2=nic nie pod³¹czone
|
||||
TCouplerType ct=ConnectTo->Couplers[Couplers[ConnectNo].ConnectedNr].CouplerType; //typ sprzêgu pod³¹czanego pojazdu
|
||||
Couplers[ConnectNo].Connected=ConnectTo; //tak podpi¹æ (do siebie) zawsze mo¿na, najwy¿ej bêdzie wirtualny
|
||||
CouplerDist(ConnectNo); //przeliczenie odleg³oœci pomiêdzy sprzêgami
|
||||
if (CouplingType==ctrain_virtual) return false; //wirtualny wiêcej nic nie robi
|
||||
if (Forced?true:((Couplers[ConnectNo].CoupleDist<=dEpsilon)&&(Couplers[ConnectNo].CouplerType!=NoCoupler)&&(Couplers[ConnectNo].CouplerType==ct)))
|
||||
{//stykaja sie zderzaki i kompatybilne typy sprzegow, chyba ¿e ³¹czenie na starcie
|
||||
if (Couplers[ConnectNo].CouplingFlag==ctrain_virtual) //jeœli wczeœniej nie by³o po³¹czone
|
||||
{//ustalenie z której strony rysowaæ sprzêg
|
||||
Couplers[ConnectNo].Render=true; //tego rysowaæ
|
||||
ConnectTo->Couplers[Couplers[ConnectNo].ConnectedNr].Render=false; //a tego nie
|
||||
};
|
||||
Couplers[ConnectNo].CouplingFlag=CouplingType; //ustawienie typu sprzêgu
|
||||
//if (CouplingType!=ctrain_virtual) //Ra: wirtualnego nie ³¹czymy zwrotnie!
|
||||
//{//jeœli ³¹czenie sprzêgiem niewirtualnym, ustawiamy po³¹czenie zwrotne
|
||||
ConnectTo->Couplers[Couplers[ConnectNo].ConnectedNr].CouplingFlag=CouplingType;
|
||||
ConnectTo->Couplers[Couplers[ConnectNo].ConnectedNr].Connected=this;
|
||||
ConnectTo->Couplers[Couplers[ConnectNo].ConnectedNr].CoupleDist=Couplers[ConnectNo].CoupleDist;
|
||||
return true;
|
||||
//}
|
||||
//pod³¹czenie nie uda³o siê - jest wirtualne
|
||||
}
|
||||
}
|
||||
return false; //brak pod³¹czanego pojazdu, zbyt du¿a odleg³oœæ, niezgodny typ sprzêgu, brak sprzêgu, brak haka
|
||||
};
|
||||
|
||||
bool __fastcall TMoverParameters::Attach(Byte ConnectNo,Byte ConnectToNr,T_MoverParameters *ConnectTo,Byte CouplingType,bool Forced)
|
||||
{//³¹czenie do (ConnectNo) pojazdu (ConnectTo) stron¹ (ConnectToNr)
|
||||
return Attach(ConnectNo,ConnectToNr,(TMoverParameters*)ConnectTo,CouplingType,Forced);
|
||||
};
|
||||
|
||||
int __fastcall TMoverParameters::DettachStatus(Byte ConnectNo)
|
||||
{//Ra: sprawdzenie, czy odleg³oœæ jest dobra do roz³¹czania
|
||||
//powinny byæ 3 informacje: =0 sprzêg ju¿ roz³¹czony, <0 da siê roz³¹czyæ. >0 nie da siê roz³¹czyæ
|
||||
if (!Couplers[ConnectNo].Connected)
|
||||
return 0; //nie ma nic, to roz³¹czanie jest OK
|
||||
if ((Couplers[ConnectNo].CouplingFlag&ctrain_coupler)==0)
|
||||
return -Couplers[ConnectNo].CouplingFlag; //hak nie po³¹czony - roz³¹czanie jest OK
|
||||
if (TestFlag(DamageFlag,dtrain_coupling))
|
||||
return -Couplers[ConnectNo].CouplingFlag; //hak urwany - roz³¹czanie jest OK
|
||||
//ABu021104: zakomentowane 'and (CouplerType<>Articulated)' w warunku, nie wiem co to bylo, ale za to teraz dziala odczepianie... :) }
|
||||
//if (CouplerType==Articulated) return false; //sprzêg nie do rozpiêcia - mo¿e byæ tylko urwany
|
||||
//Couplers[ConnectNo].CoupleDist=Distance(Loc,Couplers[ConnectNo].Connected->Loc,Dim,Couplers[ConnectNo].Connected->Dim);
|
||||
CouplerDist(ConnectNo);
|
||||
if (Couplers[ConnectNo].CouplerType==Screw?Couplers[ConnectNo].CoupleDist<0.0:true)
|
||||
return -Couplers[ConnectNo].CouplingFlag; //mo¿na roz³¹czaæ, jeœli dociœniêty
|
||||
return (Couplers[ConnectNo].CoupleDist>0.2)?-Couplers[ConnectNo].CouplingFlag:Couplers[ConnectNo].CouplingFlag;
|
||||
};
|
||||
|
||||
bool __fastcall TMoverParameters::Dettach(Byte ConnectNo)
|
||||
{//rozlaczanie
|
||||
if (!Couplers[ConnectNo].Connected) return true; //nie ma nic, to odczepiono
|
||||
//with Couplers[ConnectNo] do
|
||||
int i=DettachStatus(ConnectNo); //stan sprzêgu
|
||||
if (i<0)
|
||||
{//gdy scisniete zderzaki, chyba ze zerwany sprzeg (wirtualnego nie odpinamy z drugiej strony)
|
||||
//Couplers[ConnectNo].Connected=NULL; //lepiej zostawic bo przeciez trzeba kontrolowac zderzenia odczepionych
|
||||
Couplers[ConnectNo].Connected->Couplers[Couplers[ConnectNo].ConnectedNr].CouplingFlag=0; //pozostaje sprzêg wirtualny
|
||||
Couplers[ConnectNo].CouplingFlag=0; //pozostaje sprzêg wirtualny
|
||||
return true;
|
||||
}
|
||||
else if (i>0)
|
||||
{//od³¹czamy wê¿e i resztê, pozostaje sprzêg fizyczny, który wymaga dociœniêcia (z wirtualnym nic)
|
||||
Couplers[ConnectNo].CouplingFlag&=ctrain_coupler;
|
||||
Couplers[ConnectNo].Connected->Couplers[Couplers[ConnectNo].ConnectedNr].CouplingFlag=Couplers[ConnectNo].CouplingFlag;
|
||||
}
|
||||
return false; //jeszcze nie roz³¹czony
|
||||
};
|
||||
|
||||
void __fastcall TMoverParameters::SetCoupleDist()
|
||||
{//przeliczenie odleg³oœci sprzêgów
|
||||
if (Couplers[0].Connected)
|
||||
{
|
||||
CouplerDist(0);
|
||||
if (CategoryFlag&2)
|
||||
{//Ra: dla samochodów zderzanie kul to za ma³o
|
||||
}
|
||||
}
|
||||
if (Couplers[1].Connected)
|
||||
{
|
||||
CouplerDist(1);
|
||||
if (CategoryFlag&2)
|
||||
{//Ra: dla samochodów zderzanie kul to za ma³o
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
bool __fastcall TMoverParameters::DirectionForward()
|
||||
{
|
||||
if ((MainCtrlPosNo>0)&&(ActiveDir<1)&&(MainCtrlPos==0))
|
||||
{
|
||||
++ActiveDir;
|
||||
DirAbsolute=ActiveDir*CabNo;
|
||||
if (DirAbsolute)
|
||||
if (Battery) //jeœli bateria jest ju¿ za³¹czona
|
||||
BatterySwitch(true); //to w ten oto durny sposób aktywuje siê CA/SHP
|
||||
SendCtrlToNext("Direction",ActiveDir,CabNo);
|
||||
return true;
|
||||
}
|
||||
else if ((ActiveDir==1)&&(MainCtrlPos==0)&&(TrainType==dt_EZT))
|
||||
return MinCurrentSwitch(true); //"wysoki rozruch" EN57
|
||||
return false;
|
||||
};
|
||||
|
||||
// Nastawianie hamulców
|
||||
|
||||
void __fastcall TMoverParameters::BrakeLevelSet(double b)
|
||||
{//ustawienie pozycji hamulca na wartoϾ (b) w zakresie od -2 do BrakeCtrlPosNo
|
||||
//jedyny dopuszczalny sposób przestawienia hamulca zasadniczego
|
||||
if (fBrakeCtrlPos==b) return; //nie przeliczaæ, jak nie ma zmiany
|
||||
fBrakeCtrlPos=b;
|
||||
BrakeCtrlPosR=b;
|
||||
if (fBrakeCtrlPos<Handle->GetPos(bh_MIN))
|
||||
fBrakeCtrlPos=Handle->GetPos(bh_MIN); //odciêcie
|
||||
else
|
||||
if (fBrakeCtrlPos>Handle->GetPos(bh_MAX))
|
||||
fBrakeCtrlPos=Handle->GetPos(bh_MAX);
|
||||
int x=floor(fBrakeCtrlPos); //jeœli odwo³ujemy siê do BrakeCtrlPos w poœrednich, to musi byæ obciête a nie zaokr¹gone
|
||||
while ((x>BrakeCtrlPos)&&(BrakeCtrlPos<BrakeCtrlPosNo)) //jeœli zwiêkszy³o siê o 1
|
||||
if (!T_MoverParameters::IncBrakeLevelOld()) break; //wyjœcie awaryjne
|
||||
while ((x<BrakeCtrlPos)&&(BrakeCtrlPos>=-1)) //jeœli zmniejszy³o siê o 1
|
||||
if (!T_MoverParameters::DecBrakeLevelOld()) break;
|
||||
BrakePressureActual=BrakePressureTable[BrakeCtrlPos+2]; //skopiowanie pozycji
|
||||
/*
|
||||
//youBy: obawiam sie, ze tutaj to nie dziala :P
|
||||
//Ra 2014-03: by³o tak zrobione, ¿e dzia³a³o - po ka¿dej zmianie pozycji by³a wywo³ywana ta funkcja
|
||||
// if (BrakeSystem==Pneumatic?BrakeSubsystem==Oerlikon:false) //tylko Oerlikon akceptuje u³amki
|
||||
if(false)
|
||||
if (fBrakeCtrlPos>0.0)
|
||||
{//wartoœci poœrednie wyliczamy tylko dla hamowania
|
||||
double u=fBrakeCtrlPos-double(x); //u³amek ponad wartoœæ ca³kowit¹
|
||||
if (u>0.0)
|
||||
{//wyliczamy wartoœci wa¿one
|
||||
BrakePressureActual.PipePressureVal+=-u*BrakePressureActual.PipePressureVal+u*BrakePressureTable[BrakeCtrlPos+1+2].PipePressureVal;
|
||||
//BrakePressureActual.BrakePressureVal+=-u*BrakePressureActual.BrakePressureVal+u*BrakePressureTable[BrakeCtrlPos+1].BrakePressureVal; //to chyba nie bêdzie tak dzia³aæ, zw³aszcza w EN57
|
||||
BrakePressureActual.FlowSpeedVal+=-u*BrakePressureActual.FlowSpeedVal+u*BrakePressureTable[BrakeCtrlPos+1+2].FlowSpeedVal;
|
||||
}
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
bool __fastcall TMoverParameters::BrakeLevelAdd(double b)
|
||||
{//dodanie wartoœci (b) do pozycji hamulca (w tym ujemnej)
|
||||
//zwraca false, gdy po dodaniu by³o by poza zakresem
|
||||
BrakeLevelSet(fBrakeCtrlPos+b);
|
||||
return b>0.0?(fBrakeCtrlPos<BrakeCtrlPosNo):(BrakeCtrlPos>-1.0); //true, jeœli mo¿na kontynuowaæ
|
||||
};
|
||||
|
||||
bool __fastcall TMoverParameters::IncBrakeLevel()
|
||||
{//nowa wersja na u¿ytek AI, false gdy osi¹gniêto pozycjê BrakeCtrlPosNo
|
||||
return BrakeLevelAdd(1.0);
|
||||
};
|
||||
|
||||
bool __fastcall TMoverParameters::DecBrakeLevel()
|
||||
{//nowa wersja na u¿ytek AI, false gdy osi¹gniêto pozycjê -1
|
||||
return BrakeLevelAdd(-1.0);
|
||||
};
|
||||
|
||||
bool __fastcall TMoverParameters::ChangeCab(int direction)
|
||||
{//zmiana kabiny i resetowanie ustawien
|
||||
if (abs(ActiveCab+direction)<2)
|
||||
{
|
||||
// if (ActiveCab+direction=0) then LastCab:=ActiveCab;
|
||||
ActiveCab=ActiveCab+direction;
|
||||
if ((BrakeSystem==Pneumatic)&&(BrakeCtrlPosNo>0))
|
||||
{
|
||||
// if (BrakeHandle==FV4a) //!!!POBIERAÆ WARTOŒÆ Z KLASY ZAWORU!!!
|
||||
// BrakeLevelSet(-2); //BrakeCtrlPos=-2;
|
||||
// else if ((BrakeHandle==FVel6)||(BrakeHandle==St113))
|
||||
// BrakeLevelSet(2);
|
||||
// else
|
||||
// BrakeLevelSet(1);
|
||||
BrakeLevelSet(Handle->GetPos(bh_NP));
|
||||
LimPipePress=PipePress;
|
||||
ActFlowSpeed=0;
|
||||
}
|
||||
else
|
||||
//if (TrainType=dt_EZT) and (BrakeCtrlPosNo>0) then
|
||||
// BrakeCtrlPos:=5; //z Megapacka
|
||||
//else
|
||||
// BrakeLevelSet(0); //BrakeCtrlPos=0;
|
||||
BrakeLevelSet(Handle->GetPos(bh_NP));
|
||||
// if not TestFlag(BrakeStatus,b_dmg) then
|
||||
// BrakeStatus:=b_off; //z Megapacka
|
||||
MainCtrlPos=0;
|
||||
ScndCtrlPos=0;
|
||||
//Ra: to poni¿ej jest bez sensu - mo¿na przejœæ nie wy³¹czaj¹c
|
||||
//if ((EngineType!=DieselEngine)&&(EngineType!=DieselElectric))
|
||||
//{
|
||||
// Mains=false;
|
||||
// CompressorAllow=false;
|
||||
// ConverterAllow=false;
|
||||
//}
|
||||
//ActiveDir=0;
|
||||
//DirAbsolute=0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool __fastcall TMoverParameters::CurrentSwitch(int direction)
|
||||
{//rozruch wysoki (true) albo niski (false)
|
||||
//Ra: przenios³em z Train.cpp, nie wiem czy ma to sens
|
||||
if (MaxCurrentSwitch(direction))
|
||||
{if (TrainType!=dt_EZT)
|
||||
return (MinCurrentSwitch(direction));
|
||||
}
|
||||
if (EngineType==DieselEngine) //dla 2Ls150
|
||||
if (ShuntModeAllow)
|
||||
if (ActiveDir==0) //przed ustawieniem kierunku
|
||||
ShuntMode=direction;
|
||||
return false;
|
||||
};
|
||||
|
||||
void __fastcall TMoverParameters::UpdatePantVolume(double dt)
|
||||
{//KURS90 - sprê¿arka pantografów; Ra 2014-07: teraz jest to zbiornik rozrz¹du, chocia¿ to jeszcze nie tak
|
||||
if (EnginePowerSource.SourceType==CurrentCollector) //tylko jeœli pantografuj¹cy
|
||||
{
|
||||
//Ra 2014-07: zasadniczo, to istnieje zbiornik rozrz¹du i zbiornik pantografów - na razie mamy razem
|
||||
//Ra 2014-07: kurek trójdrogowy ³¹czy spr.pom. z pantografami i wy³¹cznikiem ciœnieniowym WS
|
||||
//Ra 2014-07: zbiornika rozrz¹du nie pompuje siê tu, tylko pantografy; potem mo¿na zamkn¹æ WS i odpaliæ resztê
|
||||
if ((TrainType==dt_EZT)?(PantPress<ScndPipePress):bPantKurek3) //kurek zamyka po³¹czenie z ZG
|
||||
{//zbiornik pantografu po³¹czony ze zbiornikiem g³ównym - ma³¹ sprê¿ark¹ siê tego nie napompuje
|
||||
//Ra 2013-12: Niebugoc³aw mówi, ¿e w EZT nie ma potrzeby odcinaæ kurkiem
|
||||
PantPress=EnginePowerSource.CollectorParameters.MaxPress; //ograniczenie ciœnienia do MaxPress (tylko w pantografach!)
|
||||
if (PantPress>ScndPipePress) PantPress=ScndPipePress; //oraz do ScndPipePress
|
||||
PantVolume=(PantPress+1)*0.1; //objêtoœæ, na wypadek odciêcia kurkiem
|
||||
}
|
||||
else
|
||||
{//zbiornik g³ówny odciêty, mo¿na pompowaæ pantografy
|
||||
if (PantCompFlag&&Battery) //w³¹czona bateria i ma³a sprê¿arka
|
||||
PantVolume+=dt*(TrainType==dt_EZT?0.003:0.005)*(2*0.45-((0.1/PantVolume/10)-0.1))/0.45; //nape³nianie zbiornika pantografów
|
||||
//Ra 2013-12: Niebugoc³aw mówi, ¿e w EZT nabija 1.5 raz wolniej ni¿ jak by³o 0.005
|
||||
PantPress=(10.0*PantVolume)-1.0; //tu by siê przyda³a objêtoœæ zbiornika
|
||||
}
|
||||
if (!PantCompFlag&&(PantVolume>0.1))
|
||||
PantVolume-=dt*0.0003; //nieszczelnoœci: 0.0003=0.3l/s
|
||||
if (Mains) //nie wchodziæ w funkcjê bez potrzeby
|
||||
if (EngineType==ElectricSeriesMotor) //nie dotyczy... czego w³aœciwie?
|
||||
if (PantPress<EnginePowerSource.CollectorParameters.MinPress)
|
||||
if ((TrainType&(dt_EZT|dt_ET40|dt_ET41|dt_ET42))?(GetTrainsetVoltage()<EnginePowerSource.CollectorParameters.MinV):true) //to jest trochê proteza; zasilanie cz³onu mo¿e byæ przez sprzêg WN
|
||||
if (MainSwitch(false))
|
||||
EventFlag=true; //wywalenie szybkiego z powodu niskiego ciœnienia
|
||||
if (TrainType!=dt_EZT) //w EN57 pompuje siê tylko w silnikowym
|
||||
//pierwotnie w CHK pantografy mia³y równie¿ rozrz¹dcze EZT
|
||||
for (int b=0;b<=1;++b)
|
||||
if (TestFlag(Couplers[b].CouplingFlag,ctrain_controll))
|
||||
if (Couplers[b].Connected->PantVolume<PantVolume) //bo inaczej trzeba w obydwu cz³onach przestawiaæ
|
||||
Couplers[b].Connected->PantVolume=PantVolume; //przekazanie ciœnienia do s¹siedniego cz³onu
|
||||
//czy np. w ET40, ET41, ET42 pantografy cz³onów maj¹ po³¹czenie pneumatyczne?
|
||||
//Ra 2014-07: raczej nie - najpierw siê za³¹cza jeden cz³on, a potem mo¿na podnieœæ w drugim
|
||||
}
|
||||
else
|
||||
{//a tu coœ dla SM42 i SM31, aby pokazywaæ na manometrze
|
||||
PantPress=CntrlPipePress;
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TMoverParameters::UpdateBatteryVoltage(double dt)
|
||||
{//przeliczenie obci¹¿enia baterii
|
||||
double sn1,sn2,sn3,sn4,sn5; //Ra: zrobiæ z tego amperomierz NN
|
||||
if ((BatteryVoltage>0)&&(EngineType!=DieselEngine)&&(EngineType!=WheelsDriven)&&(NominalBatteryVoltage>0))
|
||||
{
|
||||
if ((NominalBatteryVoltage/BatteryVoltage<1.22)&&Battery)
|
||||
{//110V
|
||||
if (!ConverterFlag)
|
||||
sn1=(dt*2.0); //szybki spadek do ok 90V
|
||||
else sn1=0;
|
||||
if (ConverterFlag)
|
||||
sn2=-(dt*2.0); //szybki wzrost do 110V
|
||||
else sn2=0;
|
||||
if (Mains)
|
||||
sn3=(dt*0.05);
|
||||
else sn3=0;
|
||||
if (iLights[0]&63) //64=blachy, nie ci¹gn¹ pr¹du //rozpisaæ na poszczególne ¿arówki...
|
||||
sn4=dt*0.003;
|
||||
else sn4=0;
|
||||
if (iLights[1]&63) //64=blachy, nie ci¹gn¹ pr¹du
|
||||
sn5=dt*0.001;
|
||||
else sn5=0;
|
||||
};
|
||||
if ((NominalBatteryVoltage/BatteryVoltage>=1.22)&&Battery)
|
||||
{//90V
|
||||
if (PantCompFlag)
|
||||
sn1=(dt*0.0046);
|
||||
else sn1=0;
|
||||
if (ConverterFlag)
|
||||
sn2=-(dt*50); //szybki wzrost do 110V
|
||||
else sn2=0;
|
||||
if (Mains)
|
||||
sn3=(dt*0.001);
|
||||
else sn3=0;
|
||||
if (iLights[0]&63) //64=blachy, nie ci¹gn¹ pr¹du
|
||||
sn4=(dt*0.0030);
|
||||
else sn4=0;
|
||||
if (iLights[1]&63) //64=blachy, nie ci¹gn¹ pr¹du
|
||||
sn5=(dt*0.0010);
|
||||
else sn5=0;
|
||||
};
|
||||
if (!Battery)
|
||||
{
|
||||
if (NominalBatteryVoltage/BatteryVoltage<1.22)
|
||||
sn1=dt*50;
|
||||
else
|
||||
sn1=0;
|
||||
sn2=dt*0.000001;
|
||||
sn3=dt*0.000001;
|
||||
sn4=dt*0.000001;
|
||||
sn5=dt*0.000001; //bardzo powolny spadek przy wy³¹czonych bateriach
|
||||
};
|
||||
BatteryVoltage-=(sn1+sn2+sn3+sn4+sn5);
|
||||
if (NominalBatteryVoltage/BatteryVoltage>1.57)
|
||||
if (MainSwitch(false)&&(EngineType!=DieselEngine)&&(EngineType!=WheelsDriven))
|
||||
EventFlag=true; //wywalanie szybkiego z powodu zbyt niskiego napiecia
|
||||
if (BatteryVoltage>NominalBatteryVoltage)
|
||||
BatteryVoltage=NominalBatteryVoltage; //wstrzymanie ³adowania pow. 110V
|
||||
if (BatteryVoltage<0.01)
|
||||
BatteryVoltage=0.01;
|
||||
}
|
||||
else
|
||||
if (NominalBatteryVoltage==0)
|
||||
BatteryVoltage=0;
|
||||
else
|
||||
BatteryVoltage=90;
|
||||
};
|
||||
|
||||
/* Ukrotnienie EN57:
|
||||
1 //uk³ad szeregowy
|
||||
2 //uk³ad równoleg³y
|
||||
3 //bocznik 1
|
||||
4 //bocznik 2
|
||||
5 //bocznik 3
|
||||
6 //do przodu
|
||||
7 //do ty³u
|
||||
8 //1 przyspieszenie
|
||||
9 //minus obw. 2 przyspieszenia
|
||||
10 //jazda na oporach
|
||||
11 //SHP
|
||||
12A //podnoszenie pantografu przedniego
|
||||
12B //podnoszenie pantografu tylnego
|
||||
13A //opuszczanie pantografu przedniego
|
||||
13B //opuszczanie wszystkich pantografów
|
||||
14 //za³¹czenie WS
|
||||
15 //rozrz¹d (WS, PSR, wa³ ku³akowy)
|
||||
16 //odblok PN
|
||||
18 //sygnalizacja przetwornicy g³ównej
|
||||
19 //luzowanie EP
|
||||
20 //hamowanie EP
|
||||
21 //rezerwa** (1900+: zamykanie drzwi prawych)
|
||||
22 //za³. przetwornicy g³ównej
|
||||
23 //wy³. przetwornicy g³ównej
|
||||
24 //za³. przetw. oœwietlenia
|
||||
25 //wy³. przetwornicy oœwietlenia
|
||||
26 //sygnalizacja WS
|
||||
28 //sprê¿arka
|
||||
29 //ogrzewanie
|
||||
30 //rezerwa* (1900+: zamykanie drzwi lewych)
|
||||
31 //otwieranie drzwi prawych
|
||||
32H //zadzia³anie PN siln. trakcyjnych
|
||||
33 //sygna³ odjazdu
|
||||
34 //rezerwa (sygnalizacja poœlizgu)
|
||||
35 //otwieranie drzwi lewych
|
||||
ZN //masa
|
||||
*/
|
||||
|
||||
double __fastcall TMoverParameters::ComputeMovement
|
||||
(double dt,double dt1,
|
||||
const TTrackShape &Shape,TTrackParam &Track,TTractionParam &ElectricTraction,
|
||||
const TLocation &NewLoc,TRotation &NewRot
|
||||
)
|
||||
{//trzeba po ma³u przenosiæ tu tê funkcjê
|
||||
double d;
|
||||
T_MoverParameters::ComputeMovement(dt,dt1,Shape,Track,ElectricTraction,NewLoc,NewRot);
|
||||
if (Power>1.0) //w rozrz¹dczym nie (jest b³¹d w FIZ!) - Ra 2014-07: teraz we wszystkich
|
||||
UpdatePantVolume(dt); //Ra 2014-07: obs³uga zbiornika rozrz¹du oraz pantografów
|
||||
|
||||
if (EngineType==WheelsDriven)
|
||||
d=CabNo*dL; //na chwile dla testu
|
||||
else
|
||||
d=dL;
|
||||
DistCounter=DistCounter+fabs(dL)/1000.0;
|
||||
dL=0;
|
||||
|
||||
//koniec procedury, tu nastepuja dodatkowe procedury pomocnicze
|
||||
|
||||
//sprawdzanie i ewentualnie wykonywanie->kasowanie poleceñ
|
||||
if (LoadStatus>0) //czas doliczamy tylko jeœli trwa (roz)³adowanie
|
||||
LastLoadChangeTime=LastLoadChangeTime+dt; //czas (roz)³adunku
|
||||
RunInternalCommand();
|
||||
//automatyczny rozruch
|
||||
if (EngineType==ElectricSeriesMotor)
|
||||
if (AutoRelayCheck())
|
||||
SetFlag(SoundFlag,sound_relay);
|
||||
/*
|
||||
else {McZapkie-041003: aby slychac bylo przelaczniki w sterowniczym}
|
||||
if (EngineType=None) and (MainCtrlPosNo>0) then
|
||||
for b:=0 to 1 do
|
||||
with Couplers[b] do
|
||||
if TestFlag(CouplingFlag,ctrain_controll) then
|
||||
if Connected^.Power>0.01 then
|
||||
SoundFlag:=SoundFlag or Connected^.SoundFlag;
|
||||
*/
|
||||
if (EngineType==DieselEngine)
|
||||
if (dizel_Update(dt))
|
||||
SetFlag(SoundFlag,sound_relay);
|
||||
//uklady hamulcowe:
|
||||
if (VeselVolume>0)
|
||||
Compressor=CompressedVolume/VeselVolume;
|
||||
else
|
||||
{
|
||||
Compressor=0;
|
||||
CompressorFlag=false;
|
||||
};
|
||||
ConverterCheck();
|
||||
if (CompressorSpeed>0.0) //sprê¿arka musi mieæ jak¹œ niezerow¹ wydajnoœæ
|
||||
CompressorCheck(dt); //¿eby rozwa¿aæ jej za³¹czenie i pracê
|
||||
UpdateBrakePressure(dt);
|
||||
UpdatePipePressure(dt);
|
||||
UpdateBatteryVoltage(dt);
|
||||
UpdateScndPipePressure(dt); // druga rurka, youBy
|
||||
//hamulec antypoœlizgowy - wy³¹czanie
|
||||
if ((BrakeSlippingTimer>0.8)&&(ASBType!=128)) //ASBSpeed=0.8
|
||||
Hamulec->ASB(0);
|
||||
//SetFlag(BrakeStatus,-b_antislip);
|
||||
BrakeSlippingTimer=BrakeSlippingTimer+dt;
|
||||
//sypanie piasku - wy³¹czone i piasek siê nie koñczy - b³êdy AI
|
||||
//if AIControllFlag then
|
||||
// if SandDose then
|
||||
// if Sand>0 then
|
||||
// begin
|
||||
// Sand:=Sand-NPoweredAxles*SandSpeed*dt;
|
||||
// if Random<dt then SandDose:=false;
|
||||
// end
|
||||
// else
|
||||
// begin
|
||||
// SandDose:=false;
|
||||
// Sand:=0;
|
||||
// end;
|
||||
//czuwak/SHP
|
||||
//if (Vel>10) and (not DebugmodeFlag) then
|
||||
if (!DebugModeFlag)
|
||||
SecuritySystemCheck(dt1);
|
||||
return d;
|
||||
};
|
||||
|
||||
double __fastcall TMoverParameters::FastComputeMovement
|
||||
(double dt,
|
||||
const TTrackShape &Shape,TTrackParam &Track,
|
||||
const TLocation &NewLoc,TRotation &NewRot
|
||||
)
|
||||
{//trzeba po ma³u przenosiæ tu tê funkcjê
|
||||
double d;
|
||||
T_MoverParameters::FastComputeMovement(dt,Shape,Track,NewLoc,NewRot);
|
||||
if (Power>1.0) //w rozrz¹dczym nie (jest b³¹d w FIZ!)
|
||||
UpdatePantVolume(dt); //Ra 2014-07: obs³uga zbiornika rozrz¹du oraz pantografów
|
||||
if (EngineType==WheelsDriven)
|
||||
d=CabNo*dL; //na chwile dla testu
|
||||
else
|
||||
d=dL;
|
||||
DistCounter=DistCounter+fabs(dL)/1000.0;
|
||||
dL=0;
|
||||
|
||||
//koniec procedury, tu nastepuja dodatkowe procedury pomocnicze
|
||||
|
||||
//sprawdzanie i ewentualnie wykonywanie->kasowanie poleceñ
|
||||
if (LoadStatus>0) //czas doliczamy tylko jeœli trwa (roz)³adowanie
|
||||
LastLoadChangeTime=LastLoadChangeTime+dt; //czas (roz)³adunku
|
||||
RunInternalCommand();
|
||||
if (EngineType==DieselEngine)
|
||||
if (dizel_Update(dt))
|
||||
SetFlag(SoundFlag,sound_relay);
|
||||
//uklady hamulcowe:
|
||||
if (VeselVolume>0)
|
||||
Compressor=CompressedVolume/VeselVolume;
|
||||
else
|
||||
{
|
||||
Compressor=0;
|
||||
CompressorFlag=false;
|
||||
};
|
||||
ConverterCheck();
|
||||
if (CompressorSpeed>0.0) //sprê¿arka musi mieæ jak¹œ niezerow¹ wydajnoœæ
|
||||
CompressorCheck(dt); //¿eby rozwa¿aæ jej za³¹czenie i pracê
|
||||
UpdateBrakePressure(dt);
|
||||
UpdatePipePressure(dt);
|
||||
UpdateScndPipePressure(dt); // druga rurka, youBy
|
||||
UpdateBatteryVoltage(dt);
|
||||
//hamulec antyposlizgowy - wy³¹czanie
|
||||
if ((BrakeSlippingTimer>0.8)&&(ASBType!=128)) //ASBSpeed=0.8
|
||||
Hamulec->ASB(0);
|
||||
BrakeSlippingTimer=BrakeSlippingTimer+dt;
|
||||
return d;
|
||||
};
|
||||
|
||||
double __fastcall TMoverParameters::ShowEngineRotation(int VehN)
|
||||
{//pokazywanie obrotów silnika, równie¿ dwóch dalszych pojazdów (3×SN61)
|
||||
int b;
|
||||
switch (VehN)
|
||||
{//numer obrotomierza
|
||||
case 1:
|
||||
return fabs(enrot);
|
||||
case 2:
|
||||
for (b=0;b<=1;++b)
|
||||
if (TestFlag(Couplers[b].CouplingFlag,ctrain_controll))
|
||||
if (Couplers[b].Connected->Power>0.01)
|
||||
return fabs(Couplers[b].Connected->enrot);
|
||||
break;
|
||||
case 3: //to nie uwzglêdnia ewentualnego odwrócenia pojazdu w œrodku
|
||||
for (b=0;b<=1;++b)
|
||||
if (TestFlag(Couplers[b].CouplingFlag,ctrain_controll))
|
||||
if (Couplers[b].Connected->Power>0.01)
|
||||
if (TestFlag(Couplers[b].Connected->Couplers[b].CouplingFlag,ctrain_controll))
|
||||
if (Couplers[b].Connected->Couplers[b].Connected->Power>0.01)
|
||||
return fabs(Couplers[b].Connected->Couplers[b].Connected->enrot);
|
||||
break;
|
||||
};
|
||||
return 0.0;
|
||||
};
|
||||
|
||||
void __fastcall TMoverParameters::ConverterCheck()
|
||||
{//sprawdzanie przetwornicy
|
||||
if (ConverterAllow&&Mains)
|
||||
ConverterFlag=true;
|
||||
else
|
||||
ConverterFlag=false;
|
||||
};
|
||||
|
||||
int __fastcall TMoverParameters::ShowCurrent(Byte AmpN)
|
||||
{//odczyt ampera¿u
|
||||
switch (EngineType)
|
||||
{case ElectricInductionMotor:
|
||||
switch (AmpN)
|
||||
{//do asynchronicznych
|
||||
case 1: return WindingRes*Mm/Vadd;
|
||||
case 2: return dizel_fill*WindingRes;
|
||||
default: return T_MoverParameters::ShowCurrent(AmpN);
|
||||
}
|
||||
break;
|
||||
case DieselElectric:
|
||||
return fabs(Im);
|
||||
break;
|
||||
default:
|
||||
return T_MoverParameters::ShowCurrent(AmpN);
|
||||
}
|
||||
};
|
||||
173
Mover.h
Normal file
173
Mover.h
Normal file
@@ -0,0 +1,173 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef MoverH
|
||||
#define MoverH
|
||||
//---------------------------------------------------------------------------
|
||||
#include "Mover.hpp"
|
||||
// Ra: Niestety "_mover.hpp" siê nieprawid³owo generuje - przek³ada sobie TCoupling na sam koniec.
|
||||
// Przy wszelkich poprawkach w "_mover.pas" trzeba skopiowaæ rêcznie "_mover.hpp" do "mover.hpp" i
|
||||
// poprawiæ b³êdy! Tak a¿ do wydzielnia TCoupling z Pascala do C++...
|
||||
// Docelowo obs³ugê sprzêgów (³¹czenie, roz³¹czanie, obliczanie odleg³oœci, przesy³ komend)
|
||||
// trzeba przenieϾ na poziom DynObj.cpp.
|
||||
// Obs³ugê silniników te¿ trzeba wydzieliæ do osobnego modu³u, bo ka¿dy osobno mo¿e mieæ poœlizg.
|
||||
#include "dumb3d.h"
|
||||
using namespace Math3D;
|
||||
|
||||
enum TProblem //lista problemów taboru, które uniemo¿liwiaj¹ jazdê
|
||||
{//flagi bitowe
|
||||
pr_Hamuje=1, //pojazd ma za³¹czony hamulec lub zatarte osie
|
||||
pr_Pantografy=2, //pojazd wymaga napompowania pantografów
|
||||
pr_Ostatni=0x80000000 //ostatnia flaga bitowa
|
||||
};
|
||||
|
||||
class TMoverParameters : public T_MoverParameters
|
||||
{//Ra: wrapper na kod pascalowy, przejmuj¹cy jego funkcje
|
||||
public:
|
||||
vector3 vCoulpler[2]; //powtórzenie wspó³rzêdnych sprzêgów z DynObj :/
|
||||
vector3 DimHalf; //po³owy rozmiarów do obliczeñ geometrycznych
|
||||
//int WarningSignal; //0: nie trabi, 1,2: trabi syren¹ o podanym numerze
|
||||
unsigned char WarningSignal; //tymczasowo 8bit, ze wzglêdu na funkcje w MTools
|
||||
double fBrakeCtrlPos; //p³ynna nastawa hamulca zespolonego
|
||||
bool bPantKurek3; //kurek trójdrogowy (pantografu): true=po³¹czenie z ZG, false=po³¹czenie z ma³¹ sprê¿ark¹
|
||||
int iProblem; //flagi problemów z taborem, aby AI nie musia³o porównywaæ; 0=mo¿e jechaæ
|
||||
int iLights[2]; //bity zapalonych œwiate³ tutaj, ¿eby da³o siê liczyæ pobór pr¹du
|
||||
private:
|
||||
double __fastcall CouplerDist(Byte Coupler);
|
||||
public:
|
||||
__fastcall TMoverParameters(double VelInitial,AnsiString TypeNameInit,AnsiString NameInit,
|
||||
int LoadInitial,AnsiString LoadTypeInitial,int Cab);
|
||||
//obs³uga sprzêgów
|
||||
double __fastcall Distance(const TLocation &Loc1,const TLocation &Loc2,const TDimension &Dim1,const TDimension &Dim2);
|
||||
double __fastcall Distance(const vector3 &Loc1,const vector3 &Loc2,const vector3 &Dim1,const vector3 &Dim2);
|
||||
bool __fastcall Attach(Byte ConnectNo,Byte ConnectToNr,TMoverParameters *ConnectTo,Byte CouplingType,bool Forced=false);
|
||||
bool __fastcall Attach(Byte ConnectNo,Byte ConnectToNr,T_MoverParameters *ConnectTo,Byte CouplingType,bool Forced=false);
|
||||
int __fastcall DettachStatus(Byte ConnectNo);
|
||||
bool __fastcall Dettach(Byte ConnectNo);
|
||||
void __fastcall SetCoupleDist();
|
||||
bool __fastcall DirectionForward();
|
||||
void __fastcall BrakeLevelSet(double b);
|
||||
bool __fastcall BrakeLevelAdd(double b);
|
||||
bool __fastcall IncBrakeLevel(); //wersja na u¿ytek AI
|
||||
bool __fastcall DecBrakeLevel();
|
||||
bool __fastcall ChangeCab(int direction);
|
||||
bool __fastcall CurrentSwitch(int direction);
|
||||
void __fastcall UpdateBatteryVoltage(double dt);
|
||||
double __fastcall ComputeMovement
|
||||
(double dt,double dt1,
|
||||
const TTrackShape &Shape,TTrackParam &Track,TTractionParam &ElectricTraction,
|
||||
const TLocation &NewLoc,TRotation &NewRot
|
||||
);
|
||||
double __fastcall FastComputeMovement
|
||||
(double dt,
|
||||
const TTrackShape &Shape,TTrackParam &Track,
|
||||
const TLocation &NewLoc,TRotation &NewRot
|
||||
);
|
||||
double __fastcall ShowEngineRotation(int VehN);
|
||||
//double __fastcall GetTrainsetVoltage(void);
|
||||
//bool __fastcall Physic_ReActivation(void);
|
||||
//double __fastcall LocalBrakeRatio(void);
|
||||
//double __fastcall ManualBrakeRatio(void);
|
||||
//double __fastcall PipeRatio(void);
|
||||
//double __fastcall RealPipeRatio(void);
|
||||
//double __fastcall BrakeVP(void);
|
||||
//bool __fastcall DynamicBrakeSwitch(bool Switch);
|
||||
//bool __fastcall SendCtrlBroadcast(AnsiString CtrlCommand, double ctrlvalue);
|
||||
//bool __fastcall SendCtrlToNext(AnsiString CtrlCommand, double ctrlvalue, double dir);
|
||||
//bool __fastcall CabActivisation(void);
|
||||
//bool __fastcall CabDeactivisation(void);
|
||||
//bool __fastcall IncMainCtrl(int CtrlSpeed);
|
||||
//bool __fastcall DecMainCtrl(int CtrlSpeed);
|
||||
//bool __fastcall IncScndCtrl(int CtrlSpeed);
|
||||
//bool __fastcall DecScndCtrl(int CtrlSpeed);
|
||||
//bool __fastcall AddPulseForce(int Multipler);
|
||||
//bool __fastcall SandDoseOn(void);
|
||||
//bool __fastcall SecuritySystemReset(void);
|
||||
//void __fastcall SecuritySystemCheck(double dt);
|
||||
//bool __fastcall BatterySwitch(bool State);
|
||||
//bool __fastcall EpFuseSwitch(bool State);
|
||||
//bool __fastcall IncBrakeLevelOld(void);
|
||||
//bool __fastcall DecBrakeLevelOld(void);
|
||||
//bool __fastcall IncLocalBrakeLevel(Byte CtrlSpeed);
|
||||
//bool __fastcall DecLocalBrakeLevel(Byte CtrlSpeed);
|
||||
//bool __fastcall IncLocalBrakeLevelFAST(void);
|
||||
//bool __fastcall DecLocalBrakeLevelFAST(void);
|
||||
//bool __fastcall IncManualBrakeLevel(Byte CtrlSpeed);
|
||||
//bool __fastcall DecManualBrakeLevel(Byte CtrlSpeed);
|
||||
//bool __fastcall EmergencyBrakeSwitch(bool Switch);
|
||||
//bool __fastcall AntiSlippingBrake(void);
|
||||
//bool __fastcall BrakeReleaser(Byte state);
|
||||
//bool __fastcall SwitchEPBrake(Byte state);
|
||||
//bool __fastcall AntiSlippingButton(void);
|
||||
//bool __fastcall IncBrakePress(double &brake, double PressLimit, double dp);
|
||||
//bool __fastcall DecBrakePress(double &brake, double PressLimit, double dp);
|
||||
//bool __fastcall BrakeDelaySwitch(Byte BDS);
|
||||
//bool __fastcall IncBrakeMult(void);
|
||||
//bool __fastcall DecBrakeMult(void);
|
||||
//void __fastcall UpdateBrakePressure(double dt);
|
||||
//void __fastcall UpdatePipePressure(double dt);
|
||||
//void __fastcall CompressorCheck(double dt);
|
||||
void __fastcall UpdatePantVolume(double dt);
|
||||
//void __fastcall UpdateScndPipePressure(double dt);
|
||||
//void __fastcall UpdateBatteryVoltage(double dt);
|
||||
//double __fastcall GetDVc(double dt);
|
||||
//void __fastcall ComputeConstans(void);
|
||||
//double __fastcall ComputeMass(void);
|
||||
//double __fastcall Adhesive(double staticfriction);
|
||||
//double __fastcall TractionForce(double dt);
|
||||
//double __fastcall FrictionForce(double R, Byte TDamage);
|
||||
//double __fastcall BrakeForce(const TTrackParam &Track);
|
||||
//double __fastcall CouplerForce(Byte CouplerN, double dt);
|
||||
//void __fastcall CollisionDetect(Byte CouplerN, double dt);
|
||||
//double __fastcall ComputeRotatingWheel(double WForce, double dt, double n);
|
||||
//bool __fastcall SetInternalCommand(AnsiString NewCommand, double NewValue1, double NewValue2);
|
||||
//double __fastcall GetExternalCommand(AnsiString &Command);
|
||||
//bool __fastcall RunCommand(AnsiString command, double CValue1, double CValue2);
|
||||
//bool __fastcall RunInternalCommand(void);
|
||||
//void __fastcall PutCommand(AnsiString NewCommand, double NewValue1, double NewValue2, const TLocation
|
||||
// &NewLocation);
|
||||
//bool __fastcall DirectionBackward(void);
|
||||
//bool __fastcall MainSwitch(bool State);
|
||||
//bool __fastcall ConverterSwitch(bool State);
|
||||
//bool __fastcall CompressorSwitch(bool State);
|
||||
void __fastcall ConverterCheck();
|
||||
//bool __fastcall FuseOn(void);
|
||||
//bool __fastcall FuseFlagCheck(void);
|
||||
//void __fastcall FuseOff(void);
|
||||
int __fastcall ShowCurrent(Byte AmpN);
|
||||
//double __fastcall v2n(void);
|
||||
//double __fastcall current(double n, double U);
|
||||
//double __fastcall Momentum(double I);
|
||||
//double __fastcall MomentumF(double I, double Iw, Byte SCP);
|
||||
//bool __fastcall CutOffEngine(void);
|
||||
//bool __fastcall MaxCurrentSwitch(bool State);
|
||||
//bool __fastcall ResistorsFlagCheck(void);
|
||||
//bool __fastcall MinCurrentSwitch(bool State);
|
||||
//bool __fastcall AutoRelaySwitch(bool State);
|
||||
//bool __fastcall AutoRelayCheck(void);
|
||||
//bool __fastcall dizel_EngageSwitch(double state);
|
||||
//bool __fastcall dizel_EngageChange(double dt);
|
||||
//bool __fastcall dizel_AutoGearCheck(void);
|
||||
//double __fastcall dizel_fillcheck(Byte mcp);
|
||||
//double __fastcall dizel_Momentum(double dizel_fill, double n, double dt);
|
||||
//bool __fastcall dizel_Update(double dt);
|
||||
//bool __fastcall LoadingDone(double LSpeed, AnsiString LoadInit);
|
||||
//void __fastcall ComputeTotalForce(double dt, double dt1, bool FullVer);
|
||||
//double __fastcall ComputeMovement(double dt, double dt1, const TTrackShape &Shape, TTrackParam &Track
|
||||
// , TTractionParam &ElectricTraction, const TLocation &NewLoc, TRotation &NewRot);
|
||||
//double __fastcall FastComputeMovement(double dt, const TTrackShape &Shape, TTrackParam &Track, const
|
||||
// TLocation &NewLoc, TRotation &NewRot);
|
||||
//bool __fastcall ChangeOffsetH(double DeltaOffset);
|
||||
//__fastcall T_MoverParameters(double VelInitial, AnsiString TypeNameInit, AnsiString NameInit, int LoadInitial
|
||||
// , AnsiString LoadTypeInitial, int Cab);
|
||||
//bool __fastcall LoadChkFile(AnsiString chkpath);
|
||||
//bool __fastcall CheckLocomotiveParameters(bool ReadyFlag, int Dir);
|
||||
//AnsiString __fastcall EngineDescription(int what);
|
||||
//bool __fastcall DoorLeft(bool State);
|
||||
//bool __fastcall DoorRight(bool State);
|
||||
//bool __fastcall DoorBlockedFlag(void);
|
||||
//bool __fastcall PantFront(bool State);
|
||||
//bool __fastcall PantRear(bool State);
|
||||
//
|
||||
};
|
||||
|
||||
#endif
|
||||
167
Names.cpp
Normal file
167
Names.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include <vcl.h>
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Names.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
/*
|
||||
Moduł zarządzający plikami oraz wyszukiwaniem obiektów wg nazw.
|
||||
1. Ma przydzielony z góry (EU07.INI) obszar pamięci (rzędu 16MB).
|
||||
2. W przypadku przepełnienia dostępnej pamięci wystąpi błąd wczytywania.
|
||||
3. Obszar ten będzie zużywany na rekordy obiektów oraz ciągi tekstowe z nazwami.
|
||||
4. Rekordy będą sortowane w ramach typu (tekstury, dźwięki, modele, node, eventy).
|
||||
5. Pierwszy etap wyszukiwania to 5 bitów z pierwszego bajtu i 3 z drugiego (256).
|
||||
6. Dla plików istnieje możliwość wczytania ich w innym terminie.
|
||||
7. Możliwość wczytania plików w oddzielnym watku (np. tekstur).
|
||||
|
||||
Obsługiwane pliki:
|
||||
1. Tekstury, można wczytywać później, rekord przechowuje numer podany przez kartę graficzną.
|
||||
2. Dźwięki, można wczytać później.
|
||||
3. Modele, można wczytać później o ile nie mają animacji eventami i nie dotyczą pojazdów.
|
||||
|
||||
Obiekty sortowane wg nazw, można dodawać i usuwać komórki scenerii:
|
||||
4. Tory, drogi, rzeki - wyszukiwanie w celu sprawdzenia zajetości.
|
||||
5. Eventy - wyszukiwane przy zewnętrznym wywołaniu oraz podczas wczytywania.
|
||||
6. Pojazdy - wyszukiwane w celu wysyłania komend.
|
||||
7. Egzemplarze modeli animowanych - wyszukiwanie w celu połączenia z animacjami.
|
||||
|
||||
*/
|
||||
|
||||
void __fastcall ItemRecord::TreeAdd(ItemRecord *r,int c)
|
||||
{//dodanie rekordu do drzewa - ustalenie w której gałęzi
|
||||
//zapisać w (iFlags) ile znaków jest zgodnych z nadrzędnym, żeby nie sprawdzać wszystkich od zera
|
||||
if ((cName[c]&&r->cName[c])?cName[c]==r->cName[c]:false)
|
||||
TreeAdd(r,c+1); //ustawić wg kolejnego znaku, chyba że zero
|
||||
else
|
||||
if ((unsigned char)(cName[c])<(unsigned char)(r->cName[c]))
|
||||
{//zero jest najmniejsze - doczepiamy jako (rNext)
|
||||
if (!rNext) rNext=r;
|
||||
else rNext->TreeAdd(r,0); //doczepić do tej gałęzi
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!rPrev) rPrev=r;
|
||||
else rPrev->TreeAdd(r,0); //doczepić do tej gałęzi
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall ItemRecord::ListGet(ItemRecord *r,int*&n)
|
||||
{//rekurencyjne wypełnianie posortowanej listy na podstawie drzewa
|
||||
if (rPrev) rPrev->ListGet(r,n); //dodanie wszystkich wcześniejszych
|
||||
*n++=this-r; //dodanie swojego indeksu do tabeli
|
||||
if (rNext) rNext->ListGet(r,n); //dodanie wszystkich późniejszych
|
||||
};
|
||||
|
||||
void* __fastcall 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)
|
||||
{//wyszukanie ciągu (n)
|
||||
ItemRecord *r=this; //żeby nie robić rekurencji
|
||||
int i=0;
|
||||
do
|
||||
{
|
||||
if (!n[i]) if (!r->cName[i]) return r; //znaleziony
|
||||
if (n[i]==r->cName[i])
|
||||
++i; //porównać kolejny znak
|
||||
else
|
||||
if ((unsigned char)(n[i])<(unsigned char)(r->cName[i]))
|
||||
{
|
||||
i=0; //porównywać od nowa
|
||||
r=r->rPrev; //wcześniejsza gałąź drzewa
|
||||
}
|
||||
else
|
||||
{
|
||||
i=0; //porównywać od nowa
|
||||
r=r->rNext; //późniejsza gałąź drzewa
|
||||
}
|
||||
} while (r);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
__fastcall TNames::TNames()
|
||||
{//tworzenie bufora
|
||||
iSize=16*1024*1024; //rozmiar bufora w bajtach
|
||||
cBuffer=new char[iSize];
|
||||
ZeroMemory(cBuffer,iSize); //nie trzymać jakiś starych śmieci
|
||||
rRecords=(ItemRecord*)cBuffer;
|
||||
cLast=cBuffer+iSize; //bajt za buforem
|
||||
iLast=-1;
|
||||
ZeroMemory(rTypes,20*sizeof(ItemRecord*));
|
||||
};
|
||||
|
||||
int __fastcall TNames::Add(int t,const char *n)
|
||||
{//dodanie obiektu typu (t) o nazwie (n)
|
||||
int len=strlen(n)+1; //ze znacznikiem końca
|
||||
cLast-=len; //rezerwacja miejsca
|
||||
memcpy(cLast,n,len); //przekopiowanie tekstu do bufora
|
||||
//cLast[len-1]='\0';
|
||||
rRecords[++iLast].cName=cLast; //połączenie nazwy z rekordem
|
||||
rRecords[iLast].iFlags=t;
|
||||
if (!rTypes[t])
|
||||
rTypes[t]=rRecords+iLast; //korzeń drzewa, bo nie było wcześniej
|
||||
else
|
||||
rTypes[t]->TreeAdd(rRecords+iLast,0); //doczepienie jako gałąź
|
||||
//rTypes[t]=Sort(t); //sortowanie uruchamiać ręcznie
|
||||
if ((iLast&0x3F)==0) //nie za często, bo sortowania zajmą więcej czasu niż wyszukiwania
|
||||
Sort(t); //optymalizacja drzewa co jakiś czas
|
||||
return iLast;
|
||||
}
|
||||
int __fastcall TNames::Add(int t,const char *n,void *d)
|
||||
{
|
||||
int i=Add(t,n);
|
||||
rRecords[iLast].pData=d;
|
||||
return i;
|
||||
};
|
||||
|
||||
bool __fastcall TNames::Update(int t,const char *n,void *d)
|
||||
{//dodanie jeśli nie ma, wymiana (d), gdy jest
|
||||
ItemRecord *r=FindRecord(t,n); //najpierw sprawdzić, czy już jest
|
||||
if (r)
|
||||
{//przy zdublowaniu nazwy podmieniać w drzewku na późniejszy
|
||||
r->pData=d;
|
||||
return true; //duplikat
|
||||
}
|
||||
//Add(t,n,d); //nazwa unikalna
|
||||
return false; //został dodany nowy
|
||||
};
|
||||
|
||||
ItemRecord* __fastcall TNames::TreeSet(int *n,int d,int u)
|
||||
{//rekurencyjne wypełnianie drzewa pozycjami od (d) do (u)
|
||||
if (d==u)
|
||||
{
|
||||
rRecords[n[d]].rPrev=rRecords[n[d]].rNext=NULL;
|
||||
return rRecords+n[d]; //tej gałęzi nie ma
|
||||
}
|
||||
else if (d>u) return NULL;
|
||||
int p=(u+d)>>1; //połowa
|
||||
rRecords[n[p]].rPrev=TreeSet(n,d,p-1); //zapisanie wcześniejszych gałęzi
|
||||
rRecords[n[p]].rNext=TreeSet(n,p+1,u); //zapisanie późniejszych gałęzi
|
||||
return rRecords+n[p];
|
||||
};
|
||||
|
||||
void __fastcall TNames::Sort(int t)
|
||||
{//przebudowa drzewa typu (t), zwraca wierzchołek drzewa
|
||||
if (iLast<3) return; //jak jest mało, to nie ma sensu sortować
|
||||
if (rTypes[t]) //jeśli jest jakiś rekord danego typu
|
||||
{int *r=new int[iLast+1]; //robocza tablica indeksów - numery posortowanych rekordów
|
||||
int *q=r; //wskaźnik roboczy, przekazywany przez referencję
|
||||
rTypes[t]->ListGet(rRecords,q); //drzewo jest już posortowane - zamienić je na listę
|
||||
rTypes[t]=TreeSet(r,0,(q-r)-1);
|
||||
delete[] r;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
ItemRecord* __fastcall TNames::FindRecord(const int t,const char *n)
|
||||
{//poszukiwanie rekordu w celu np. zmiany wskaźnika
|
||||
return rTypes[t]?rTypes[t]->TreeFindRecord(n):NULL;
|
||||
};
|
||||
|
||||
53
Names.h
Normal file
53
Names.h
Normal file
@@ -0,0 +1,53 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef NamesH
|
||||
#define NamesH
|
||||
//---------------------------------------------------------------------------
|
||||
class ItemRecord
|
||||
{//rekord opisuj¹cy obiekt; raz utworzony nie przemieszcza siê
|
||||
//rozmiar rekordu mo¿na zmieniæ w razie potrzeby
|
||||
public:
|
||||
char *cName; //wskaŸnik do nazwy umieszczonej w buforze
|
||||
int iFlags; //flagi bitowe
|
||||
ItemRecord *rPrev,*rNext; //posortowane drzewo (przebudowywane w razie potrzeby)
|
||||
union
|
||||
{void *pData; //wskaŸnik do obiektu
|
||||
int iData; //albo numer obiektu (tekstury)
|
||||
unsigned int uData;
|
||||
};
|
||||
//typedef
|
||||
void __fastcall ListGet(ItemRecord *r,int*&n);
|
||||
void __fastcall TreeAdd(ItemRecord *r,int c);
|
||||
template <typename TOut> inline TOut* DataGet() {return (TOut*)pData;};
|
||||
template <typename TOut> inline void DataSet(TOut *x) {pData=(void*)x;};
|
||||
void* __fastcall TreeFind(const char *n);
|
||||
ItemRecord* __fastcall TreeFindRecord(const char *n);
|
||||
};
|
||||
|
||||
class TNames
|
||||
{
|
||||
public:
|
||||
int iSize; //rozmiar bufora
|
||||
char *cBuffer; //bufor dla rekordów (na pocz¹tku) i nazw (na koñcu)
|
||||
ItemRecord *rRecords; //rekordy na pocz¹tku bufora
|
||||
char *cLast; //ostatni u¿yty bajt na nazwy
|
||||
ItemRecord *rTypes[20]; //ro¿ne typy obiektów (pocz¹tek drzewa)
|
||||
int iLast; //ostatnio u¿yty rekord
|
||||
public:
|
||||
__fastcall TNames();
|
||||
int __fastcall Add(int t,const char *n); //dodanie obiektu typu (t)
|
||||
int __fastcall Add(int t,const char *n,void *d); //dodanie obiektu z wskaŸnikiem
|
||||
int __fastcall Add(int t,const char *n,int d); //dodanie obiektu z numerem
|
||||
bool __fastcall Update(int t,const char *n,void *d); //dodanie jeœli nie ma, wymiana (d), gdy jest
|
||||
void __fastcall TreeSet();
|
||||
ItemRecord* __fastcall TreeSet(int *n,int d,int u);
|
||||
void __fastcall Sort(int t); //przebudowa drzewa typu (t)
|
||||
ItemRecord* __fastcall 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);
|
||||
//template <typename TOut> inline TOut* Find(const int t,const char *n)
|
||||
//{return (TOut*)(rTypes[t]->TreeFind(n));};
|
||||
};
|
||||
#endif
|
||||
|
||||
151
QueryParserComp.hpp
Normal file
151
QueryParserComp.hpp
Normal file
@@ -0,0 +1,151 @@
|
||||
// Borland C++ Builder
|
||||
// Copyright (c) 1995, 1999 by Borland International
|
||||
// All rights reserved
|
||||
|
||||
// (DO NOT EDIT: machine generated header) 'QueryParserComp.pas' rev: 5.00
|
||||
|
||||
#ifndef QueryParserCompHPP
|
||||
#define QueryParserCompHPP
|
||||
|
||||
#pragma delphiheader begin
|
||||
#pragma option push -w-
|
||||
#pragma option push -Vx
|
||||
#include <SysUtils.hpp> // Pascal unit
|
||||
#include <Classes.hpp> // Pascal unit
|
||||
#include <SysInit.hpp> // Pascal unit
|
||||
#include <System.hpp> // Pascal unit
|
||||
|
||||
//-- user supplied -----------------------------------------------------------
|
||||
|
||||
namespace Queryparsercomp
|
||||
{
|
||||
//-- type declarations -------------------------------------------------------
|
||||
#pragma option push -b-
|
||||
enum TTokenType { ttString, ttSymbol, ttComment, ttDelimiter, ttSpecialChar, ttStatementDelimiter, ttCommentedSymbol,
|
||||
ttCommentDelimiter };
|
||||
#pragma option pop
|
||||
|
||||
typedef Set<char, 0, 255> TSetOfChar;
|
||||
|
||||
typedef AnsiString TComment[2];
|
||||
|
||||
#pragma option push -b-
|
||||
enum TCharacterType { ctSymbol, ctBeginComment, ctEndComment, ctDelimiter, ctString, ctSpecialChar }
|
||||
;
|
||||
#pragma option pop
|
||||
|
||||
#pragma option push -b-
|
||||
enum QueryParserComp__1 { cmt1, cmt2, cmt3 };
|
||||
#pragma option pop
|
||||
|
||||
typedef Set<QueryParserComp__1, cmt1, cmt3> TCommentType;
|
||||
|
||||
typedef AnsiString QueryParserComp__2[3][2];
|
||||
|
||||
typedef void __fastcall (__closure *TEndOfStatement)(System::TObject* Sender, AnsiString SQLStatement
|
||||
);
|
||||
|
||||
class DELPHICLASS TQueryParserComp;
|
||||
class PASCALIMPLEMENTATION TQueryParserComp : public Classes::TComponent
|
||||
{
|
||||
typedef Classes::TComponent inherited;
|
||||
|
||||
private:
|
||||
Classes::TStringStream* FStream;
|
||||
bool FEOF;
|
||||
AnsiString FToken;
|
||||
TTokenType FTokenType;
|
||||
bool FComment;
|
||||
bool FString;
|
||||
bool FWasString;
|
||||
TCommentType FCommentType;
|
||||
AnsiString FStringDelimiters;
|
||||
AnsiString FLastStringDelimiterFound;
|
||||
int FSymbolsCount;
|
||||
AnsiString FSpecialCharacters;
|
||||
bool FRemoveStrDelimiter;
|
||||
AnsiString FStringToParse;
|
||||
int FGoPosition;
|
||||
TEndOfStatement FOnStatementDelimiter;
|
||||
bool FCountFromStatement;
|
||||
Classes::TStringList* FStatementDelimiters;
|
||||
char FStringDelimiter;
|
||||
bool FGenerateOnStmtDelimiter;
|
||||
void __fastcall Init(void);
|
||||
void __fastcall SetStringToParse(AnsiString AStringToParse);
|
||||
bool __fastcall StatementDelimiter(void);
|
||||
bool __fastcall CheckForBeginComment(void);
|
||||
bool __fastcall CheckForEndComment(char Character);
|
||||
TCharacterType __fastcall CharacterType(char Character);
|
||||
bool __fastcall CheckCharcterType(char Character);
|
||||
bool __fastcall StringDelimiter(char Character);
|
||||
bool __fastcall SpecialCharacter(char Character);
|
||||
void __fastcall RemoveStringDelimiter(AnsiString &Source);
|
||||
void __fastcall SetDelimiterType(AnsiString Source);
|
||||
void __fastcall SetToken(void);
|
||||
void __fastcall SetSD(Classes::TStringList* ASD);
|
||||
void __fastcall SetSpecialCharacters(AnsiString ASpecialCharacters);
|
||||
void __fastcall SetStringDelimiters(AnsiString AStringDelimiters);
|
||||
|
||||
protected:
|
||||
DYNAMIC void __fastcall DoStatementDelimiter(void);
|
||||
|
||||
public:
|
||||
__fastcall virtual TQueryParserComp(Classes::TComponent* AOwner);
|
||||
__fastcall virtual ~TQueryParserComp(void);
|
||||
void __fastcall LoadStringToParse(AnsiString FileName);
|
||||
void __fastcall First(void);
|
||||
void __fastcall FirstToken(void);
|
||||
void __fastcall NextToken(void);
|
||||
AnsiString __fastcall GetNextSymbol();
|
||||
__property bool EndOfFile = {read=FEOF, nodefault};
|
||||
__property bool Comment = {read=FComment, nodefault};
|
||||
__property AnsiString Token = {read=FToken};
|
||||
__property TTokenType TokenType = {read=FTokenType, nodefault};
|
||||
__property char CurrentStringDelimiter = {read=FStringDelimiter, nodefault};
|
||||
__property int SymbolsCount = {read=FSymbolsCount, default=0};
|
||||
__property Classes::TStringStream* StringStream = {read=FStream};
|
||||
|
||||
__published:
|
||||
__property bool IsEOFStmtDelimiter = {read=FGenerateOnStmtDelimiter, write=FGenerateOnStmtDelimiter
|
||||
, nodefault};
|
||||
__property AnsiString StringDelimiters = {read=FStringDelimiters, write=SetStringDelimiters};
|
||||
__property AnsiString SpecialCharacters = {read=FSpecialCharacters, write=SetSpecialCharacters};
|
||||
__property bool RemoveStrDelimiter = {read=FRemoveStrDelimiter, write=FRemoveStrDelimiter, nodefault
|
||||
};
|
||||
__property bool CountFromStatement = {read=FCountFromStatement, write=FCountFromStatement, nodefault
|
||||
};
|
||||
__property AnsiString TextToParse = {read=FStringToParse, write=SetStringToParse};
|
||||
__property Classes::TStringList* StatementDelimiters = {read=FStatementDelimiters, write=SetSD};
|
||||
__property TEndOfStatement OnStatementDelimiter = {read=FOnStatementDelimiter, write=FOnStatementDelimiter
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
//-- var, const, procedure ---------------------------------------------------
|
||||
extern PACKAGE System::ResourceString _sTextNotSet;
|
||||
#define Queryparsercomp_sTextNotSet System::LoadResourceString(&Queryparsercomp::_sTextNotSet)
|
||||
extern PACKAGE System::ResourceString _sIllegalSpecialChar;
|
||||
#define Queryparsercomp_sIllegalSpecialChar System::LoadResourceString(&Queryparsercomp::_sIllegalSpecialChar)
|
||||
|
||||
extern PACKAGE System::ResourceString _sIllegalStringChar;
|
||||
#define Queryparsercomp_sIllegalStringChar System::LoadResourceString(&Queryparsercomp::_sIllegalStringChar)
|
||||
|
||||
static const char CR = '\xd';
|
||||
static const char LF = '\xa';
|
||||
static const char TAB = '\x9';
|
||||
#define CRLF "\r\n"
|
||||
extern PACKAGE TSetOfChar Delimiters;
|
||||
extern PACKAGE AnsiString Comments[3][2];
|
||||
extern PACKAGE void __fastcall Register(void);
|
||||
|
||||
} /* namespace Queryparsercomp */
|
||||
#if !defined(NO_IMPLICIT_NAMESPACE_USE)
|
||||
using namespace Queryparsercomp;
|
||||
#endif
|
||||
#pragma option pop // -w-
|
||||
#pragma option pop // -Vx
|
||||
|
||||
#pragma delphiheader end.
|
||||
//-- end unit ----------------------------------------------------------------
|
||||
#endif // QueryParserComp
|
||||
724
QueryParserComp.pas
Normal file
724
QueryParserComp.pas
Normal file
@@ -0,0 +1,724 @@
|
||||
unit QueryParserComp;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, Sysutils;
|
||||
|
||||
resourcestring
|
||||
sTextNotSet = 'You must set the TextToParse property first.';
|
||||
sIllegalSpecialChar = 'Illegal special character.';
|
||||
sIllegalStringChar = 'Illegal string delimiter.';
|
||||
|
||||
type
|
||||
TTokenType = (ttString, ttSymbol, ttComment, ttDelimiter, ttSpecialChar,
|
||||
ttStatementDelimiter, ttCommentedSymbol, ttCommentDelimiter);
|
||||
TSetOfChar = set of Char;
|
||||
TComment = array[0..1] of string;
|
||||
TCharacterType = (ctSymbol, ctBeginComment, ctEndComment, ctDelimiter,
|
||||
ctString, ctSpecialChar);
|
||||
TCommentType = set of (cmt1, cmt2, cmt3);
|
||||
|
||||
const
|
||||
CR = #13;
|
||||
LF = #10;
|
||||
TAB = #9;
|
||||
CRLF = CR + LF;
|
||||
Delimiters: TSetOfChar = [' ', ',', ';', CR, LF, TAB];
|
||||
Comments: array[0..2] of TComment = (('/*', '*/'), ('#', LF), ('//', LF));
|
||||
|
||||
type
|
||||
TEndOfStatement = procedure(Sender: TObject; SQLStatement: String) of object;
|
||||
|
||||
TQueryParserComp = class(TComponent)
|
||||
private
|
||||
FStream: TStringStream;
|
||||
FEOF: Boolean;
|
||||
FToken: String;
|
||||
FTokenType: TTokenType;
|
||||
FComment: Boolean;
|
||||
FString: Boolean;
|
||||
FWasString: Boolean;
|
||||
FCommentType: TCommentType;
|
||||
FStringDelimiters: String;
|
||||
FLastStringDelimiterFound: String;
|
||||
FSymbolsCount: Integer;
|
||||
FSpecialCharacters: String;
|
||||
FRemoveStrDelimiter: Boolean;
|
||||
FStringToParse: String;
|
||||
FGoPosition: Integer;
|
||||
FOnStatementDelimiter: TEndOfStatement;
|
||||
FCountFromStatement: Boolean;
|
||||
FStatementDelimiters: TStringList;
|
||||
FStringDelimiter: Char;
|
||||
FGenerateOnStmtDelimiter: Boolean;
|
||||
procedure Init;
|
||||
procedure SetStringToParse(AStringToParse: String);
|
||||
function StatementDelimiter: Boolean;
|
||||
function CheckForBeginComment: Boolean;
|
||||
function CheckForEndComment(Character: Char): Boolean;
|
||||
function CharacterType(Character: Char): TCharacterType;
|
||||
function CheckCharcterType(Character: Char): Boolean;
|
||||
function StringDelimiter(Character: Char): Boolean;
|
||||
function SpecialCharacter(Character: Char): Boolean;
|
||||
procedure RemoveStringDelimiter(var Source: String);
|
||||
procedure SetDelimiterType(Source: String);
|
||||
procedure SetToken;
|
||||
procedure SetSD(ASD: TStringList);
|
||||
procedure SetSpecialCharacters(ASpecialCharacters: String);
|
||||
procedure SetStringDelimiters(AStringDelimiters: String);
|
||||
protected
|
||||
procedure DoStatementDelimiter; dynamic;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure LoadStringToParse(FileName: string);
|
||||
procedure First;
|
||||
procedure FirstToken;
|
||||
procedure NextToken;
|
||||
function GetNextSymbol : string;
|
||||
property EndOfFile: Boolean read FEOF;
|
||||
property Comment: Boolean read FComment;
|
||||
property Token: String read FToken;
|
||||
property TokenType: TTokenType read FTokenType;
|
||||
property CurrentStringDelimiter: Char read FStringDelimiter;
|
||||
property SymbolsCount: Integer read FSymbolsCount default 0;
|
||||
property StringStream: TStringStream read FStream;
|
||||
published
|
||||
property IsEOFStmtDelimiter: Boolean read FGenerateOnStmtDelimiter
|
||||
write FGenerateOnStmtDelimiter;
|
||||
property StringDelimiters: String read FStringDelimiters
|
||||
write SetStringDelimiters;
|
||||
property SpecialCharacters: String read FSpecialCharacters
|
||||
write SetSpecialCharacters;
|
||||
property RemoveStrDelimiter: Boolean read FRemoveStrDelimiter
|
||||
write FRemoveStrDelimiter;
|
||||
property CountFromStatement: Boolean read FCountFromStatement
|
||||
write FCountFromStatement;
|
||||
property TextToParse: String read FStringToParse
|
||||
write SetStringToParse;
|
||||
property StatementDelimiters: TStringList read FStatementDelimiters write SetSD;
|
||||
property OnStatementDelimiter: TEndOfStatement read FOnStatementDelimiter
|
||||
write FOnStatementDelimiter;
|
||||
end;
|
||||
|
||||
procedure Register;
|
||||
|
||||
implementation
|
||||
|
||||
{ TSQLParser }
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterComponents('Samples', [TQueryParserComp]);
|
||||
end;
|
||||
|
||||
constructor TQueryParserComp.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited;
|
||||
FStatementDelimiters := TStringList.Create;
|
||||
FStatementDelimiters.Add('GO');
|
||||
FStatementDelimiters.Add(';');
|
||||
FCountFromStatement := True;
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.LoadStringToParse(FileName: string);
|
||||
var
|
||||
fs:TFileStream;
|
||||
size:integer;
|
||||
begin
|
||||
|
||||
fs:= TFileStream.Create(FileName, fmOpenRead);
|
||||
|
||||
size:= fs.Size;
|
||||
|
||||
if Assigned(FStream) then
|
||||
FStream.Free;
|
||||
|
||||
FStream := TStringStream.Create('');
|
||||
FStream.CopyFrom(fs,size);
|
||||
fs.Free;
|
||||
Init;
|
||||
First;
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.FirstToken;
|
||||
begin
|
||||
Init;
|
||||
NextToken;
|
||||
end;
|
||||
|
||||
function TQueryParserComp.CheckForBeginComment: Boolean;
|
||||
var
|
||||
Buffer: String;
|
||||
begin
|
||||
Result := False;
|
||||
if not FEOF and not FString then
|
||||
begin
|
||||
Buffer := FStream.ReadString(1);
|
||||
if cmt1 in FCommentType then
|
||||
if Buffer[1] = '*' then
|
||||
begin
|
||||
FCommentType := [cmt1];
|
||||
Result := True;
|
||||
end;
|
||||
if cmt2 in FCommentType then
|
||||
if Buffer[1] = '/' then
|
||||
begin
|
||||
FCommentType := [cmt2];
|
||||
Result := True;
|
||||
end;
|
||||
if cmt3 in FCommentType then
|
||||
if Buffer[1] = '-' then
|
||||
begin
|
||||
FCommentType := [cmt3];
|
||||
Result := True;
|
||||
end;
|
||||
FStream.Seek(-1, soFromCurrent);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.SetDelimiterType(Source: String);
|
||||
begin
|
||||
FToken := Source[1];
|
||||
|
||||
if ((cmt2 in FCommentType) or (cmt3 in FCommentType)) and FComment
|
||||
and ((Source[1] = CR) or (Source[1] = LF)) then
|
||||
begin
|
||||
FComment := False;
|
||||
FTokenType := ttCommentDelimiter;
|
||||
end
|
||||
else
|
||||
FTokenType := ttDelimiter;
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.NextToken;
|
||||
var
|
||||
Buffer: String;
|
||||
ETextNotSet: Exception;
|
||||
begin
|
||||
if FEOF then
|
||||
Exit;
|
||||
|
||||
if not Assigned(FStream) then
|
||||
begin
|
||||
ETextNotSet := Exception.Create(sTextNotSet);
|
||||
raise ETextNotSet;
|
||||
end;
|
||||
|
||||
if not FString then
|
||||
FStringDelimiter := ' ';
|
||||
|
||||
FToken := '';
|
||||
if not FEOF then
|
||||
begin
|
||||
Buffer := FStream.ReadString(1);
|
||||
if Length(Buffer) > 0 then
|
||||
begin
|
||||
if (Buffer[1] in Delimiters) and not (FString or FComment)then
|
||||
SetDelimiterType(Buffer)
|
||||
else
|
||||
begin
|
||||
if FStream.Position > 0 then
|
||||
FStream.Seek(-1, soFromCurrent);
|
||||
SetToken;
|
||||
end;
|
||||
end
|
||||
else
|
||||
FEOF := True;
|
||||
end;
|
||||
|
||||
case FTokenType of
|
||||
ttSymbol: Inc(FSymbolsCount);
|
||||
ttString:
|
||||
begin
|
||||
FStringDelimiter := FToken[1];
|
||||
if FRemoveStrDelimiter then
|
||||
RemoveStringDelimiter(FToken);
|
||||
end;
|
||||
end;
|
||||
|
||||
if StatementDelimiter then
|
||||
FTokenType := ttStatementDelimiter;
|
||||
|
||||
if FEOF then
|
||||
begin
|
||||
FLastStringDelimiterFound := '';
|
||||
FWasString := False;
|
||||
FString := False;
|
||||
|
||||
if FGenerateOnStmtDelimiter then
|
||||
DoStatementDelimiter;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TQueryParserComp.GetNextSymbol : string;
|
||||
begin
|
||||
GetNextSymbol:= '';
|
||||
while ( not EndOfFile) do
|
||||
begin
|
||||
NextToken;
|
||||
if (TokenType=ttSymbol) then
|
||||
begin
|
||||
GetNextSymbol:= Token;
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
end;
|
||||
|
||||
function TQueryParserComp.StatementDelimiter: Boolean;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
if not FString then
|
||||
for i := 0 to FStatementDelimiters.Count - 1 do
|
||||
begin
|
||||
Result := (UpperCase(FToken) = UpperCase(FStatementDelimiters.Strings[i]));
|
||||
if Result then
|
||||
begin
|
||||
if FCountFromStatement then
|
||||
FSymbolsCount := 0;
|
||||
DoStatementDelimiter;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TQueryParserComp.CharacterType(Character: Char): TCharacterType;
|
||||
begin
|
||||
Result := ctSymbol;
|
||||
case Character of
|
||||
'/':
|
||||
begin
|
||||
if not FComment then
|
||||
begin
|
||||
FCommentType := [cmt1, cmt2];
|
||||
if CheckForBeginComment then
|
||||
Result := ctBeginComment;
|
||||
end;
|
||||
end;
|
||||
'-':
|
||||
begin
|
||||
if not FComment then
|
||||
begin
|
||||
FCommentType := [cmt3];
|
||||
if CheckForBeginComment then
|
||||
Result := ctBeginComment;
|
||||
end;
|
||||
end;
|
||||
'*':
|
||||
begin
|
||||
if CheckForEndComment(Character) then
|
||||
Result := ctEndComment;
|
||||
end;
|
||||
CR, LF, ' ', ',', TAB:
|
||||
begin
|
||||
if CheckForEndComment(Character) then
|
||||
Result := ctEndComment
|
||||
else
|
||||
Result := ctDelimiter;
|
||||
|
||||
if FString and ((Character = CR) or (Character = LF)) then
|
||||
begin
|
||||
FString := False;
|
||||
FWasString := False;
|
||||
Result := ctDelimiter;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if not FString then
|
||||
if SpecialCharacter(Character) then
|
||||
begin
|
||||
if not FComment then
|
||||
Result := ctSpecialChar;
|
||||
end;
|
||||
|
||||
if not FComment then
|
||||
if StringDelimiter(Character) then
|
||||
begin
|
||||
Result := ctSymbol;
|
||||
if FString then
|
||||
begin
|
||||
FLastStringDelimiterFound := '';
|
||||
FWasString := True;
|
||||
FString := False;
|
||||
end
|
||||
else
|
||||
begin
|
||||
FWasString := False;
|
||||
FString := True;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TQueryParserComp.CheckForEndComment(Character: Char): Boolean;
|
||||
var
|
||||
Buffer: String;
|
||||
begin
|
||||
Result := False;
|
||||
|
||||
if not FComment or FString then
|
||||
Exit;
|
||||
|
||||
if not FEOF then
|
||||
begin
|
||||
if cmt1 in FCommentType then
|
||||
begin
|
||||
Buffer := FStream.ReadString(1);
|
||||
if Buffer[1] = '/' then
|
||||
Result := True;
|
||||
|
||||
FStream.Seek(-1, soFromCurrent);
|
||||
end;
|
||||
if (cmt2 in FCommentType) or (cmt3 in FCommentType) then
|
||||
begin
|
||||
if (Character = CR) or (Character = LF) then
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TQueryParserComp.CheckCharcterType(Character: Char): Boolean;
|
||||
var
|
||||
Buffer: String;
|
||||
begin
|
||||
Result := False;
|
||||
case CharacterType(Character) of
|
||||
ctBeginComment:
|
||||
begin
|
||||
if not FComment then
|
||||
begin
|
||||
if FToken <> '' then
|
||||
begin
|
||||
FStream.Seek(-1, soFromCurrent);
|
||||
FTokenType := ttSymbol;
|
||||
end
|
||||
else
|
||||
begin
|
||||
FComment := True;
|
||||
FToken := FToken + Character;
|
||||
Buffer := FStream.ReadString(1);
|
||||
FToken := FToken + Buffer;
|
||||
FTokenType := ttComment;
|
||||
end;
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
ctEndComment:
|
||||
begin
|
||||
if FComment then
|
||||
begin
|
||||
Result := True;
|
||||
if FToken <> '' then
|
||||
begin
|
||||
FStream.Seek(-1, soFromCurrent);
|
||||
FTokenType := ttCommentedSymbol;
|
||||
end
|
||||
else
|
||||
begin
|
||||
FComment := False;
|
||||
FToken := FToken + Character;
|
||||
if FCommentType = [cmt1] then
|
||||
begin
|
||||
Buffer := FStream.ReadString(1);
|
||||
FToken := FToken + Buffer;
|
||||
end;
|
||||
FTokenType := ttComment;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
ctSymbol:
|
||||
begin
|
||||
FToken := FToken + Character;
|
||||
if FComment then
|
||||
FTokenType := ttCommentedSymbol
|
||||
else
|
||||
begin
|
||||
if FString or FWasString then
|
||||
begin
|
||||
if FWasString then
|
||||
begin
|
||||
FTokenType := ttString;
|
||||
FWasString := False;
|
||||
|
||||
|
||||
Result := True;
|
||||
end
|
||||
else
|
||||
FTokenType := ttString;
|
||||
end
|
||||
else
|
||||
FTokenType := ttSymbol;
|
||||
end;
|
||||
end;
|
||||
ctSpecialChar:
|
||||
begin
|
||||
if FToken <> '' then
|
||||
begin
|
||||
FStream.Seek(-1, soFromCurrent);
|
||||
FTokenType := ttSymbol;
|
||||
end
|
||||
else
|
||||
begin
|
||||
FToken := FToken + Character;
|
||||
FTokenType := ttSpecialChar;
|
||||
end;
|
||||
Result := True;
|
||||
end;
|
||||
ctDelimiter:
|
||||
begin
|
||||
FTokenType := ttDelimiter;
|
||||
Result := True;
|
||||
end;
|
||||
end
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.RemoveStringDelimiter(var Source: String);
|
||||
var
|
||||
EndOfString: Integer;
|
||||
i: Integer;
|
||||
begin
|
||||
for i := 1 to Length(FStringDelimiters) do
|
||||
begin
|
||||
EndOfString := 1;
|
||||
while not (EndOfString = 0) do
|
||||
begin
|
||||
EndOfString := Pos(FStringDelimiters[i], Source);
|
||||
if EndOfString <> 0 then
|
||||
begin
|
||||
FLastStringDelimiterFound := Copy(FStringDelimiters, i, 1);
|
||||
Delete(Source, EndOfString, 1);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TQueryParserComp.StringDelimiter(Character: Char): Boolean;
|
||||
var
|
||||
i: Integer;
|
||||
Buffer: String;
|
||||
begin
|
||||
Result := False;
|
||||
|
||||
for i := 1 to Length(FStringDelimiters) do
|
||||
if (Character = FStringDelimiters[i]) then
|
||||
begin
|
||||
if (FLastStringDelimiterFound = '') then
|
||||
FLastStringDelimiterFound := FStringDelimiters[i];
|
||||
|
||||
if (FLastStringDelimiterFound = FStringDelimiters[i]) then
|
||||
begin
|
||||
if not FEOF then
|
||||
Buffer := FStream.ReadString(1);
|
||||
|
||||
if Length(Buffer) > 0 then
|
||||
begin
|
||||
if Buffer[1] <> Character then
|
||||
begin
|
||||
FStream.Seek(-1, soFromCurrent);
|
||||
Result := True;
|
||||
end
|
||||
else
|
||||
FToken := FToken + Buffer;
|
||||
end
|
||||
else
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TQueryParserComp.SpecialCharacter(Character: Char): Boolean;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
for i := 1 to Length(FSpecialCharacters) do
|
||||
if Character = FSpecialCharacters[i] then
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.SetToken;
|
||||
var
|
||||
EndToken: Boolean;
|
||||
Buffer: String;
|
||||
begin
|
||||
EndToken := False;
|
||||
while not (EndToken or FEOF) do
|
||||
begin
|
||||
FEOF := FStream.Position >= FStream.Size-1;
|
||||
Buffer := FStream.ReadString(1);
|
||||
|
||||
if not (Buffer[1] in Delimiters) then
|
||||
EndToken := CheckCharcterType(Buffer[1])
|
||||
else
|
||||
begin
|
||||
if not (FString or FComment) then
|
||||
begin
|
||||
EndToken := True;
|
||||
FStream.Seek(-1, soFromCurrent);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if FString and ((Buffer[1] = CR) or (Buffer[1] = LF)) then
|
||||
begin
|
||||
FString := False;
|
||||
FWasString := False;
|
||||
EndToken := True;
|
||||
end
|
||||
else
|
||||
if FComment and ((cmt2 in FCommentType) or
|
||||
(cmt3 in FCommentType)) and ((Buffer[1] = CR) or
|
||||
(Buffer[1] = LF)) then
|
||||
begin
|
||||
EndToken := True;
|
||||
FStream.Seek(-1, soFromCurrent);
|
||||
FComment := False;
|
||||
FCommentType := [];
|
||||
end
|
||||
else
|
||||
FToken := FToken + Buffer;
|
||||
end;
|
||||
end;
|
||||
end; //while
|
||||
end;
|
||||
|
||||
destructor TQueryParserComp.Destroy;
|
||||
begin
|
||||
if Assigned(FStream) then
|
||||
FStream.Free;
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.DoStatementDelimiter;
|
||||
var
|
||||
Buffer: String;
|
||||
CurrentPosition: Integer;
|
||||
begin
|
||||
if Assigned(FOnStatementDelimiter) then
|
||||
begin
|
||||
CurrentPosition := FStream.Position;
|
||||
FStream.Seek(FGoPosition, soFromBeginning);
|
||||
Buffer := FStream.ReadString(CurrentPosition-FGoPosition-Length(FToken));
|
||||
FStream.Seek(Length(FToken), soFromCurrent);
|
||||
if FStream.Position >= FStream.Size then
|
||||
FEOF := True;
|
||||
|
||||
FGoPosition := FStream.Position;
|
||||
|
||||
if FCountFromStatement then
|
||||
FSymbolsCount := 0;
|
||||
|
||||
FOnStatementDelimiter(Self, Trim(Buffer));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.SetStringToParse(AStringToParse: String);
|
||||
begin
|
||||
|
||||
if AStringToParse = '' then
|
||||
Exit;
|
||||
|
||||
if Assigned(FStream) then
|
||||
FStream.Free;
|
||||
|
||||
TrimRight(AStringToParse);
|
||||
FStream := TStringStream.Create(AStringToParse);
|
||||
FStringToParse := AStringToParse;
|
||||
|
||||
Init;
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.SetSD(ASD: TStringList);
|
||||
begin
|
||||
FStatementDelimiters.Assign(ASD);
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.First;
|
||||
begin
|
||||
Init;
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.Init;
|
||||
var
|
||||
ETextNotSet: Exception;
|
||||
begin
|
||||
if not Assigned(FStream) then
|
||||
begin
|
||||
ETextNotSet := Exception.Create(sTextNotSet);
|
||||
raise ETextNotSet;
|
||||
end;
|
||||
|
||||
FStream.Seek(0, soFromBeginning);
|
||||
FToken := '';
|
||||
FTokenType := ttString;
|
||||
FComment := False;
|
||||
FCommentType := [];
|
||||
FEOF := False;
|
||||
FSymbolsCount := 0;
|
||||
FGoPosition := 0;
|
||||
FLastStringDelimiterFound := '';
|
||||
FWasString := False;
|
||||
FString := False;
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.SetSpecialCharacters(ASpecialCharacters: String);
|
||||
var
|
||||
i: Integer;
|
||||
k: Integer;
|
||||
IllegalSpecialChar: Exception;
|
||||
begin
|
||||
for i := 1 to Length(ASpecialCharacters) do
|
||||
begin
|
||||
for k := 0 to FStatementDelimiters.Count - 1 do
|
||||
begin
|
||||
if (Pos(ASpecialCharacters[i], FStatementDelimiters.Strings[k]) <> 0) then
|
||||
begin
|
||||
IllegalSpecialChar := Exception.Create(sIllegalSpecialChar);
|
||||
raise IllegalSpecialChar;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (ASpecialCharacters[i] in Delimiters) or
|
||||
(Pos(ASpecialCharacters[i], FStringDelimiters) <> 0) then
|
||||
begin
|
||||
IllegalSpecialChar := Exception.Create(sIllegalSpecialChar);
|
||||
raise IllegalSpecialChar;
|
||||
end;
|
||||
end;
|
||||
|
||||
FSpecialCharacters := ASpecialCharacters;
|
||||
end;
|
||||
|
||||
procedure TQueryParserComp.SetStringDelimiters(AStringDelimiters: String);
|
||||
var
|
||||
i: Integer;
|
||||
k: Integer;
|
||||
IllegalStringChar: Exception;
|
||||
begin
|
||||
for i := 1 to Length(AStringDelimiters) do
|
||||
begin
|
||||
for k := 0 to FStatementDelimiters.Count - 1 do
|
||||
begin
|
||||
if (Pos(AStringDelimiters[i], FStatementDelimiters.Strings[k]) <> 0) then
|
||||
begin
|
||||
IllegalStringChar := Exception.Create(sIllegalStringChar);
|
||||
raise IllegalStringChar;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (AStringDelimiters[i] in Delimiters) or
|
||||
(Pos(AStringDelimiters[i], FSpecialCharacters) <> 0) then
|
||||
begin
|
||||
IllegalStringChar := Exception.Create(sIllegalStringChar);
|
||||
raise IllegalStringChar;
|
||||
end;
|
||||
end;
|
||||
|
||||
FStringDelimiters := AStringDelimiters;
|
||||
end;
|
||||
|
||||
end.
|
||||
277
RealSound.cpp
Normal file
277
RealSound.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
//---------------------------------------------------------------------------
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
||||
|
||||
*/
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "math.h"
|
||||
#include "RealSound.h"
|
||||
#include "Globals.h"
|
||||
#include "Timer.h"
|
||||
#include "Logs.h"
|
||||
#include "McZapkie\mctools.hpp"
|
||||
|
||||
__fastcall TRealSound::TRealSound()
|
||||
{
|
||||
pSound=NULL;
|
||||
dSoundAtt=-1;
|
||||
AM=0.0;
|
||||
AA=0.0;
|
||||
FM=0.0;
|
||||
FA=0.0;
|
||||
vSoundPosition.x=0;
|
||||
vSoundPosition.y=0;
|
||||
vSoundPosition.z=0;
|
||||
fDistance=fPreviousDistance=0.0;
|
||||
fFrequency=22050.0; //częstotliwość samplowania pliku
|
||||
iDoppler=0; //normlanie jest załączony; !=0 - modyfikacje
|
||||
bLoopPlay=false; //dźwięk wyłączony
|
||||
}
|
||||
|
||||
__fastcall TRealSound::~TRealSound()
|
||||
{
|
||||
//if (this) if (pSound) pSound->Stop();
|
||||
}
|
||||
|
||||
void __fastcall TRealSound::Free()
|
||||
{
|
||||
}
|
||||
|
||||
void __fastcall TRealSound::Init(char *SoundName, double DistanceAttenuation, double X, double Y, double Z,bool Dynamic,bool freqmod,double rmin)
|
||||
{
|
||||
//Nazwa=SoundName; //to tak raczej nie zadziała, (SoundName) jest tymczasowe
|
||||
pSound=TSoundsManager::GetFromName(SoundName,Dynamic,&fFrequency);
|
||||
if (pSound)
|
||||
{
|
||||
if (freqmod)
|
||||
if (fFrequency!=22050.0)
|
||||
{//dla modulowanych nie może być zmiany mnożnika, bo częstotliwość w nagłówku byłą ignorowana, a mogła być inna niż 22050
|
||||
fFrequency=22050.0;
|
||||
ErrorLog("Bad sound: "+AnsiString(SoundName)+", as modulated, should have 22.05kHz in header");
|
||||
}
|
||||
AM=1.0;
|
||||
pSound->SetVolume(DSBVOLUME_MIN);
|
||||
}
|
||||
else
|
||||
{//nie ma dźwięku, to jest wysyp
|
||||
AM=0;
|
||||
ErrorLog("Missed sound: "+AnsiString(SoundName));
|
||||
}
|
||||
if (DistanceAttenuation>0.0)
|
||||
{
|
||||
dSoundAtt=DistanceAttenuation*DistanceAttenuation;
|
||||
vSoundPosition.x=X;
|
||||
vSoundPosition.y=Y;
|
||||
vSoundPosition.z=Z;
|
||||
if (rmin<0) iDoppler=1; //wyłączenie efektu Dopplera, np. dla dźwięku ptaków
|
||||
}
|
||||
else
|
||||
dSoundAtt=-1;
|
||||
};
|
||||
|
||||
|
||||
double __fastcall TRealSound::ListenerDistance(vector3 ListenerPosition)
|
||||
{
|
||||
if (dSoundAtt==-1)
|
||||
{ return 0.0; }
|
||||
else
|
||||
{ return SquareMagnitude(ListenerPosition-vSoundPosition); }
|
||||
}
|
||||
|
||||
void __fastcall TRealSound::Play(double Volume, int Looping, bool ListenerInside, vector3 NewPosition)
|
||||
{
|
||||
if (!pSound) return;
|
||||
long int vol;
|
||||
double dS;
|
||||
// double Distance;
|
||||
DWORD stat;
|
||||
if ((Global::bSoundEnabled)&&(AM!=0))
|
||||
{
|
||||
if (Volume>1.0)
|
||||
Volume=1.0;
|
||||
fPreviousDistance=fDistance;
|
||||
fDistance=0.0; //??
|
||||
if (dSoundAtt>0.0)
|
||||
{
|
||||
vSoundPosition=NewPosition;
|
||||
dS=dSoundAtt; //*dSoundAtt; //bo odleglosc podawana w kwadracie
|
||||
fDistance=ListenerDistance(Global::pCameraPosition);
|
||||
if (ListenerInside) //osłabianie dźwięków z odległością
|
||||
Volume=Volume*dS/(dS+fDistance);
|
||||
else
|
||||
Volume=Volume*dS/(dS+2*fDistance); //podwójne dla ListenerInside=false
|
||||
}
|
||||
if (iDoppler) //
|
||||
{//Ra 2014-07: efekt Dopplera nie zawsze jest wskazany
|
||||
//if (FreeFlyModeFlag) //gdy swobodne latanie - nie sprawdza się to
|
||||
fPreviousDistance=fDistance; //to efektu Dopplera nie będzie
|
||||
}
|
||||
if (Looping) //dźwięk zapętlony można wyłączyć i zostanie włączony w miarę potrzeby
|
||||
bLoopPlay=true; //dźwięk wyłączony
|
||||
//McZapkie-010302 - babranie tylko z niezbyt odleglymi dźwiękami
|
||||
if ((dSoundAtt==-1)||(fDistance<20.0*dS))
|
||||
{
|
||||
// vol=2*Volume+1;
|
||||
// if (vol<1) vol=1;
|
||||
// vol=10000*(log(vol)-1);
|
||||
// vol=10000*(vol-1);
|
||||
//int glos=1;
|
||||
//Volume=Volume*glos; //Ra: whatta hella is this
|
||||
if (Volume<0.0) Volume=0.0;
|
||||
vol=-5000.0+5000.0*Volume;
|
||||
if (vol>=0)
|
||||
vol=-1;
|
||||
if (Timer::GetSoundTimer()||!Looping) //Ra: po co to jest?
|
||||
pSound->SetVolume(vol); //Attenuation, in hundredths of a decibel (dB).
|
||||
pSound->GetStatus(&stat);
|
||||
if (!(stat&DSBSTATUS_PLAYING))
|
||||
pSound->Play(0,0,Looping);
|
||||
}
|
||||
else //wylacz dzwiek bo daleko
|
||||
{//Ra 2014-09: oddalanie się nie może być powodem do wyłączenie dźwięku
|
||||
/*
|
||||
// Ra: stara wersja, ale podobno lepsza
|
||||
pSound->GetStatus(&stat);
|
||||
if (bLoopPlay) //jeśli zapętlony, to zostanie ponownie włączony, o ile znajdzie się bliżej
|
||||
if (stat&DSBSTATUS_PLAYING)
|
||||
pSound->Stop();
|
||||
// Ra: wyłączyłem, bo podobno jest gorzej niż wcześniej
|
||||
//ZiomalCl: dźwięk po wyłączeniu sam się nie włączy, gdy wrócimy w rejon odtwarzania
|
||||
pSound->SetVolume(DSBVOLUME_MIN); //dlatego lepiej go wyciszyć na czas oddalenia się
|
||||
pSound->GetStatus(&stat);
|
||||
if (!(stat&DSBSTATUS_PLAYING))
|
||||
pSound->Play(0,0,Looping); //ZiomalCl: włączenie odtwarzania rownież i tu, gdyż jesli uruchamiamy dźwięk poza promieniem, nie uruchomi się on w ogóle
|
||||
*/
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TRealSound::Start()
|
||||
{//włączenie dźwięku
|
||||
|
||||
};
|
||||
|
||||
void __fastcall TRealSound::Stop()
|
||||
{
|
||||
DWORD stat;
|
||||
if (pSound)
|
||||
if ((Global::bSoundEnabled)&&(AM!=0))
|
||||
{
|
||||
bLoopPlay=false; //dźwięk wyłączony
|
||||
pSound->GetStatus(&stat);
|
||||
if (stat&DSBSTATUS_PLAYING)
|
||||
pSound->Stop();
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TRealSound::AdjFreq(double Freq, double dt) //McZapkie TODO: dorobic tu efekt Dopplera
|
||||
//Freq moze byc liczba dodatnia mniejsza od 1 lub wieksza od 1
|
||||
{
|
||||
float df, Vlist, Vsrc;
|
||||
if ((Global::bSoundEnabled) && (AM!=0))
|
||||
{
|
||||
if (dt>0)
|
||||
//efekt Dopplera
|
||||
{
|
||||
Vlist=(sqrt(fPreviousDistance)-sqrt(fDistance))/dt;
|
||||
df= Freq*(1+Vlist/299.8);
|
||||
}
|
||||
else
|
||||
df=Freq;
|
||||
if (Timer::GetSoundTimer())
|
||||
{
|
||||
df=fFrequency*df; //TODO - brac czestotliwosc probkowania z wav
|
||||
pSound->SetFrequency(( df<DSBFREQUENCY_MIN ? DSBFREQUENCY_MIN : (df>DSBFREQUENCY_MAX ? DSBFREQUENCY_MAX : df) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double TRealSound::GetWaveTime() //McZapkie: na razie tylko dla 22KHz/8bps
|
||||
{//używana do pomiaru czasu dla dźwięków z początkiem i końcem
|
||||
if (!pSound) return 0.0;
|
||||
double WaveTime;
|
||||
DSBCAPS caps;
|
||||
caps.dwSize=sizeof(caps);
|
||||
pSound->GetCaps(&caps);
|
||||
WaveTime=caps.dwBufferBytes;
|
||||
return WaveTime/fFrequency; //(pSound->); // wielkosc w bajtach przez czestotliwosc probkowania
|
||||
}
|
||||
|
||||
void __fastcall TRealSound::SetPan(int Pan)
|
||||
{
|
||||
pSound->SetPan(Pan);
|
||||
}
|
||||
|
||||
int TRealSound::GetStatus()
|
||||
{
|
||||
DWORD stat;
|
||||
if ((Global::bSoundEnabled) && (AM!=0))
|
||||
{
|
||||
pSound->GetStatus(&stat);
|
||||
return stat;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __fastcall TRealSound::ResetPosition()
|
||||
{
|
||||
if (pSound) //Ra: znowu jakiś badziew!
|
||||
pSound->SetCurrentPosition(0);
|
||||
}
|
||||
|
||||
void __fastcall TTextSound::Init(char *SoundName,double SoundAttenuation,double X,double Y,double Z,bool Dynamic,bool freqmod,double rmin)
|
||||
{//dodatkowo doczytuje plik tekstowy
|
||||
TRealSound::Init(SoundName,SoundAttenuation,X,Y,Z,Dynamic,freqmod,rmin);
|
||||
fTime=GetWaveTime();
|
||||
AnsiString txt=AnsiString(SoundName);
|
||||
txt.Delete(txt.Length()-3,4); //obcięcie rozszerzenia
|
||||
for (int i=txt.Length();i>0;--i)
|
||||
if (txt[i]=='/') txt[i]='\\'; //bo nie rozumi
|
||||
txt+="-"+Global::asLang+".txt"; //już może być w różnych językach
|
||||
if (!FileExists(txt))
|
||||
txt="sounds\\"+txt; //ścieżka może nie być podana
|
||||
if (FileExists(txt))
|
||||
{//wczytanie
|
||||
TFileStream *ts=new TFileStream(txt,fmOpenRead);
|
||||
asText=AnsiString::StringOfChar(' ',ts->Size);
|
||||
ts->Read(asText.c_str(),ts->Size);
|
||||
delete ts;
|
||||
}
|
||||
};
|
||||
void __fastcall TTextSound::Play(double Volume,int Looping,bool ListenerInside,vector3 NewPosition)
|
||||
{
|
||||
if (!asText.IsEmpty())
|
||||
{//jeśli ma powiązany tekst
|
||||
DWORD stat;
|
||||
pSound->GetStatus(&stat);
|
||||
if (!(stat&DSBSTATUS_PLAYING)) //jeśli nie jest aktualnie odgrywany
|
||||
{
|
||||
int i;
|
||||
AnsiString t=asText;
|
||||
do
|
||||
{//na razie zrobione jakkolwiek, docelowo przenieść teksty do tablicy nazw
|
||||
i=t.Pos("\r"); //znak nowej linii
|
||||
if (!i)
|
||||
Global::tranTexts.Add(t.c_str(),fTime,true);
|
||||
else
|
||||
{
|
||||
Global::tranTexts.Add(t.SubString(1,i-1).c_str(),fTime,true);
|
||||
t.Delete(1,i);
|
||||
while (t.IsEmpty()?false:(unsigned char)(t[1])<33)
|
||||
t.Delete(1,1);
|
||||
}
|
||||
} while (i>0);
|
||||
}
|
||||
}
|
||||
TRealSound::Play(Volume,Looping,ListenerInside,NewPosition);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
|
||||
66
RealSound.h
Normal file
66
RealSound.h
Normal file
@@ -0,0 +1,66 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef RealSoundH
|
||||
#define RealSoundH
|
||||
|
||||
#include "Sound.h"
|
||||
#include "Geometry.h"
|
||||
|
||||
class TRealSound
|
||||
{
|
||||
protected:
|
||||
PSound pSound;
|
||||
char* Nazwa; //dla celow odwszawiania
|
||||
double fDistance,fPreviousDistance; //dla liczenia Dopplera
|
||||
float fFrequency; //częstotliwość samplowania pliku
|
||||
int iDoppler; //Ra 2014-07: możliwość wyłączenia efektu Dopplera np. dla śpiewu ptaków
|
||||
public:
|
||||
vector3 vSoundPosition; //polozenie zrodla dzwieku
|
||||
double dSoundAtt; //odleglosc polowicznego zaniku dzwieku
|
||||
double AM; //mnoznik amplitudy
|
||||
double AA; //offset amplitudy
|
||||
double FM; //mnoznik czestotliwosci
|
||||
double FA; //offset czestotliwosci
|
||||
bool bLoopPlay; //czy zapętlony dźwięk jest odtwarzany
|
||||
__fastcall TRealSound();
|
||||
__fastcall ~TRealSound();
|
||||
void __fastcall Free();
|
||||
void __fastcall Init(char *SoundName,double SoundAttenuation,double X,double Y,double Z,bool Dynamic,bool freqmod=false,double rmin=0.0);
|
||||
double __fastcall ListenerDistance(vector3 ListenerPosition);
|
||||
void __fastcall Play(double Volume,int Looping,bool ListenerInside,vector3 NewPosition);
|
||||
void __fastcall Start();
|
||||
void __fastcall Stop();
|
||||
void __fastcall AdjFreq(double Freq,double dt);
|
||||
void __fastcall SetPan(int Pan);
|
||||
double GetWaveTime(); //McZapkie TODO: dorobic dla roznych bps
|
||||
int GetStatus();
|
||||
void __fastcall ResetPosition();
|
||||
//void __fastcall FreqReset(float f=22050.0) {fFrequency=f;};
|
||||
};
|
||||
|
||||
class TTextSound : public TRealSound
|
||||
{//dźwięk ze stenogramem
|
||||
AnsiString asText;
|
||||
float fTime; //czas trwania
|
||||
public:
|
||||
void __fastcall Init(char *SoundName,double SoundAttenuation,double X,double Y,double Z,bool Dynamic,bool freqmod=false,double rmin=0.0);
|
||||
void __fastcall Play(double Volume,int Looping,bool ListenerInside,vector3 NewPosition);
|
||||
};
|
||||
|
||||
class TSynthSound
|
||||
{//klasa generująca sygnał odjazdu (Rp12, Rp13), potem rozbudować o pracę manewrowego...
|
||||
int iIndex[44]; //indeksy początkowe, gdy mamy kilka wariantów dźwięków składowych
|
||||
//0..9 - cyfry 0..9
|
||||
//10..19 - liczby 10..19
|
||||
//21..29 - dziesiątki (*21==*10?)
|
||||
//31..39 - setki 100,200,...,800,900
|
||||
//40 - "tysiąc"
|
||||
//41 - "tysiące"
|
||||
//42 - indeksy początkowe dla "odjazd"
|
||||
//43 - indeksy początkowe dla "gotów"
|
||||
PSound *sSound; //posortowana tablica dźwięków, rozmiar zależny od liczby znalezionych plików
|
||||
//a może zamiast wielu plików/dźwięków zrobić jeden połączony plik i posługiwać się czasem od..do?
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
78
ResourceManager.cpp
Normal file
78
ResourceManager.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "ResourceManager.h"
|
||||
#include "Logs.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
ResourceManager::Resources ResourceManager::_resources;
|
||||
double ResourceManager::_expiry = 5.0f;
|
||||
double ResourceManager::_lastUpdate = 0.0f;
|
||||
double ResourceManager::_lastReport = 0.0f;
|
||||
|
||||
void ResourceManager::Register(Resource* resource)
|
||||
{
|
||||
_resources.push_back(resource);
|
||||
};
|
||||
|
||||
void ResourceManager::Unregister(Resource* resource)
|
||||
{
|
||||
Resources::iterator iter = std::find(_resources.begin(), _resources.end(), resource);
|
||||
|
||||
if(iter != _resources.end())
|
||||
_resources.erase(iter);
|
||||
|
||||
resource->Release();
|
||||
};
|
||||
|
||||
class ResourceExpired
|
||||
{
|
||||
public:
|
||||
ResourceExpired(double time): _time(time) { };
|
||||
bool operator()(Resource* resource)
|
||||
{
|
||||
return (resource->GetLastUsage() < _time);
|
||||
}
|
||||
|
||||
private:
|
||||
double _time;
|
||||
};
|
||||
|
||||
void ResourceManager::Sweep(double currentTime)
|
||||
{
|
||||
|
||||
if(currentTime - _lastUpdate < _expiry)
|
||||
return;
|
||||
|
||||
Resources::iterator begin = std::remove_if(_resources.begin(), _resources.end(), ResourceExpired(currentTime - _expiry));
|
||||
|
||||
#ifdef RESOURCE_REPORTING
|
||||
if(begin != _resources.end())
|
||||
WriteLog("Releasing resources");
|
||||
#endif
|
||||
|
||||
for(Resources::iterator iter = begin; iter != _resources.end(); iter++)
|
||||
(*iter)->Release();
|
||||
|
||||
#ifdef RESOURCE_REPORTING
|
||||
if(begin != _resources.end())
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "Released " << (_resources.end() - begin) << " resources";
|
||||
WriteLog(msg.str().c_str());
|
||||
};
|
||||
#endif
|
||||
|
||||
_resources.erase(begin, _resources.end());
|
||||
|
||||
#ifdef RESOURCE_REPORTING
|
||||
if(currentTime - _lastReport > 30.0f)
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "Resources count: " << _resources.size();
|
||||
WriteLog(msg.str().c_str());
|
||||
_lastReport = currentTime;
|
||||
};
|
||||
#endif
|
||||
|
||||
_lastUpdate = currentTime;
|
||||
|
||||
};
|
||||
45
ResourceManager.h
Normal file
45
ResourceManager.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef RESOURCEMANAGER_H
|
||||
#define RESOURCEMANAGER_H 1
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#pragma hdrstop
|
||||
|
||||
class Resource
|
||||
{
|
||||
|
||||
public:
|
||||
virtual void Release() = 0;
|
||||
double GetLastUsage() const { return _lastUsage; }
|
||||
|
||||
protected:
|
||||
void SetLastUsage(double lastUsage) { _lastUsage = lastUsage; }
|
||||
|
||||
private:
|
||||
double _lastUsage;
|
||||
|
||||
};
|
||||
|
||||
class ResourceManager
|
||||
{
|
||||
|
||||
public:
|
||||
static void Register(Resource* resource);
|
||||
static void Unregister(Resource* resource);
|
||||
|
||||
static void Sweep(double currentTime);
|
||||
static void SetExpiry(double expiry) { _expiry = expiry; }
|
||||
|
||||
private:
|
||||
typedef std::vector<Resource*> Resources;
|
||||
|
||||
static double _expiry;
|
||||
static double _lastUpdate;
|
||||
static double _lastReport;
|
||||
|
||||
static Resources _resources;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
918
Segment.cpp
Normal file
918
Segment.cpp
Normal file
@@ -0,0 +1,918 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#pragma hdrstop
|
||||
#include "opengl/glew.h"
|
||||
//#include "opengl/glut.h"
|
||||
|
||||
#include "Segment.h"
|
||||
#include "Usefull.h"
|
||||
#include "Globals.h"
|
||||
#include "Track.h"
|
||||
|
||||
//#define Precision 10000
|
||||
|
||||
#pragma package(smart_init)
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
//101206 Ra: trapezoidalne drogi
|
||||
//110806 Ra: odwrócone mapowanie wzdłuż - Point1 == 1.0
|
||||
|
||||
AnsiString __fastcall Where(vector3 p)
|
||||
{//zamiana współrzędnych na tekst, używana w błędach
|
||||
return AnsiString(p.x)+" "+AnsiString(p.y)+" "+AnsiString(p.z);
|
||||
};
|
||||
|
||||
__fastcall TSegment::TSegment(TTrack *owner)
|
||||
{
|
||||
Point1=CPointOut=CPointIn=Point2=vector3(0.0f,0.0f,0.0f);
|
||||
fLength=0;
|
||||
fRoll1=0;
|
||||
fRoll2=0;
|
||||
fTsBuffer=NULL;
|
||||
fStep=0;
|
||||
pOwner=owner;
|
||||
};
|
||||
|
||||
__fastcall TSegment::~TSegment()
|
||||
{
|
||||
SafeDeleteArray(fTsBuffer);
|
||||
};
|
||||
|
||||
bool __fastcall TSegment::Init(
|
||||
vector3 NewPoint1,vector3 NewPoint2,double fNewStep,
|
||||
double fNewRoll1,double fNewRoll2)
|
||||
{//wersja dla prostego - wyliczanie punktów kontrolnych
|
||||
vector3 dir;
|
||||
if (fNewRoll1==fNewRoll2)
|
||||
{//faktyczny prosty
|
||||
dir=Normalize(NewPoint2-NewPoint1); //wektor kierunku o długości 1
|
||||
return TSegment::Init(
|
||||
NewPoint1,dir,-dir,NewPoint2,
|
||||
fNewStep,fNewRoll1,fNewRoll2,
|
||||
false);
|
||||
}
|
||||
else
|
||||
{//prosty ze zmienną przechyłką musi być segmentowany jak krzywe
|
||||
dir=(NewPoint2-NewPoint1)/3.0; //punkty kontrolne prostego są w 1/3 długości
|
||||
return TSegment::Init(
|
||||
NewPoint1,NewPoint1+dir,NewPoint2-dir,NewPoint2,
|
||||
fNewStep,fNewRoll1,fNewRoll2,
|
||||
true);
|
||||
}
|
||||
};
|
||||
|
||||
bool __fastcall TSegment::Init(
|
||||
vector3 &NewPoint1,vector3 NewCPointOut,vector3 NewCPointIn,vector3 &NewPoint2,
|
||||
double fNewStep,double fNewRoll1, double fNewRoll2, bool bIsCurve)
|
||||
{//wersja uniwersalna (dla krzywej i prostego)
|
||||
Point1=NewPoint1;
|
||||
CPointOut=NewCPointOut;
|
||||
CPointIn=NewCPointIn;
|
||||
Point2=NewPoint2;
|
||||
//poprawienie przechyłki
|
||||
fRoll1=DegToRad(fNewRoll1); //Ra: przeliczone jest bardziej przydatne do obliczeń
|
||||
fRoll2=DegToRad(fNewRoll2);
|
||||
if (Global::bRollFix)
|
||||
{//Ra: poprawianie przechyłki
|
||||
// Przechyłka powinna być na środku wewnętrznej szyny, a standardowo jest w osi
|
||||
// toru. Dlatego trzeba podnieść tor oraz odpowiednio podwyższyć podsypkę.
|
||||
// Nie wykonywać tej funkcji, jeśli podwyższenie zostało uwzględnione w edytorze.
|
||||
// Problematyczne mogą byc rozjazdy na przechyłce - lepiej je modelować w edytorze.
|
||||
// Na razie wszystkie scenerie powinny być poprawiane.
|
||||
// Jedynie problem będzie z podwójną rampą przechyłkową, która w środku będzie
|
||||
// mieć moment wypoziomowania, ale musi on być również podniesiony.
|
||||
if (fRoll1!=0.0)
|
||||
{//tylko jeśli jest przechyłka
|
||||
double w1=fabs(sin(fRoll1)*0.75); //0.5*w2+0.0325; //0.75m dla 1.435
|
||||
Point1.y+=w1; //modyfikacja musi być przed policzeniem dalszych parametrów
|
||||
if (bCurve) CPointOut.y+=w1; //prosty ma wektory jednostkowe
|
||||
pOwner->MovedUp1(w1);//zwrócić trzeba informację o podwyższeniu podsypki
|
||||
}
|
||||
if (fRoll2!=0.0)
|
||||
{
|
||||
double w2=fabs(sin(fRoll2)*0.75); //0.5*w2+0.0325; //0.75m dla 1.435
|
||||
Point2.y+=w2; //modyfikacja musi być przed policzeniem dalszych parametrów
|
||||
if (bCurve) CPointIn.y+=w2; //prosty ma wektory jednostkowe
|
||||
//zwrócić trzeba informację o podwyższeniu podsypki
|
||||
}
|
||||
}
|
||||
//Ra: ten kąt jeszcze do przemyślenia jest
|
||||
fDirection=-atan2(Point2.x-Point1.x,Point2.z-Point1.z); //kąt w planie, żeby nie liczyć wielokrotnie
|
||||
bCurve=bIsCurve;
|
||||
if (bCurve)
|
||||
{//przeliczenie współczynników wielomianu, będzie mniej mnożeń i można policzyć pochodne
|
||||
vC=3.0*(CPointOut-Point1); //t^1
|
||||
vB=3.0*(CPointIn-CPointOut)-vC; //t^2
|
||||
vA=Point2-Point1-vC-vB; //t^3
|
||||
fLength=ComputeLength();
|
||||
}
|
||||
else
|
||||
fLength=(Point1-Point2).Length();
|
||||
fStep=fNewStep;
|
||||
if (fLength<=0)
|
||||
{
|
||||
ErrorLog("Bad geometry: Length <= 0 in TSegment::Init at "+Where(Point1));
|
||||
//MessageBox(0,"Length<=0","TSegment::Init",MB_OK);
|
||||
return false; //zerowe nie mogą być
|
||||
}
|
||||
fStoop=atan2((Point2.y-Point1.y),fLength); //pochylenie toru prostego, żeby nie liczyć wielokrotnie
|
||||
SafeDeleteArray(fTsBuffer);
|
||||
if ((bCurve) && (fStep>0))
|
||||
{//Ra: prosty dostanie podział, jak ma różną przechyłkę na końcach
|
||||
double s=0;
|
||||
int i=0;
|
||||
iSegCount=ceil(fLength/fStep); //potrzebne do VBO
|
||||
//fStep=fLength/(double)(iSegCount-1); //wyrównanie podziału
|
||||
fTsBuffer=new double[iSegCount+1];
|
||||
fTsBuffer[0]=0; /* TODO : fix fTsBuffer */
|
||||
while (s<fLength)
|
||||
{
|
||||
i++;
|
||||
s+=fStep;
|
||||
if (s>fLength) s=fLength;
|
||||
fTsBuffer[i]=GetTFromS(s);
|
||||
}
|
||||
}
|
||||
if (fLength>500)
|
||||
{//tor ma pojemność 40 pojazdów, więc nie może być za długi
|
||||
ErrorLog("Bad geometry: Length > 500m at "+Where(Point1));
|
||||
//MessageBox(0,"Length>500","TSegment::Init",MB_OK);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
vector3 __fastcall TSegment::GetFirstDerivative(double fTime)
|
||||
{
|
||||
|
||||
double fOmTime = 1.0 - fTime;
|
||||
double fPowTime = fTime;
|
||||
vector3 kResult = fOmTime*(CPointOut-Point1);
|
||||
|
||||
//int iDegreeM1 = 3 - 1;
|
||||
|
||||
double fCoeff = 2*fPowTime;
|
||||
kResult = (kResult+fCoeff*(CPointIn-CPointOut))*fOmTime;
|
||||
fPowTime *= fTime;
|
||||
|
||||
kResult += fPowTime*(Point2-CPointIn);
|
||||
kResult *= 3;
|
||||
|
||||
return kResult;
|
||||
}
|
||||
|
||||
double __fastcall TSegment::RombergIntegral(double fA, double fB)
|
||||
{
|
||||
double fH = fB - fA;
|
||||
|
||||
const int ms_iOrder= 5;
|
||||
|
||||
double ms_apfRom[2][ms_iOrder];
|
||||
|
||||
ms_apfRom[0][0] = 0.5*fH*((GetFirstDerivative(fA).Length())+(GetFirstDerivative(fB).Length()));
|
||||
for (int i0 = 2, iP0 = 1; i0 <= ms_iOrder; i0++, iP0 *= 2, fH *= 0.5)
|
||||
{
|
||||
// approximations via the trapezoid rule
|
||||
double fSum = 0.0;
|
||||
int i1;
|
||||
for (i1 = 1; i1 <= iP0; i1++)
|
||||
fSum += (GetFirstDerivative(fA + fH*(i1-0.5)).Length());
|
||||
|
||||
// Richardson extrapolation
|
||||
ms_apfRom[1][0] = 0.5*(ms_apfRom[0][0] + fH*fSum);
|
||||
for (int i2 = 1, iP2 = 4; i2 < i0; i2++, iP2 *= 4)
|
||||
{
|
||||
ms_apfRom[1][i2] =
|
||||
(iP2*ms_apfRom[1][i2-1] - ms_apfRom[0][i2-1])/(iP2-1);
|
||||
}
|
||||
|
||||
for (i1 = 0; i1 < i0; i1++)
|
||||
ms_apfRom[0][i1] = ms_apfRom[1][i1];
|
||||
}
|
||||
|
||||
return ms_apfRom[0][ms_iOrder-1];
|
||||
}
|
||||
|
||||
double __fastcall TSegment::GetTFromS(double s)
|
||||
{
|
||||
// initial guess for Newton's method
|
||||
int it=0;
|
||||
double fTolerance= 0.001;
|
||||
double fRatio = s/RombergIntegral(0,1);
|
||||
double fOmRatio = 1.0 - fRatio;
|
||||
double fTime = fOmRatio*0 + fRatio*1;
|
||||
|
||||
// for (int i = 0; i < iIterations; i++)
|
||||
while (true)
|
||||
{
|
||||
it++;
|
||||
if (it>10)
|
||||
{
|
||||
ErrorLog("Bad geometry: Too many iterations at "+Where(Point1));
|
||||
//MessageBox(0,"Too many iterations","GetTFromS",MB_OK);
|
||||
return fTime;
|
||||
}
|
||||
|
||||
double fDifference = RombergIntegral(0,fTime) - s;
|
||||
if ( ( fDifference>0 ? fDifference : -fDifference) < fTolerance )
|
||||
return fTime;
|
||||
|
||||
fTime -= fDifference/GetFirstDerivative(fTime).Length();
|
||||
}
|
||||
|
||||
// Newton's method failed. If this happens, increase iterations or
|
||||
// tolerance or integration accuracy.
|
||||
//return -1; //Ra: tu nigdy nie dojdzie
|
||||
|
||||
};
|
||||
|
||||
vector3 __fastcall TSegment::RaInterpolate(double t)
|
||||
{//wyliczenie XYZ na krzywej Beziera z użyciem współczynników
|
||||
return t*(t*(t*vA+vB)+vC)+Point1; //9 mnożeń, 9 dodawań
|
||||
};
|
||||
|
||||
vector3 __fastcall TSegment::RaInterpolate0(double t)
|
||||
{//wyliczenie XYZ na krzywej Beziera, na użytek liczenia długości nie jest dodawane Point1
|
||||
return t*(t*(t*vA+vB)+vC); //9 mnożeń, 6 dodawań
|
||||
};
|
||||
|
||||
double __fastcall TSegment::ComputeLength() //McZapkie-150503: dlugosc miedzy punktami krzywej
|
||||
{//obliczenie długości krzywej Beziera za pomocą interpolacji odcinkami
|
||||
//Ra: zamienić na liczenie rekurencyjne średniej z cięciwy i łamanej po kontrolnych
|
||||
//Ra: koniec rekurencji jeśli po podziale suma długości nie różni się więcej niż 0.5mm od poprzedniej
|
||||
//Ra: ewentualnie rozpoznać łuk okręgu płaskiego i liczyć ze wzoru na długość łuku
|
||||
double t,l=0;
|
||||
vector3 last=vector3(0,0,0); //długość liczona po przesunięciu odcinka do początku układu
|
||||
vector3 tmp=Point2-Point1;
|
||||
int m=20.0*tmp.Length(); //było zawsze do 10000, teraz jest liczone odcinkami po około 5cm
|
||||
for (int i=1;i<=m;i++)
|
||||
{
|
||||
t=double(i)/double(m); //wyznaczenie parametru na krzywej z przedziału (0,1>
|
||||
//tmp=Interpolate(t,p1,cp1,cp2,p2);
|
||||
tmp=RaInterpolate0(t); //obliczenie punktu dla tego parametru
|
||||
t=vector3(tmp-last).Length(); //obliczenie długości wektora
|
||||
l+=t; //zwiększenie wyliczanej długości
|
||||
last=tmp;
|
||||
}
|
||||
return (l);
|
||||
}
|
||||
|
||||
const double fDirectionOffset=0.1; //długość wektora do wyliczenia kierunku
|
||||
|
||||
vector3 __fastcall TSegment::GetDirection(double fDistance)
|
||||
{//takie toporne liczenie pochodnej dla podanego dystansu od Point1
|
||||
double t1=GetTFromS(fDistance-fDirectionOffset);
|
||||
if (t1<=0.0)
|
||||
return (CPointOut-Point1); //na zewnątrz jako prosta
|
||||
double t2=GetTFromS(fDistance+fDirectionOffset);
|
||||
if (t2>=1.0)
|
||||
return (Point1-CPointIn); //na zewnątrz jako prosta
|
||||
return (FastGetPoint(t2)-FastGetPoint(t1));
|
||||
}
|
||||
|
||||
vector3 __fastcall TSegment::FastGetDirection(double fDistance, double fOffset)
|
||||
{//takie toporne liczenie pochodnej dla parametru 0.0÷1.0
|
||||
double t1=fDistance-fOffset;
|
||||
if (t1<=0.0)
|
||||
return (CPointOut-Point1); //wektor na początku jest stały
|
||||
double t2=fDistance+fOffset;
|
||||
if (t2>=1.0)
|
||||
return (Point2-CPointIn); //wektor na końcu jest stały
|
||||
return (FastGetPoint(t2)-FastGetPoint(t1));
|
||||
}
|
||||
|
||||
vector3 __fastcall TSegment::GetPoint(double fDistance)
|
||||
{//wyliczenie współrzędnych XYZ na torze w odległości (fDistance) od Point1
|
||||
if (bCurve)
|
||||
{//można by wprowadzić uproszczony wzór dla okręgów płaskich
|
||||
double t=GetTFromS(fDistance); //aproksymacja dystansu na krzywej Beziera
|
||||
//return Interpolate(t,Point1,CPointOut,CPointIn,Point2);
|
||||
return RaInterpolate(t);
|
||||
}
|
||||
else
|
||||
{//wyliczenie dla odcinka prostego jest prostsze
|
||||
double t=fDistance/fLength; //zerowych torów nie ma
|
||||
return ((1.0-t)*Point1+(t)*Point2);
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TSegment::RaPositionGet(double fDistance,vector3 &p,vector3 &a)
|
||||
{//ustalenie pozycji osi na torze, przechyłki, pochylenia i kierunku jazdy
|
||||
if (bCurve)
|
||||
{//można by wprowadzić uproszczony wzór dla okręgów płaskich
|
||||
double t=GetTFromS(fDistance); //aproksymacja dystansu na krzywej Beziera na parametr (t)
|
||||
p=RaInterpolate(t);
|
||||
a.x=(1.0-t)*fRoll1+(t)*fRoll2; //przechyłka w danym miejscu (zmienia się liniowo)
|
||||
//pochodna jest 3*A*t^2+2*B*t+C
|
||||
a.y=atan(t*(t*3.0*vA.y+vB.y+vB.y)+vC.y); //pochylenie krzywej (w pionie)
|
||||
a.z=-atan2(t*(t*3.0*vA.x+vB.x+vB.x)+vC.x,t*(t*3.0*vA.z+vB.z+vB.z)+vC.z); //kierunek krzywej w planie
|
||||
}
|
||||
else
|
||||
{//wyliczenie dla odcinka prostego jest prostsze
|
||||
double t=fDistance/fLength; //zerowych torów nie ma
|
||||
p=((1.0-t)*Point1+(t)*Point2);
|
||||
a.x=(1.0-t)*fRoll1+(t)*fRoll2; //przechyłka w danym miejscu (zmienia się liniowo)
|
||||
a.y=fStoop; //pochylenie toru prostego
|
||||
a.z=fDirection; //kierunek toru w planie
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
vector3 __fastcall TSegment::FastGetPoint(double t)
|
||||
{
|
||||
//return (bCurve?Interpolate(t,Point1,CPointOut,CPointIn,Point2):((1.0-t)*Point1+(t)*Point2));
|
||||
return (bCurve?RaInterpolate(t):((1.0-t)*Point1+(t)*Point2));
|
||||
}
|
||||
|
||||
void __fastcall TSegment::RenderLoft(const vector6 *ShapePoints, int iNumShapePoints,
|
||||
double fTextureLength, int iSkip, int iQualityFactor,vector3 **p,bool bRender)
|
||||
{//generowanie trójkątów dla odcinka trajektorii ruchu
|
||||
//standardowo tworzy triangle_strip dla prostego albo ich zestaw dla łuku
|
||||
//po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli
|
||||
// podany jest przekrój końcowy
|
||||
//podsypka toru jest robiona za pomocą 6 punktów, szyna 12, drogi i rzeki na 3+2+3
|
||||
if (iQualityFactor<1) iQualityFactor= 1; //co który segment ma być uwzględniony
|
||||
vector3 pos1,pos2,dir,parallel1,parallel2,pt,norm;
|
||||
double s,step,fOffset,tv1,tv2,t;
|
||||
int i,j ;
|
||||
bool trapez=iNumShapePoints<0; //sygnalizacja trapezowatości
|
||||
iNumShapePoints=abs(iNumShapePoints);
|
||||
if (bCurve)
|
||||
{
|
||||
double m1,jmm1,m2,jmm2; //pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
tv1=1.0; //Ra: to by można było wyliczać dla odcinka, wyglądało by lepiej
|
||||
step=fStep*iQualityFactor;
|
||||
s=fStep*iSkip; //iSkip - ile odcinków z początku pominąć
|
||||
i=iSkip; //domyślnie 0
|
||||
if (!fTsBuffer)
|
||||
return; //prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
if (i>iSegCount)
|
||||
return; //prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
t=fTsBuffer[i]; //tabela watości t dla segmentów
|
||||
fOffset=0.1/fLength; //pierwsze 10cm
|
||||
pos1=FastGetPoint(t); //wektor początku segmentu
|
||||
dir=FastGetDirection(t,fOffset); //wektor kierunku
|
||||
//parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //wektor poprzeczny
|
||||
parallel1=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
m2=s/fLength; jmm2=1.0-m2;
|
||||
while (s<fLength)
|
||||
{
|
||||
//step=SquareMagnitude(Global::GetCameraPosition()+pos);
|
||||
i+=iQualityFactor; //kolejny punkt łamanej
|
||||
s+=step; //końcowa pozycja segmentu [m]
|
||||
m1=m2; jmm1=jmm2; //stara pozycja
|
||||
m2=s/fLength; jmm2=1.0-m2; //nowa pozycja
|
||||
if (s>fLength-0.5) //Ra: -0.5 żeby nie robiło cieniasa na końcu
|
||||
{//gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step-=(s-fLength); //jeszcze do wyliczenia mapowania potrzebny
|
||||
s=fLength;
|
||||
i=iSegCount; //20/5 ma dawać 4
|
||||
m2=1.0; jmm2=0.0;
|
||||
}
|
||||
while (tv1<0.0) tv1+=1.0; //przestawienie mapowania
|
||||
tv2=tv1-step/fTextureLength; //mapowanie na końcu segmentu
|
||||
t=fTsBuffer[i]; //szybsze od GetTFromS(s);
|
||||
pos2=FastGetPoint(t);
|
||||
dir=FastGetDirection(t,fOffset); //nowy wektor kierunku
|
||||
//parallel2=CrossProduct(dir,vector3(0,1,0)); //wektor poprzeczny
|
||||
parallel2=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
if (trapez)
|
||||
for (j=0;j<iNumShapePoints;j++)
|
||||
{
|
||||
norm=(jmm1*ShapePoints[j].n.x+m1*ShapePoints[j+iNumShapePoints].n.x)*parallel1;
|
||||
norm.y+=jmm1*ShapePoints[j].n.y+m1*ShapePoints[j+iNumShapePoints].n.y;
|
||||
pt=parallel1*(jmm1*ShapePoints[j].x+m1*ShapePoints[j+iNumShapePoints].x)+pos1;
|
||||
pt.y+=jmm1*ShapePoints[j].y+m1*ShapePoints[j+iNumShapePoints].y;
|
||||
if (bRender)
|
||||
{//skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale potrzebować punktów
|
||||
glNormal3f(norm.x,norm.y,norm.z);
|
||||
glTexCoord2f(jmm1*ShapePoints[j].z+m1*ShapePoints[j+iNumShapePoints].z,tv1);
|
||||
glVertex3f(pt.x,pt.y,pt.z); //pt nie mamy gdzie zapamiętać?
|
||||
}
|
||||
if (p) //jeśli jest wskaźnik do tablicy
|
||||
if (*p)
|
||||
if (!j) //to dla pierwszego punktu
|
||||
{*(*p)=pt; (*p)++;} //zapamiętanie brzegu jezdni
|
||||
//dla trapezu drugi koniec ma inne współrzędne
|
||||
norm=(jmm1*ShapePoints[j].n.x+m1*ShapePoints[j+iNumShapePoints].n.x)*parallel2;
|
||||
norm.y+=jmm1*ShapePoints[j].n.y+m1*ShapePoints[j+iNumShapePoints].n.y;
|
||||
pt=parallel2*(jmm2*ShapePoints[j].x+m2*ShapePoints[j+iNumShapePoints].x)+pos2;
|
||||
pt.y+=jmm2*ShapePoints[j].y+m2*ShapePoints[j+iNumShapePoints].y;
|
||||
if (bRender)
|
||||
{//skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale potrzebować punktów
|
||||
glNormal3f(norm.x,norm.y,norm.z);
|
||||
glTexCoord2f(jmm2*ShapePoints[j].z+m2*ShapePoints[j+iNumShapePoints].z,tv2);
|
||||
glVertex3f(pt.x,pt.y,pt.z);
|
||||
}
|
||||
if (p) //jeśli jest wskaźnik do tablicy
|
||||
if (*p)
|
||||
if (!j) //to dla pierwszego punktu
|
||||
if (i==iSegCount)
|
||||
{*(*p)=pt; (*p)++;} //zapamiętanie brzegu jezdni
|
||||
}
|
||||
else
|
||||
for (j=0;j<iNumShapePoints;j++)
|
||||
{//łuk z jednym profilem
|
||||
norm=ShapePoints[j].n.x*parallel1;
|
||||
norm.y+=ShapePoints[j].n.y;
|
||||
pt=parallel1*ShapePoints[j].x+pos1;
|
||||
pt.y+=ShapePoints[j].y;
|
||||
glNormal3f(norm.x,norm.y,norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z,tv1);
|
||||
glVertex3f(pt.x,pt.y,pt.z); //punkt na początku odcinka
|
||||
norm=ShapePoints[j].n.x*parallel2;
|
||||
norm.y+=ShapePoints[j].n.y;
|
||||
pt=parallel2*ShapePoints[j].x+pos2;
|
||||
pt.y+=ShapePoints[j].y;
|
||||
glNormal3f(norm.x,norm.y,norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z,tv2);
|
||||
glVertex3f(pt.x,pt.y,pt.z); //punkt na końcu odcinka
|
||||
}
|
||||
glEnd();
|
||||
pos1=pos2;
|
||||
parallel1=parallel2;
|
||||
tv1=tv2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{//gdy prosty, nie modyfikujemy wektora kierunkowego i poprzecznego
|
||||
pos1=FastGetPoint((fStep*iSkip)/fLength);
|
||||
pos2=FastGetPoint_1();
|
||||
dir=GetDirection();
|
||||
//parallel1=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel1=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
if (trapez)
|
||||
for (j=0;j<iNumShapePoints;j++)
|
||||
{
|
||||
norm=ShapePoints[j].n.x*parallel1;
|
||||
norm.y+=ShapePoints[j].n.y;
|
||||
pt=parallel1*ShapePoints[j].x+pos1;
|
||||
pt.y+=ShapePoints[j].y;
|
||||
glNormal3f(norm.x,norm.y,norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z,0);
|
||||
glVertex3f(pt.x,pt.y,pt.z);
|
||||
//dla trapezu drugi koniec ma inne współrzędne względne
|
||||
norm=ShapePoints[j+iNumShapePoints].n.x*parallel1;
|
||||
norm.y+=ShapePoints[j+iNumShapePoints].n.y;
|
||||
pt=parallel1*ShapePoints[j+iNumShapePoints].x+pos2; //odsunięcie
|
||||
pt.y+=ShapePoints[j+iNumShapePoints].y; //wysokość
|
||||
glNormal3f(norm.x,norm.y,norm.z);
|
||||
glTexCoord2f(ShapePoints[j+iNumShapePoints].z,fLength/fTextureLength);
|
||||
glVertex3f(pt.x,pt.y,pt.z);
|
||||
}
|
||||
else
|
||||
for (j=0;j<iNumShapePoints;j++)
|
||||
{
|
||||
norm=ShapePoints[j].n.x*parallel1;
|
||||
norm.y+=ShapePoints[j].n.y;
|
||||
pt=parallel1*ShapePoints[j].x+pos1;
|
||||
pt.y+=ShapePoints[j].y;
|
||||
glNormal3f(norm.x,norm.y,norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z,0);
|
||||
glVertex3f(pt.x,pt.y,pt.z);
|
||||
pt=parallel1*ShapePoints[j].x+pos2;
|
||||
pt.y+=ShapePoints[j].y;
|
||||
glNormal3f(norm.x,norm.y,norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z,fLength/fTextureLength);
|
||||
glVertex3f(pt.x,pt.y,pt.z);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TSegment::RenderSwitchRail(const vector6 *ShapePoints1, const vector6 *ShapePoints2,
|
||||
int iNumShapePoints,double fTextureLength, int iSkip, double fOffsetX)
|
||||
{//tworzenie siatki trójkątów dla iglicy
|
||||
vector3 pos1,pos2,dir,parallel1,parallel2,pt;
|
||||
double a1,a2,s,step,offset,tv1,tv2,t,t2,t2step,oldt2,sp,oldsp;
|
||||
int i,j ;
|
||||
if (bCurve)
|
||||
{//dla toru odchylonego
|
||||
//t2= 0;
|
||||
t2step= 1/double(iSkip); //przesunięcie tekstury?
|
||||
oldt2= 1;
|
||||
tv1=1.0;
|
||||
step= fStep; //długść segmentu
|
||||
s= 0;
|
||||
i= 0;
|
||||
t= fTsBuffer[i]; //wartość t krzywej Beziera dla początku
|
||||
a1= 0;
|
||||
// step= fStep/fLength;
|
||||
offset= 0.1/fLength; //około 10cm w sensie parametru t
|
||||
pos1= FastGetPoint( t ); //współrzędne dla parmatru t
|
||||
// dir= GetDirection1();
|
||||
dir=FastGetDirection(t,offset); //wektor wzdłużny
|
||||
//parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //poprzeczny?
|
||||
parallel1=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
|
||||
|
||||
while (s<fLength && i<iSkip)
|
||||
{
|
||||
// step= SquareMagnitude(Global::GetCameraPosition()+pos);
|
||||
//t2= oldt2+t2step;
|
||||
i++;
|
||||
s+= step;
|
||||
|
||||
if (s>fLength)
|
||||
{
|
||||
step-= (s-fLength);
|
||||
s= fLength;
|
||||
}
|
||||
|
||||
while (tv1<0.0) tv1+=1.0;
|
||||
tv2=tv1-step/fTextureLength;
|
||||
|
||||
t= fTsBuffer[i];
|
||||
pos2= FastGetPoint( t );
|
||||
dir=FastGetDirection(t,offset);
|
||||
//parallel2=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel2=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
|
||||
a2= double(i)/(iSkip);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
for (j=0; j<iNumShapePoints; j++)
|
||||
{//po dwa punkty trapezu
|
||||
pt= parallel1*(ShapePoints1[j].x*a1+(ShapePoints2[j].x-fOffsetX)*(1.0-a1))+pos1;
|
||||
pt.y+= ShapePoints1[j].y*a1+ShapePoints2[j].y*(1.0-a1);
|
||||
glNormal3f(0.0f,1.0f,0.0f);
|
||||
glTexCoord2f(ShapePoints1[j].z*a1+ShapePoints2[j].z*(1.0-a1),tv1);
|
||||
glVertex3f(pt.x,pt.y,pt.z);
|
||||
|
||||
pt= parallel2*(ShapePoints1[j].x*a2+(ShapePoints2[j].x-fOffsetX)*(1.0-a2))+pos2;
|
||||
pt.y+= ShapePoints1[j].y*a2+ShapePoints2[j].y*(1.0-a2);
|
||||
glNormal3f(0.0f,1.0f,0.0f);
|
||||
glTexCoord2f(ShapePoints1[j].z*a2+ShapePoints2[j].z*(1.0-a2),tv2);
|
||||
glVertex3f(pt.x,pt.y,pt.z);
|
||||
}
|
||||
glEnd();
|
||||
pos1= pos2;
|
||||
parallel1= parallel2;
|
||||
tv1=tv2;
|
||||
a1= a2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{//dla toru prostego
|
||||
tv1=1.0;
|
||||
s= 0;
|
||||
i= 0;
|
||||
// pos1= FastGetPoint( (5*iSkip)/fLength );
|
||||
pos1= FastGetPoint_0();
|
||||
dir=GetDirection();
|
||||
//parallel1=CrossProduct(dir,vector3(0,1,0));
|
||||
parallel1=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
|
||||
step= 5;
|
||||
a1= 0;
|
||||
|
||||
while (i<iSkip)
|
||||
{
|
||||
// step= SquareMagnitude(Global::GetCameraPosition()+pos);
|
||||
i++;
|
||||
s+= step;
|
||||
|
||||
if (s>fLength)
|
||||
{
|
||||
step-= (s-fLength);
|
||||
s= fLength;
|
||||
}
|
||||
|
||||
while (tv1<0.0) tv1+=1.0;
|
||||
|
||||
tv2=tv1-step/fTextureLength;
|
||||
|
||||
t= s/fLength;
|
||||
pos2= FastGetPoint( t );
|
||||
|
||||
a2= double(i)/(iSkip);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
for (j=0; j<iNumShapePoints; j++)
|
||||
{
|
||||
pt= parallel1*(ShapePoints1[j].x*a1+(ShapePoints2[j].x-fOffsetX)*(1.0-a1))+pos1;
|
||||
pt.y+= ShapePoints1[j].y*a1+ShapePoints2[j].y*(1.0-a1);
|
||||
glNormal3f(0.0f,1.0f,0.0f);
|
||||
glTexCoord2f((ShapePoints1[j].z),tv1);
|
||||
glVertex3f(pt.x,pt.y,pt.z);
|
||||
|
||||
pt= parallel1*(ShapePoints1[j].x*a2+(ShapePoints2[j].x-fOffsetX)*(1.0-a2))+pos2;
|
||||
pt.y+= ShapePoints1[j].y*a2+ShapePoints2[j].y*(1.0-a2);
|
||||
glNormal3f(0.0f,1.0f,0.0f);
|
||||
glTexCoord2f(ShapePoints2[j].z,tv2);
|
||||
glVertex3f(pt.x,pt.y,pt.z);
|
||||
}
|
||||
glEnd();
|
||||
pos1= pos2;
|
||||
tv1=tv2;
|
||||
a1= a2;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TSegment::Render()
|
||||
{
|
||||
vector3 pt;
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
int i;
|
||||
if (bCurve)
|
||||
{
|
||||
glColor3f(0,0,1.0f);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(Point1.x,Point1.y,Point1.z);
|
||||
glVertex3f(CPointOut.x,CPointOut.y,CPointOut.z);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(Point2.x,Point2.y,Point2.z);
|
||||
glVertex3f(CPointIn.x,CPointIn.y,CPointIn.z);
|
||||
glEnd();
|
||||
|
||||
glColor3f(1.0f,0,0);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int i=0; i<=8; i++)
|
||||
{
|
||||
pt= FastGetPoint(double(i)/8.0f);
|
||||
glVertex3f(pt.x,pt.y,pt.z);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor3f(0,0,1.0f);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(Point1.x,Point1.y,Point1.z);
|
||||
glVertex3f(Point1.x+CPointOut.x,Point1.y+CPointOut.y,Point1.z+CPointOut.z);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(Point2.x,Point2.y,Point2.z);
|
||||
glVertex3f(Point2.x+CPointIn.x,Point2.y+CPointIn.y,Point2.z+CPointIn.z);
|
||||
glEnd();
|
||||
|
||||
glColor3f(0.5f,0,0);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(Point1.x+CPointOut.x,Point1.y+CPointOut.y,Point1.z+CPointOut.z);
|
||||
glVertex3f(Point2.x+CPointIn.x,Point2.y+CPointIn.y,Point2.z+CPointIn.z);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void __fastcall TSegment::RaRenderLoft(
|
||||
CVertNormTex* &Vert,const vector6 *ShapePoints,
|
||||
int iNumShapePoints,double fTextureLength,int iSkip,int iEnd,double fOffsetX)
|
||||
{//generowanie trójkątów dla odcinka trajektorii ruchu
|
||||
//standardowo tworzy triangle_strip dla prostego albo ich zestaw dla łuku
|
||||
//po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli
|
||||
// podany jest przekrój końcowy
|
||||
//podsypka toru jest robiona za pomocą 6 punktów, szyna 12, drogi i rzeki na 3+2+3
|
||||
//na użytek VBO strip dla łuków jest tworzony wzdłuż
|
||||
//dla skróconego odcinka (iEnd<iSegCount), ShapePoints dotyczy
|
||||
//końców skróconych, a nie całości (to pod kątem iglic jest)
|
||||
vector3 pos1,pos2,dir,parallel1,parallel2,pt,norm;
|
||||
double s,step,fOffset,tv1,tv2,t,fEnd;
|
||||
int i,j ;
|
||||
bool trapez=iNumShapePoints<0; //sygnalizacja trapezowatości
|
||||
iNumShapePoints=abs(iNumShapePoints);
|
||||
if (bCurve)
|
||||
{
|
||||
double m1,jmm1,m2,jmm2; //pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
step=fStep;
|
||||
tv1=1.0; //Ra: to by można było wyliczać dla odcinka, wyglądało by lepiej
|
||||
s=fStep*iSkip; //iSkip - ile odcinków z początku pominąć
|
||||
i=iSkip; //domyślnie 0
|
||||
t=fTsBuffer[i]; //tabela wattości t dla segmentów
|
||||
fOffset=0.1/fLength; //pierwsze 10cm
|
||||
pos1=FastGetPoint(t); //wektor początku segmentu
|
||||
dir=FastGetDirection(t,fOffset); //wektor kierunku
|
||||
//parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //wektor prostopadły
|
||||
parallel1=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
if (iEnd==0) iEnd=iSegCount;
|
||||
fEnd=fLength*double(iEnd)/double(iSegCount);
|
||||
m2=s/fEnd; jmm2=1.0-m2;
|
||||
while (i<iEnd)
|
||||
{
|
||||
++i; //kolejny punkt łamanej
|
||||
s+=step; //końcowa pozycja segmentu [m]
|
||||
m1=m2; jmm1=jmm2; //stara pozycja
|
||||
m2=s/fEnd; jmm2=1.0-m2; //nowa pozycja
|
||||
if (i==iEnd)
|
||||
{//gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step-=(s-fEnd); //jeszcze do wyliczenia mapowania potrzebny
|
||||
s=fEnd;
|
||||
//i=iEnd; //20/5 ma dawać 4
|
||||
m2=1.0; jmm2=0.0;
|
||||
}
|
||||
while (tv1<0.0) tv1+=1.0;
|
||||
tv2=tv1-step/fTextureLength; //mapowanie na końcu segmentu
|
||||
t=fTsBuffer[i]; //szybsze od GetTFromS(s);
|
||||
pos2=FastGetPoint(t);
|
||||
dir=FastGetDirection(t,fOffset); //nowy wektor kierunku
|
||||
//parallel2=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel2=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j=0; j<iNumShapePoints; j++)
|
||||
{//współrzędne początku
|
||||
norm=(jmm1*ShapePoints[j].n.x+m1*ShapePoints[j+iNumShapePoints].n.x)*parallel1;
|
||||
norm.y+=jmm1*ShapePoints[j].n.y+m1*ShapePoints[j+iNumShapePoints].n.y;
|
||||
pt=parallel1*(jmm1*(ShapePoints[j].x-fOffsetX)+m1*ShapePoints[j+iNumShapePoints].x)+pos1;
|
||||
pt.y+=jmm1*ShapePoints[j].y+m1*ShapePoints[j+iNumShapePoints].y;
|
||||
Vert->nx=norm.x; //niekoniecznie tak
|
||||
Vert->ny=norm.y;
|
||||
Vert->nz=norm.z;
|
||||
Vert->u=jmm1*ShapePoints[j].z+m1*ShapePoints[j+iNumShapePoints].z;
|
||||
Vert->v=tv1;
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na początku odcinka
|
||||
Vert++;
|
||||
//dla trapezu drugi koniec ma inne współrzędne względne
|
||||
norm=(jmm1*ShapePoints[j].n.x+m1*ShapePoints[j+iNumShapePoints].n.x)*parallel2;
|
||||
norm.y+=jmm1*ShapePoints[j].n.y+m1*ShapePoints[j+iNumShapePoints].n.y;
|
||||
pt=parallel2*(jmm2*(ShapePoints[j].x-fOffsetX)+m2*ShapePoints[j+iNumShapePoints].x)+pos2;
|
||||
pt.y+=jmm2*ShapePoints[j].y+m2*ShapePoints[j+iNumShapePoints].y;
|
||||
Vert->nx=norm.x; //niekoniecznie tak
|
||||
Vert->ny=norm.y;
|
||||
Vert->nz=norm.z;
|
||||
Vert->u=jmm2*ShapePoints[j].z+m2*ShapePoints[j+iNumShapePoints].z;
|
||||
Vert->v=tv2;
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
else
|
||||
for (j=0;j<iNumShapePoints;j++)
|
||||
{//współrzędne początku
|
||||
norm=ShapePoints[j].n.x*parallel1;
|
||||
norm.y+=ShapePoints[j].n.y;
|
||||
pt=parallel1*(ShapePoints[j].x-fOffsetX)+pos1;
|
||||
pt.y+=ShapePoints[j].y;
|
||||
Vert->nx=norm.x; //niekoniecznie tak
|
||||
Vert->ny=norm.y;
|
||||
Vert->nz=norm.z;
|
||||
Vert->u=ShapePoints[j].z;
|
||||
Vert->v=tv1;
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na początku odcinka
|
||||
Vert++;
|
||||
norm=ShapePoints[j].n.x*parallel2;
|
||||
norm.y+=ShapePoints[j].n.y;
|
||||
pt=parallel2*ShapePoints[j].x+pos2;
|
||||
pt.y+=ShapePoints[j].y;
|
||||
Vert->nx=norm.x; //niekoniecznie tak
|
||||
Vert->ny=norm.y;
|
||||
Vert->nz=norm.z;
|
||||
Vert->u=ShapePoints[j].z;
|
||||
Vert->v=tv2;
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
pos1=pos2;
|
||||
parallel1=parallel2;
|
||||
tv1=tv2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{//gdy prosty
|
||||
pos1=FastGetPoint((fStep*iSkip)/fLength);
|
||||
pos2=FastGetPoint_1();
|
||||
dir=GetDirection();
|
||||
//parallel1=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel1=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j=0;j<iNumShapePoints;j++)
|
||||
{
|
||||
norm=ShapePoints[j].n.x*parallel1;
|
||||
norm.y+=ShapePoints[j].n.y;
|
||||
pt=parallel1*(ShapePoints[j].x-fOffsetX)+pos1;
|
||||
pt.y+=ShapePoints[j].y;
|
||||
Vert->nx=norm.x; //niekoniecznie tak
|
||||
Vert->ny=norm.y;
|
||||
Vert->nz=norm.z;
|
||||
Vert->u=ShapePoints[j].z;
|
||||
Vert->v=0;
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na początku odcinka
|
||||
Vert++;
|
||||
//dla trapezu drugi koniec ma inne współrzędne
|
||||
norm=ShapePoints[j+iNumShapePoints].n.x*parallel1;
|
||||
norm.y+=ShapePoints[j+iNumShapePoints].n.y;
|
||||
pt=parallel1*(ShapePoints[j+iNumShapePoints].x-fOffsetX)+pos2; //odsunięcie
|
||||
pt.y+=ShapePoints[j+iNumShapePoints].y; //wysokość
|
||||
Vert->nx=norm.x; //niekoniecznie tak
|
||||
Vert->ny=norm.y;
|
||||
Vert->nz=norm.z;
|
||||
Vert->u=ShapePoints[j+iNumShapePoints].z;
|
||||
Vert->v=fLength/fTextureLength;
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
else
|
||||
for (j=0;j<iNumShapePoints;j++)
|
||||
{
|
||||
norm=ShapePoints[j].n.x*parallel1;
|
||||
norm.y+=ShapePoints[j].n.y;
|
||||
pt=parallel1*(ShapePoints[j].x-fOffsetX)+pos1;
|
||||
pt.y+=ShapePoints[j].y;
|
||||
Vert->nx=norm.x; //niekoniecznie tak
|
||||
Vert->ny=norm.y;
|
||||
Vert->nz=norm.z;
|
||||
Vert->u=ShapePoints[j].z;
|
||||
Vert->v=0;
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na początku odcinka
|
||||
Vert++;
|
||||
pt=parallel1*(ShapePoints[j].x-fOffsetX)+pos2;
|
||||
pt.y+=ShapePoints[j].y;
|
||||
Vert->nx=norm.x; //niekoniecznie tak
|
||||
Vert->ny=norm.y;
|
||||
Vert->nz=norm.z;
|
||||
Vert->u=ShapePoints[j].z;
|
||||
Vert->v=fLength/fTextureLength;
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TSegment::RaAnimate(
|
||||
CVertNormTex* &Vert,const vector6 *ShapePoints,
|
||||
int iNumShapePoints,double fTextureLength,int iSkip,int iEnd,double fOffsetX)
|
||||
{//jak wyżej, tylko z pominięciem mapowania i braku trapezowania
|
||||
vector3 pos1,pos2,dir,parallel1,parallel2,pt;
|
||||
double s,step,fOffset,t,fEnd;
|
||||
int i,j ;
|
||||
bool trapez=iNumShapePoints<0; //sygnalizacja trapezowatości
|
||||
iNumShapePoints=abs(iNumShapePoints);
|
||||
if (bCurve)
|
||||
{
|
||||
double m1,jmm1,m2,jmm2; //pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
step=fStep;
|
||||
s=fStep*iSkip; //iSkip - ile odcinków z początku pominąć
|
||||
i=iSkip; //domyślnie 0
|
||||
t=fTsBuffer[i]; //tabela wattości t dla segmentów
|
||||
fOffset=0.1/fLength; //pierwsze 10cm
|
||||
pos1=FastGetPoint(t); //wektor początku segmentu
|
||||
dir=FastGetDirection(t,fOffset); //wektor kierunku
|
||||
//parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //wektor prostopadły
|
||||
parallel1=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
if (iEnd==0) iEnd=iSegCount;
|
||||
fEnd=fLength*double(iEnd)/double(iSegCount);
|
||||
m2=s/fEnd; jmm2=1.0-m2;
|
||||
while (i<iEnd)
|
||||
{
|
||||
++i; //kolejny punkt łamanej
|
||||
s+=step; //końcowa pozycja segmentu [m]
|
||||
m1=m2; jmm1=jmm2; //stara pozycja
|
||||
m2=s/fEnd; jmm2=1.0-m2; //nowa pozycja
|
||||
if (i==iEnd)
|
||||
{//gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step-=(s-fEnd); //jeszcze do wyliczenia mapowania potrzebny
|
||||
s=fEnd;
|
||||
//i=iEnd; //20/5 ma dawać 4
|
||||
m2=1.0; jmm2=0.0;
|
||||
}
|
||||
t=fTsBuffer[i]; //szybsze od GetTFromS(s);
|
||||
pos2=FastGetPoint(t);
|
||||
dir=FastGetDirection(t,fOffset); //nowy wektor kierunku
|
||||
//parallel2=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel2=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j=0; j<iNumShapePoints; j++)
|
||||
{//współrzędne początku
|
||||
pt=parallel1*(jmm1*(ShapePoints[j].x-fOffsetX)+m1*ShapePoints[j+iNumShapePoints].x)+pos1;
|
||||
pt.y+=jmm1*ShapePoints[j].y+m1*ShapePoints[j+iNumShapePoints].y;
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na początku odcinka
|
||||
Vert++;
|
||||
//dla trapezu drugi koniec ma inne współrzędne
|
||||
pt=parallel2*(jmm2*(ShapePoints[j].x-fOffsetX)+m2*ShapePoints[j+iNumShapePoints].x)+pos2;
|
||||
pt.y+=jmm2*ShapePoints[j].y+m2*ShapePoints[j+iNumShapePoints].y;
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
pos1=pos2;
|
||||
parallel1=parallel2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{//gdy prosty
|
||||
pos1=FastGetPoint((fStep*iSkip)/fLength);
|
||||
pos2=FastGetPoint_1();
|
||||
dir=GetDirection();
|
||||
//parallel1=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel1=Normalize(vector3(-dir.z,0.0,dir.x)); //wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j=0;j<iNumShapePoints;j++)
|
||||
{
|
||||
pt=parallel1*(ShapePoints[j].x-fOffsetX)+pos1;
|
||||
pt.y+=ShapePoints[j].y;
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na początku odcinka
|
||||
Vert++;
|
||||
pt=parallel1*(ShapePoints[j+iNumShapePoints].x-fOffsetX)+pos2; //odsunięcie
|
||||
pt.y+=ShapePoints[j+iNumShapePoints].y; //wysokość
|
||||
Vert->x=pt.x; Vert->y=pt.y; Vert->z=pt.z; //punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
}
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
104
Segment.h
Normal file
104
Segment.h
Normal file
@@ -0,0 +1,104 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef SegmentH
|
||||
#define SegmentH
|
||||
|
||||
#include "VBO.h"
|
||||
#include "dumb3d.h"
|
||||
#include "Classes.h"
|
||||
|
||||
using namespace Math3D;
|
||||
|
||||
//110405 Ra: klasa punktów przekroju z normalnymi
|
||||
|
||||
class vector6 : public vector3
|
||||
{//punkt przekroju wraz z wektorem normalnym
|
||||
public:
|
||||
vector3 n;
|
||||
__fastcall vector6()
|
||||
{x=y=z=n.x=n.z=0.0; n.y=1.0;};
|
||||
__fastcall vector6(double a,double b,double c,double d,double e,double f)
|
||||
//{x=a; y=b; z=c; n.x=d; n.y=e; n.z=f;};
|
||||
{x=a; y=b; z=c; n.x=0.0; n.y=1.0; n.z=0.0;}; //Ra: bo na razie s¹ z tym problemy
|
||||
__fastcall vector6(double a,double b,double c)
|
||||
{x=a; y=b; z=c; n.x=0.0; n.y=1.0; n.z=0.0;};
|
||||
};
|
||||
|
||||
class TSegment
|
||||
{//aproksymacja toru (zwrotnica ma dwa takie, jeden z nich jest aktywny)
|
||||
private:
|
||||
vector3 Point1,CPointOut,CPointIn,Point2;
|
||||
double fRoll1,fRoll2; //przechy³ka na koñcach
|
||||
double fLength; //d³ugoœæ policzona
|
||||
double *fTsBuffer; //wartoœci parametru krzywej dla równych odcinków
|
||||
double fStep;
|
||||
int iSegCount; //iloœæ odcinków do rysowania krzywej
|
||||
double fDirection; //Ra: k¹t prostego w planie; dla ³uku k¹t od Point1
|
||||
double fStoop; //Ra: k¹t wzniesienia; dla ³uku od Point1
|
||||
vector3 vA,vB,vC; //wspó³czynniki wielomianów trzeciego stopnia vD==Point1
|
||||
//TSegment *pPrev; //odcinek od strony punktu 1 - w segmencie, ¿eby nie skakaæ na zwrotnicach
|
||||
//TSegment *pNext; //odcinek od strony punktu 2
|
||||
TTrack *pOwner; //wskaŸnik na w³aœciciela
|
||||
double fAngle[2]; //k¹ty zakoñczenia drogi na przejazdach
|
||||
vector3 __fastcall GetFirstDerivative(double fTime);
|
||||
double __fastcall RombergIntegral(double fA, double fB);
|
||||
double __fastcall GetTFromS(double s);
|
||||
vector3 __fastcall RaInterpolate(double t);
|
||||
vector3 __fastcall RaInterpolate0(double t);
|
||||
//TSegment *segNeightbour[2]; //s¹siednie odcinki - musi byæ przeniesione z Track
|
||||
//int iNeightbour[2]; //do którego koñca doczepiony
|
||||
public:
|
||||
bool bCurve;
|
||||
//int iShape; //Ra: flagi kszta³tu dadz¹ wiêcej mo¿liwoœci optymalizacji (0-Bezier,1-prosty,2/3-³uk w lewo/prawo,6/7-przejœciowa w lewo/prawo)
|
||||
__fastcall TSegment(TTrack *owner);
|
||||
__fastcall ~TSegment();
|
||||
bool __fastcall Init(vector3 NewPoint1,vector3 NewPoint2,double fNewStep,
|
||||
double fNewRoll1=0,double fNewRoll2=0);
|
||||
bool __fastcall Init(vector3 &NewPoint1,vector3 NewCPointOut,
|
||||
vector3 NewCPointIn,vector3 &NewPoint2,double fNewStep,
|
||||
double fNewRoll1=0,double fNewRoll2=0,bool bIsCurve=true);
|
||||
inline double __fastcall ComputeLength(); //McZapkie-150503
|
||||
inline vector3 __fastcall GetDirection1() {return bCurve?CPointOut-Point1:CPointOut;};
|
||||
inline vector3 __fastcall GetDirection2() {return bCurve?CPointIn-Point2:CPointIn;};
|
||||
vector3 __fastcall GetDirection(double fDistance);
|
||||
vector3 __fastcall GetDirection() {return CPointOut;};
|
||||
vector3 __fastcall FastGetDirection(double fDistance,double fOffset);
|
||||
vector3 __fastcall GetPoint(double fDistance);
|
||||
void __fastcall RaPositionGet(double fDistance,vector3 &p,vector3 &a);
|
||||
vector3 __fastcall FastGetPoint(double t);
|
||||
inline vector3 __fastcall FastGetPoint_0() {return Point1;};
|
||||
inline vector3 __fastcall FastGetPoint_1() {return Point2;};
|
||||
inline double __fastcall GetRoll(double s)
|
||||
{
|
||||
s/=fLength;
|
||||
return ((1.0-s)*fRoll1+s*fRoll2);
|
||||
}
|
||||
void __fastcall GetRolls(double &r1,double &r2)
|
||||
{//pobranie przechy³ek (do generowania trójk¹tów)
|
||||
r1=fRoll1; r2=fRoll2;
|
||||
}
|
||||
void __fastcall RenderLoft(const vector6 *ShapePoints,int iNumShapePoints,
|
||||
double fTextureLength,int iSkip=0,int iQualityFactor=1,vector3 **p=NULL,bool bRender=true);
|
||||
void __fastcall RenderSwitchRail(const vector6 *ShapePoints1,const vector6 *ShapePoints2,
|
||||
int iNumShapePoints,double fTextureLength,int iSkip=0,double fOffsetX=0.0f);
|
||||
void __fastcall Render();
|
||||
inline double __fastcall GetLength() {return fLength;};
|
||||
void __fastcall MoveMe(vector3 pPosition)
|
||||
{Point1+=pPosition;
|
||||
Point2+=pPosition;
|
||||
if (bCurve)
|
||||
{CPointIn+=pPosition;
|
||||
CPointOut+=pPosition;
|
||||
}
|
||||
}
|
||||
int __fastcall RaSegCount() {return fTsBuffer?iSegCount:1;};
|
||||
void __fastcall RaRenderLoft(CVertNormTex* &Vert,const vector6 *ShapePoints,int iNumShapePoints,
|
||||
double fTextureLength,int iSkip=0,int iEnd=0,double fOffsetX=0.0);
|
||||
void __fastcall RaAnimate(CVertNormTex* &Vert,const vector6 *ShapePoints,int iNumShapePoints,
|
||||
double fTextureLength,int iSkip=0,int iEnd=0,double fOffsetX=0.0);
|
||||
void __fastcall AngleSet(int i,double a) {fAngle[i]=a;};
|
||||
void __fastcall Rollment(double w1,double w2); //poprawianie przechy³ki
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
377
Sound.cpp
Normal file
377
Sound.cpp
Normal file
@@ -0,0 +1,377 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#define STRICT
|
||||
#include "Sound.h"
|
||||
#include "Usefull.h"
|
||||
#include "Globals.h"
|
||||
//#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
|
||||
char Directory[]= "sounds\\";
|
||||
|
||||
LPDIRECTSOUND TSoundsManager::pDS;
|
||||
LPDIRECTSOUNDNOTIFY TSoundsManager::pDSNotify;
|
||||
|
||||
int TSoundsManager::Count= 0;
|
||||
TSoundContainer *TSoundsManager::First=NULL;
|
||||
|
||||
|
||||
__fastcall TSoundContainer::TSoundContainer( LPDIRECTSOUND pDS, char *Directory, char *strFileName, int NConcurrent)
|
||||
{//wczytanie pliku dŸwiêkowego
|
||||
int hr= 111;
|
||||
DSBuffer=NULL; //na pocz¹tek, gdyby uruchomiæ dŸwiêków siê nie uda³o
|
||||
|
||||
Concurrent= NConcurrent;
|
||||
|
||||
Oldest= 0;
|
||||
// strcpy(Name, strFileName);
|
||||
|
||||
strcpy(Name,Directory);
|
||||
strcat(Name,strFileName);
|
||||
|
||||
CWaveSoundRead* pWaveSoundRead;
|
||||
|
||||
|
||||
// Create a new wave file class
|
||||
pWaveSoundRead = new CWaveSoundRead();
|
||||
|
||||
// Load the wave file
|
||||
if (FAILED(pWaveSoundRead->Open(Name)))
|
||||
if(FAILED(pWaveSoundRead->Open(strFileName)))
|
||||
{
|
||||
// SetFileUI( hDlg, TEXT("Bad wave file.") );
|
||||
return;
|
||||
ErrorLog("Missed sound: "+AnsiString(strFileName));
|
||||
}
|
||||
|
||||
strcpy(Name,AnsiString(strFileName).LowerCase().c_str());
|
||||
|
||||
// Set up the direct sound buffer, and only request the flags needed
|
||||
// since each requires some overhead and limits if the buffer can
|
||||
// be hardware accelerated
|
||||
DSBUFFERDESC dsbd;
|
||||
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
|
||||
if (!Global::bInactivePause) //jeœli prze³¹czony w t³o ma nadal dzia³aæ
|
||||
dsbd.dwFlags|=DSBCAPS_GLOBALFOCUS; //to dŸwiêki maj¹ byæ równie¿ s³yszalne
|
||||
dsbd.dwBufferBytes = pWaveSoundRead->m_ckIn.cksize;
|
||||
dsbd.lpwfxFormat = pWaveSoundRead->m_pwfx;
|
||||
fSamplingRate=pWaveSoundRead->m_pwfx->nSamplesPerSec;
|
||||
iBitsPerSample=pWaveSoundRead->m_pwfx->wBitsPerSample;
|
||||
|
||||
// pDSBuffer= (LPDIRECTSOUNDBUFFER*) malloc(Concurrent*sizeof(LPDIRECTSOUNDBUFFER));
|
||||
// for (int i=0; i<Concurrent; i++)
|
||||
// pDSBuffer[i]= NULL;
|
||||
|
||||
// Create the static DirectSound buffer
|
||||
if( FAILED( hr = pDS->CreateSoundBuffer( &dsbd, &(DSBuffer), NULL ) ) )
|
||||
//if (FAILED(pDS->CreateSoundBuffer(&dsbd,&(DSBuffer),NULL)))
|
||||
return;
|
||||
|
||||
// Remember how big the buffer is
|
||||
DWORD dwBufferBytes;
|
||||
|
||||
dwBufferBytes = dsbd.dwBufferBytes;
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
|
||||
BYTE* pbWavData; // Pointer to actual wav data
|
||||
UINT cbWavSize; // Size of data
|
||||
VOID* pbData = NULL;
|
||||
VOID* pbData2 = NULL;
|
||||
DWORD dwLength;
|
||||
DWORD dwLength2;
|
||||
|
||||
// The size of wave data is in pWaveFileSound->m_ckIn
|
||||
INT nWaveFileSize = pWaveSoundRead->m_ckIn.cksize;
|
||||
|
||||
// Allocate that buffer.
|
||||
pbWavData = new BYTE[ nWaveFileSize ];
|
||||
if( NULL == pbWavData )
|
||||
return ;//E_OUTOFMEMORY;
|
||||
|
||||
//if (FAILED(hr=pWaveSoundRead->Read( nWaveFileSize,pbWavData,&cbWavSize)))
|
||||
if( FAILED( hr = pWaveSoundRead->Read( nWaveFileSize,
|
||||
pbWavData,
|
||||
&cbWavSize ) ) )
|
||||
return ;
|
||||
|
||||
// Reset the file to the beginning
|
||||
pWaveSoundRead->Reset();
|
||||
|
||||
// Lock the buffer down
|
||||
//if (FAILED(hr=DSBuffer->Lock(0,dwBufferBytes,&pbData,&dwLength,&pbData2,&dwLength2,0)))
|
||||
if( FAILED( hr = DSBuffer->Lock( 0, dwBufferBytes, &pbData, &dwLength,
|
||||
&pbData2, &dwLength2, 0L ) ) )
|
||||
return ;
|
||||
|
||||
// Copy the memory to it.
|
||||
memcpy( pbData, pbWavData, dwBufferBytes );
|
||||
|
||||
// Unlock the buffer, we don't need it anymore.
|
||||
DSBuffer->Unlock( pbData, dwBufferBytes, NULL, 0 );
|
||||
pbData = NULL;
|
||||
|
||||
// We dont need the wav file data buffer anymore, so delete it
|
||||
delete[] pbWavData;
|
||||
|
||||
delete pWaveSoundRead;
|
||||
|
||||
DSBuffers.push(DSBuffer);
|
||||
|
||||
/*
|
||||
for (int i=1; i<Concurrent; i++)
|
||||
{
|
||||
if( FAILED( hr= pDS->DuplicateSoundBuffer(pDSBuffer[0],&(pDSBuffer[i]))))
|
||||
{
|
||||
Concurrent= i;
|
||||
break;
|
||||
};
|
||||
|
||||
|
||||
};*/
|
||||
|
||||
};
|
||||
__fastcall TSoundContainer::~TSoundContainer()
|
||||
{
|
||||
// for (int i=Concurrent-1; i>=0; i--)
|
||||
// SAFE_RELEASE( pDSBuffer[i] );
|
||||
// free(pDSBuffer);
|
||||
while (!DSBuffers.empty())
|
||||
{
|
||||
SAFE_RELEASE(DSBuffers.top());
|
||||
DSBuffers.pop();
|
||||
}
|
||||
SafeDelete( Next );
|
||||
};
|
||||
|
||||
LPDIRECTSOUNDBUFFER __fastcall TSoundContainer::GetUnique(LPDIRECTSOUND pDS)
|
||||
{
|
||||
if (!DSBuffer) return NULL;
|
||||
//jeœli siê dobrze zainicjowa³o
|
||||
LPDIRECTSOUNDBUFFER buff;
|
||||
pDS->DuplicateSoundBuffer(DSBuffer,&buff);
|
||||
if (buff) DSBuffers.push(buff);
|
||||
return DSBuffers.top();
|
||||
};
|
||||
|
||||
|
||||
|
||||
__fastcall TSoundsManager::~TSoundsManager()
|
||||
{
|
||||
|
||||
Free();
|
||||
};
|
||||
|
||||
void __fastcall TSoundsManager::Free()
|
||||
{
|
||||
SafeDelete( First );
|
||||
SAFE_RELEASE( pDS );
|
||||
};
|
||||
|
||||
|
||||
TSoundContainer* __fastcall TSoundsManager::LoadFromFile(char *Dir,char *Name,int Concurrent)
|
||||
{
|
||||
TSoundContainer *Tmp=First;
|
||||
First=new TSoundContainer(pDS,Dir,Name,Concurrent);
|
||||
First->Next=Tmp;
|
||||
Count++;
|
||||
return First; //albo NULL, jak nie wyjdzie (na razie zawsze wychodzi)
|
||||
};
|
||||
|
||||
void __fastcall TSoundsManager::LoadSounds(char *Directory)
|
||||
{//wczytanie wszystkich plików z katalogu - ma³o elastyczne
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE handle=FindFirstFile("sounds\\*.wav",&FindFileData);
|
||||
if (handle!=INVALID_HANDLE_VALUE)
|
||||
do
|
||||
{
|
||||
LoadFromFile(Directory,FindFileData.cFileName,1);
|
||||
} while (FindNextFile(handle,&FindFileData));
|
||||
FindClose(handle);
|
||||
};
|
||||
|
||||
LPDIRECTSOUNDBUFFER __fastcall TSoundsManager::GetFromName(char *Name,bool Dynamic,float *fSamplingRate)
|
||||
{//wyszukanie dŸwiêku w pamiêci albo wczytanie z pliku
|
||||
AnsiString file;
|
||||
if (Dynamic)
|
||||
{//próba wczytania z katalogu pojazdu
|
||||
file=Global::asCurrentDynamicPath+AnsiString(Name);
|
||||
if (FileExists(file))
|
||||
Name=file.c_str(); //nowa nazwa
|
||||
else
|
||||
Dynamic=false; //wczytanie z "sounds/"
|
||||
}
|
||||
TSoundContainer *Next=First;
|
||||
DWORD dwStatus;
|
||||
for (int i=0;i<Count;i++)
|
||||
{
|
||||
if (strcmp(Name,Next->Name)==0)
|
||||
{
|
||||
if (fSamplingRate)
|
||||
*fSamplingRate=Next->fSamplingRate; //czêstotliwoœæ
|
||||
return (Next->GetUnique(pDS));
|
||||
// DSBuffers.
|
||||
/*
|
||||
Next->pDSBuffer[Next->Oldest]->Stop();
|
||||
Next->pDSBuffer[Next->Oldest]->SetCurrentPosition(0);
|
||||
if (Next->Oldest<Next->Concurrent-1)
|
||||
{
|
||||
Next->Oldest++;
|
||||
return (Next->pDSBuffer[Next->Oldest-1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Next->Oldest= 0;
|
||||
return (Next->pDSBuffer[Next->Concurrent-1]);
|
||||
};
|
||||
|
||||
/* for (int j=0; j<Next->Concurrent; j++)
|
||||
{
|
||||
|
||||
Next->pDSBuffer[j]->GetStatus(&dwStatus);
|
||||
if ((dwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING)
|
||||
return (Next->pDSBuffer[j]);
|
||||
} */
|
||||
}
|
||||
else
|
||||
Next=Next->Next;
|
||||
};
|
||||
if (Dynamic) //wczytanie z katalogu pojazdu
|
||||
Next=LoadFromFile("",Name,1);
|
||||
else
|
||||
Next=LoadFromFile(Directory,Name,1);
|
||||
if (Next)
|
||||
{//
|
||||
if (fSamplingRate)
|
||||
*fSamplingRate=Next->fSamplingRate; //czêstotliwoœæ
|
||||
return Next->GetUnique(pDS);
|
||||
}
|
||||
ErrorLog("Missed sound: "+AnsiString(Name));
|
||||
return (NULL);
|
||||
};
|
||||
|
||||
void __fastcall TSoundsManager::RestoreAll()
|
||||
{
|
||||
TSoundContainer *Next= First;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
DWORD dwStatus;
|
||||
|
||||
for (int i=0; i<Count; i++)
|
||||
{
|
||||
|
||||
|
||||
if( FAILED( hr = Next->DSBuffer->GetStatus( &dwStatus ) ) );
|
||||
// return hr;
|
||||
|
||||
if( dwStatus & DSBSTATUS_BUFFERLOST )
|
||||
{
|
||||
// Since the app could have just been activated, then
|
||||
// DirectSound may not be giving us control yet, so
|
||||
// the restoring the buffer may fail.
|
||||
// If it does, sleep until DirectSound gives us control.
|
||||
do
|
||||
{
|
||||
hr = Next->DSBuffer->Restore();
|
||||
if( hr == DSERR_BUFFERLOST )
|
||||
Sleep( 10 );
|
||||
}
|
||||
while ((hr=Next->DSBuffer->Restore())!=NULL);
|
||||
|
||||
// char *Name= Next->Name;
|
||||
// int cc= Next->Concurrent;
|
||||
// delete Next;
|
||||
// Next= new TSoundContainer(pDS, Directory, Name, cc);
|
||||
// if( FAILED( hr = FillBuffer() ) );
|
||||
// return hr;
|
||||
};
|
||||
Next= Next->Next;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
//void __fastcall TSoundsManager::Init(char *Name, int Concurrent)
|
||||
//__fastcall TSoundsManager::TSoundsManager(HWND hWnd)
|
||||
//void __fastcall TSoundsManager::Init(HWND hWnd, char *NDirectory)
|
||||
|
||||
void __fastcall TSoundsManager::Init(HWND hWnd)
|
||||
{
|
||||
|
||||
First= NULL;
|
||||
Count= 0;
|
||||
pDS= NULL;
|
||||
pDSNotify= NULL;
|
||||
|
||||
HRESULT hr; //=222;
|
||||
LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;
|
||||
|
||||
// strcpy(Directory, NDirectory);
|
||||
|
||||
// Create IDirectSound using the primary sound device
|
||||
hr = DirectSoundCreate( NULL, &pDS, NULL );
|
||||
if( hr!=DS_OK )
|
||||
{
|
||||
|
||||
if (hr==DSERR_ALLOCATED)
|
||||
return;
|
||||
if (hr==DSERR_INVALIDPARAM)
|
||||
return;
|
||||
if (hr==DSERR_NOAGGREGATION)
|
||||
return;
|
||||
if (hr==DSERR_NODRIVER)
|
||||
return;
|
||||
if (hr==DSERR_OUTOFMEMORY)
|
||||
return;
|
||||
|
||||
// hr=0;
|
||||
};
|
||||
// return ;
|
||||
|
||||
// Set coop level to DSSCL_PRIORITY
|
||||
// if( FAILED( hr = pDS->SetCooperativeLevel( hWnd, DSSCL_PRIORITY ) ) );
|
||||
// return ;
|
||||
pDS->SetCooperativeLevel( hWnd, DSSCL_PRIORITY );
|
||||
|
||||
// Get the primary buffer
|
||||
DSBUFFERDESC dsbd;
|
||||
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
|
||||
dsbd.dwSize = sizeof(DSBUFFERDESC);
|
||||
dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
if (!Global::bInactivePause) //jeœli prze³¹czony w t³o ma nadal dzia³aæ
|
||||
dsbd.dwFlags|=DSBCAPS_GLOBALFOCUS; //to dŸwiêki maj¹ byæ równie¿ s³yszalne
|
||||
dsbd.dwBufferBytes = 0;
|
||||
dsbd.lpwfxFormat = NULL;
|
||||
|
||||
if( FAILED( hr = pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) )
|
||||
return ;
|
||||
|
||||
// Set primary buffer format to 22kHz and 16-bit output.
|
||||
WAVEFORMATEX wfx;
|
||||
ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = 2;
|
||||
wfx.nSamplesPerSec = 44100;
|
||||
wfx.wBitsPerSample = 16;
|
||||
wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
|
||||
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
|
||||
|
||||
if( FAILED( hr = pDSBPrimary->SetFormat(&wfx) ) )
|
||||
return ;
|
||||
|
||||
SAFE_RELEASE( pDSBPrimary );
|
||||
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#pragma package(smart_init)
|
||||
61
Sound.h
Normal file
61
Sound.h
Normal file
@@ -0,0 +1,61 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef SoundH
|
||||
#define SoundH
|
||||
|
||||
#include <stack>
|
||||
#undef EOF
|
||||
#include <objbase.h>
|
||||
//#include <initguid.h>
|
||||
//#include <commdlg.h>
|
||||
#include <mmreg.h>
|
||||
#include <dsound.h>
|
||||
//#include "resource.h"
|
||||
#include "WavRead.h"
|
||||
|
||||
typedef LPDIRECTSOUNDBUFFER PSound;
|
||||
|
||||
//inline __fastcall Playing(PSound Sound)
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
class TSoundContainer
|
||||
{
|
||||
public:
|
||||
int Concurrent;
|
||||
int Oldest;
|
||||
char Name[80];
|
||||
LPDIRECTSOUNDBUFFER DSBuffer;
|
||||
float fSamplingRate; //czêstotliwoœæ odczytana z pliku
|
||||
int iBitsPerSample; //ile bitów na próbkê
|
||||
TSoundContainer *Next;
|
||||
std::stack< LPDIRECTSOUNDBUFFER > DSBuffers;
|
||||
LPDIRECTSOUNDBUFFER __fastcall GetUnique(LPDIRECTSOUND pDS);
|
||||
__fastcall TSoundContainer(LPDIRECTSOUND pDS, char *Directory, char *strFileName, int NConcurrent);
|
||||
__fastcall ~TSoundContainer();
|
||||
};
|
||||
|
||||
|
||||
class TSoundsManager
|
||||
{
|
||||
private:
|
||||
static LPDIRECTSOUND pDS;
|
||||
static LPDIRECTSOUNDNOTIFY pDSNotify;
|
||||
// static char Directory[80];
|
||||
static int Count;
|
||||
static TSoundContainer *First;
|
||||
static TSoundContainer* __fastcall LoadFromFile(char *Dir,char *Name,int Concurrent);
|
||||
public:
|
||||
// __fastcall TSoundsManager(HWND hWnd);
|
||||
// static void __fastcall Init(HWND hWnd, char *NDirectory);
|
||||
static void __fastcall Init(HWND hWnd);
|
||||
__fastcall ~TSoundsManager();
|
||||
static void __fastcall Free();
|
||||
static void __fastcall Init(char *Name, int Concurrent);
|
||||
static void __fastcall LoadSounds(char *Directory);
|
||||
static LPDIRECTSOUNDBUFFER __fastcall GetFromName(char *Name,bool Dynamic,float *fSamplingRate=NULL);
|
||||
static void __fastcall RestoreAll();
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
518
Spline.cpp
Normal file
518
Spline.cpp
Normal file
@@ -0,0 +1,518 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Geometry.h"
|
||||
#include "Spline.h"
|
||||
#include "usefull.h"
|
||||
#include "maptextfile.hpp"
|
||||
|
||||
//#define asSplinesPatch AnsiString("Scenery\\")
|
||||
|
||||
|
||||
bool __fastcall Connect(TKnot *k1, TKnot *k2)
|
||||
{
|
||||
if (k1 && k2)
|
||||
{
|
||||
k1->Next= k2;
|
||||
k2->Prev= k1;
|
||||
k1->InitLength();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#define Precision 10000
|
||||
float __fastcall CurveLength(vector3 p1, vector3 cp1, vector3 cp2, vector3 p2)
|
||||
{
|
||||
float t,l=0;
|
||||
vector3 tmp,last= p1;
|
||||
for (int i=1; i<=Precision; i++)
|
||||
{
|
||||
t= float(i)/float(Precision);
|
||||
tmp= Interpolate(t,p1,cp1,cp2,p2);
|
||||
t= vector3(tmp-last).Length();
|
||||
l+= t;
|
||||
last= tmp;
|
||||
}
|
||||
return (l);
|
||||
|
||||
}
|
||||
|
||||
__fastcall TKnot::TKnot()
|
||||
{
|
||||
Next=Prev= NULL;
|
||||
Length= -1;
|
||||
IsCurve= false;
|
||||
fLengthIn=fLengthOut= 0;
|
||||
fRoll= 0;
|
||||
bSwitchDirectionForward= false;
|
||||
bSwitchDirectionBackward= false;
|
||||
}
|
||||
|
||||
__fastcall TKnot::TKnot(int n)
|
||||
{
|
||||
bSwitchDirectionForward= false;
|
||||
bSwitchDirectionBackward= false;
|
||||
Next=Prev= NULL;
|
||||
Length= -1;
|
||||
IsCurve= false;
|
||||
fLengthIn=fLengthOut= 0;
|
||||
if (n>0)
|
||||
{
|
||||
Next= new TKnot(n-1);
|
||||
Next->Prev= this;
|
||||
}
|
||||
}
|
||||
|
||||
__fastcall TKnot::~TKnot()
|
||||
{
|
||||
}
|
||||
|
||||
vector3 __fastcall TKnot::GetDirection(float t)
|
||||
{
|
||||
if (IsCurve)
|
||||
{
|
||||
vector3 v1= CPointOut-Point;
|
||||
vector3 v2= Next->Point-Next->CPointIn; //BUGBUG
|
||||
return v1*(1-t)+v2*(t);
|
||||
}
|
||||
else
|
||||
return (Next->Point-Point);//Spline->Knots[KnotIndex].Point-Spline->Knots[KnotIndex].Point);
|
||||
}
|
||||
|
||||
float __fastcall TKnot::GetTFromS(float s)
|
||||
{
|
||||
// initial guess for Newton's method
|
||||
int it=0;
|
||||
float fTolerance= 0.001;
|
||||
float fRatio = s/RombergIntegral(0,1);
|
||||
float fOmRatio = 1.0 - fRatio;
|
||||
float fTime = fOmRatio*0 + fRatio*1;
|
||||
|
||||
// for (int i = 0; i < iIterations; i++)
|
||||
while (true)
|
||||
{
|
||||
it++;
|
||||
if (it>10)
|
||||
MessageBox(0,"Too many iterations","TSpline->GetTFromS",MB_OK);
|
||||
|
||||
float fDifference = RombergIntegral(0,fTime) - s;
|
||||
if ( ( fDifference>0 ? fDifference : -fDifference) < fTolerance )
|
||||
return fTime;
|
||||
|
||||
fTime -= fDifference/GetFirstDerivative(fTime).Length();
|
||||
}
|
||||
|
||||
// Newton's method failed. If this happens, increase iterations or
|
||||
// tolerance or integration accuracy.
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
bool __fastcall TKnot::Init(TKnot *NNext, TKnot *NPrev)
|
||||
{
|
||||
if (NNext!=NULL)
|
||||
{
|
||||
Next= NNext;
|
||||
Next->Prev= this;
|
||||
}
|
||||
if (NPrev!=NULL)
|
||||
{
|
||||
Prev= NPrev;
|
||||
Prev->Next= this;
|
||||
}
|
||||
}
|
||||
|
||||
bool __fastcall TKnot::InitCPoints()
|
||||
{
|
||||
if (Prev!=NULL)
|
||||
if (Prev->IsCurve)
|
||||
if (Next!=NULL)
|
||||
{
|
||||
if (!IsCurve)
|
||||
{
|
||||
CPointIn= Point-fLengthIn*Normalize(Next->Point-Point);
|
||||
}
|
||||
else
|
||||
CPointIn= Point-fLengthIn*(Normalize(Normalize(Next->Point-Point)+Normalize(Point-Prev->Point)));
|
||||
}
|
||||
else
|
||||
CPointIn= Point-fLengthIn*Normalize(Point-Prev->Point);
|
||||
else
|
||||
CPointIn= Prev->Point;
|
||||
|
||||
if (Next!=NULL)
|
||||
if (IsCurve)
|
||||
if (Prev!=NULL)
|
||||
{
|
||||
if (!Prev->IsCurve)
|
||||
{
|
||||
CPointOut= Point-fLengthOut*Normalize(Prev->Point-Point);
|
||||
}
|
||||
else
|
||||
CPointOut= Point-fLengthOut*(Normalize(Normalize(Prev->Point-Point)+Normalize(Point-Next->Point)));
|
||||
}
|
||||
else;
|
||||
// CPointOut= -fLengthOut*Normalize(Next->Point-Point);
|
||||
else
|
||||
CPointOut= Next->Point;
|
||||
else
|
||||
CPointOut= Point-fLengthOut*Normalize(Prev->Point-Point);
|
||||
}
|
||||
|
||||
bool __fastcall TKnot::InitLength()
|
||||
{
|
||||
|
||||
if (IsCurve)
|
||||
if (Next)
|
||||
Length= RombergIntegral(0,1);
|
||||
else;
|
||||
else
|
||||
if (Next)
|
||||
Length= (Point-Next->Point).Length();
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
vector3 TKnot::GetFirstDerivative(float fTime)
|
||||
{
|
||||
|
||||
float fOmTime = 1.0 - fTime;
|
||||
float fPowTime = fTime;
|
||||
vector3 kResult = fOmTime*(CPointOut-Point);
|
||||
|
||||
int iDegreeM1 = 3 - 1;
|
||||
|
||||
float fCoeff = 2*fPowTime;
|
||||
kResult = (kResult+fCoeff*(Next->CPointIn-CPointOut))*fOmTime;
|
||||
fPowTime *= fTime;
|
||||
|
||||
kResult += fPowTime*(Next->Point-Next->CPointIn);
|
||||
kResult *= 3;
|
||||
|
||||
return kResult;
|
||||
}
|
||||
|
||||
float TKnot::RombergIntegral(float fA, float fB)
|
||||
{
|
||||
float fH = fB - fA;
|
||||
|
||||
const int ms_iOrder= 5;
|
||||
|
||||
float ms_apfRom[2][ms_iOrder];
|
||||
|
||||
ms_apfRom[0][0] = 0.5*fH*((GetFirstDerivative(fA).Length())+(GetFirstDerivative(fB).Length()));
|
||||
for (int i0 = 2, iP0 = 1; i0 <= ms_iOrder; i0++, iP0 *= 2, fH *= 0.5)
|
||||
{
|
||||
// approximations via the trapezoid rule
|
||||
float fSum = 0.0;
|
||||
int i1;
|
||||
for (i1 = 1; i1 <= iP0; i1++)
|
||||
fSum += (GetFirstDerivative(fA + fH*(i1-0.5)).Length());
|
||||
|
||||
// Richardson extrapolation
|
||||
ms_apfRom[1][0] = 0.5*(ms_apfRom[0][0] + fH*fSum);
|
||||
for (int i2 = 1, iP2 = 4; i2 < i0; i2++, iP2 *= 4)
|
||||
{
|
||||
ms_apfRom[1][i2] =
|
||||
(iP2*ms_apfRom[1][i2-1] - ms_apfRom[0][i2-1])/(iP2-1);
|
||||
}
|
||||
|
||||
for (i1 = 0; i1 < i0; i1++)
|
||||
ms_apfRom[0][i1] = ms_apfRom[1][i1];
|
||||
}
|
||||
|
||||
return ms_apfRom[0][ms_iOrder-1];
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
||||
__fastcall TSpline::TSpline()
|
||||
{
|
||||
// Closed= true;
|
||||
// asName= "foo";
|
||||
// Knots= NULL;
|
||||
RootKnot= NULL;
|
||||
iNumKnots= 0;
|
||||
KnotsAllocated= false;
|
||||
// Next=Prev= this;
|
||||
}
|
||||
|
||||
__fastcall TSpline::TSpline(AnsiString asNName)
|
||||
{
|
||||
// Closed= true;
|
||||
// asName= asNName;
|
||||
// Knots= NULL;
|
||||
RootKnot= NULL;
|
||||
iNumKnots= 0;
|
||||
KnotsAllocated= false;
|
||||
// Next=Prev= this;
|
||||
}
|
||||
|
||||
__fastcall TSpline::~TSpline()
|
||||
{
|
||||
// if (KnotsAllocated)
|
||||
// SafeDeleteArray(Knots);
|
||||
|
||||
// SafeDelete(RootKnot);
|
||||
|
||||
TKnot *ck,*tk;
|
||||
ck= RootKnot;
|
||||
|
||||
for (int i=0; i<iNumKnots; i++)
|
||||
{
|
||||
tk= ck;
|
||||
ck= ck->Next;
|
||||
SafeDelete(tk);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool __fastcall TSpline::Create( int n, AnsiString asNName )
|
||||
{
|
||||
/*
|
||||
// asName= asNName;
|
||||
iNumKnots= n;
|
||||
Knots= new TKnot[iNumKnots];
|
||||
KnotsAllocated= true;
|
||||
Knots[0].Prev= NULL;
|
||||
Knots[iNumKnots-1].Next= NULL;
|
||||
for (int i=1; i<iNumKnots; i++)
|
||||
Knots[i].Init(NULL,Knots+i-1);
|
||||
*/
|
||||
}
|
||||
|
||||
bool __fastcall TSpline::AssignKnots( TKnot *FirstKnot, int n )
|
||||
{
|
||||
// iNumKnots= n;
|
||||
// Knots= FirstKnot;
|
||||
// KnotsAllocated= false;
|
||||
|
||||
}
|
||||
|
||||
int __fastcall TSpline::LoadFromFile( AnsiString FileName, TKnot *FirstKnot )
|
||||
{
|
||||
return false;
|
||||
/*
|
||||
int i;
|
||||
|
||||
iNumKnots= -1;
|
||||
|
||||
|
||||
AnsiString buf;
|
||||
buf.SetLength(255);
|
||||
|
||||
TMapTextfile *tf= new TMapTextfile();
|
||||
tf->Open(asSceneryPatch+FileName,mmRead);
|
||||
|
||||
tf->ReadLn(buf);
|
||||
|
||||
if (buf==AnsiString("\"SPLINE\""))
|
||||
{
|
||||
tf->ReadLn(buf);
|
||||
if (FirstKnot==NULL)
|
||||
Create(buf.ToInt());
|
||||
else
|
||||
AssignKnots(FirstKnot,buf.ToInt());
|
||||
TKnot *CurrentKnot= Knots;
|
||||
// iNumKnots= buf.ToInt();
|
||||
// Knots= new TKnot[iNumKnots];// malloc(*sizeof(TKnot));
|
||||
|
||||
DecimalSeparator= '.';
|
||||
for (i=0; i<iNumKnots; i++)
|
||||
{
|
||||
|
||||
tf->ReadLn(buf); CurrentKnot->Point.x= buf.ToDouble();
|
||||
tf->ReadLn(buf); CurrentKnot->Point.z= buf.ToDouble();
|
||||
tf->ReadLn(buf); CurrentKnot->Point.y= buf.ToDouble();
|
||||
tf->ReadLn(buf); CurrentKnot->CPointIn.x= buf.ToDouble();
|
||||
tf->ReadLn(buf); CurrentKnot->CPointIn.z= buf.ToDouble();
|
||||
tf->ReadLn(buf); CurrentKnot->CPointIn.y= buf.ToDouble();
|
||||
tf->ReadLn(buf); CurrentKnot->CPointOut.x= buf.ToDouble();
|
||||
tf->ReadLn(buf); CurrentKnot->CPointOut.z= buf.ToDouble();
|
||||
tf->ReadLn(buf); CurrentKnot->CPointOut.y= buf.ToDouble();
|
||||
|
||||
tf->ReadLn(buf);
|
||||
// buf.Trim();
|
||||
Knots[i].IsCurve= (buf!="#line ");
|
||||
CurrentKnot= CurrentKnot->Next;
|
||||
|
||||
|
||||
}
|
||||
DecimalSeparator= ',';
|
||||
|
||||
CurrentKnot= Knots;
|
||||
|
||||
for (i=0; i<iNumKnots-1; i++)
|
||||
{
|
||||
// Knots[i].InitLength();
|
||||
if (CurrentKnot->IsCurve)
|
||||
{
|
||||
|
||||
CurrentKnot->Length= CurveLength(CurrentKnot->Point,CurrentKnot->CPointOut,CurrentKnot->Next->CPointIn,CurrentKnot->Next->Point);
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentKnot->CPointOut= 2*CurrentKnot->Point-CurrentKnot->CPointIn;
|
||||
CurrentKnot->Next->CPointIn= CurrentKnot->Point;
|
||||
CurrentKnot->Length= (CurrentKnot->Point-CurrentKnot->Next->Point).Length();
|
||||
}
|
||||
CurrentKnot= CurrentKnot->Next;
|
||||
}
|
||||
CurrentKnot->Length= -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
tf->Close();
|
||||
|
||||
delete tf;
|
||||
|
||||
return (iNumKnots);
|
||||
*/
|
||||
}
|
||||
|
||||
int __fastcall TSpline::Load( TQueryParserComp *Parser, AnsiString asEndString )
|
||||
{
|
||||
TKnot *LastKnot= NULL;;
|
||||
if (RootKnot!=NULL)
|
||||
for (LastKnot= RootKnot; LastKnot->Next!=NULL; LastKnot= LastKnot->Next);
|
||||
|
||||
TKnot *tmp;
|
||||
|
||||
tmp= new TKnot(0);
|
||||
tmp->Prev= LastKnot;
|
||||
if (LastKnot!=NULL)
|
||||
LastKnot->Next= tmp;
|
||||
else
|
||||
RootKnot= tmp;
|
||||
|
||||
LastKnot= tmp;
|
||||
|
||||
float tf,r,pr;
|
||||
vector3 dir;
|
||||
|
||||
// asName= Parser->GetNextSymbol();
|
||||
|
||||
iNumKnots= 0;
|
||||
|
||||
do
|
||||
{
|
||||
LastKnot->fLengthIn= Parser->GetNextSymbol().ToDouble();
|
||||
tf= Parser->GetNextSymbol().ToDouble();
|
||||
LastKnot->Point.x= tf;
|
||||
tf= Parser->GetNextSymbol().ToDouble();
|
||||
LastKnot->Point.y= tf;
|
||||
tf= Parser->GetNextSymbol().ToDouble();
|
||||
LastKnot->Point.z= tf;
|
||||
tf= Parser->GetNextSymbol().ToDouble();
|
||||
LastKnot->fRoll= tf/180*M_PI;
|
||||
|
||||
LastKnot->fLengthOut= Parser->GetNextSymbol().ToDouble();
|
||||
|
||||
LastKnot->IsCurve= (LastKnot->fLengthOut!=0);
|
||||
|
||||
LastKnot->Next= new TKnot(0);
|
||||
LastKnot->Next->Prev= LastKnot;
|
||||
LastKnot= LastKnot->Next;
|
||||
|
||||
iNumKnots++;
|
||||
|
||||
|
||||
} while (Parser->GetNextSymbol().LowerCase()!=asEndString && !Parser->EOF);
|
||||
|
||||
LastKnot->Prev->Next= NULL;
|
||||
delete LastKnot;
|
||||
if (RootKnot!=NULL)
|
||||
for (LastKnot= RootKnot; LastKnot!=NULL; LastKnot= LastKnot->Next)
|
||||
LastKnot->InitCPoints();
|
||||
if (RootKnot!=NULL)
|
||||
for (LastKnot= RootKnot; LastKnot!=NULL; LastKnot= LastKnot->Next)
|
||||
LastKnot->InitLength();
|
||||
}
|
||||
|
||||
float __fastcall TSpline::GetLength()
|
||||
{
|
||||
TKnot *tmp= RootKnot;
|
||||
float l= 0;
|
||||
for (int i=0; i<iNumKnots; i++)
|
||||
{
|
||||
l+= tmp->Length;
|
||||
tmp= tmp->Next;
|
||||
}
|
||||
|
||||
return l;
|
||||
|
||||
}
|
||||
|
||||
vector3 __fastcall TSpline::GetCenter()
|
||||
{
|
||||
TKnot *ck,*tk;
|
||||
ck= RootKnot;
|
||||
vector3 pt= vector3(0,0,0);
|
||||
|
||||
for (int i=0; i<iNumKnots; i++)
|
||||
{
|
||||
pt+= ck->Point;
|
||||
ck= ck->Next;
|
||||
}
|
||||
if (iNumKnots>0)
|
||||
pt/= iNumKnots;
|
||||
|
||||
}
|
||||
|
||||
TKnot* __fastcall TSpline::GetLastKnot()
|
||||
{
|
||||
TKnot *ck;
|
||||
ck= RootKnot;
|
||||
|
||||
for (int i=0; i<iNumKnots-1; i++)
|
||||
{
|
||||
ck= ck->Next;
|
||||
}
|
||||
return ck;
|
||||
}
|
||||
|
||||
|
||||
bool __fastcall TSpline::Render()
|
||||
{
|
||||
TKnot *LastKnot= NULL;;
|
||||
|
||||
// if (RootKnot==NULL)
|
||||
// RootKnot= Knots;
|
||||
|
||||
if (RootKnot!=NULL)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
int i=0;
|
||||
for (LastKnot= RootKnot; LastKnot!=NULL && i<iNumKnots; LastKnot= LastKnot->Next, i++)
|
||||
// for (LastKnot= RootKnot; LastKnot!=NULL; LastKnot= LastKnot->Next)
|
||||
glVertex3f(LastKnot->Point.x,LastKnot->Point.y,LastKnot->Point.z);
|
||||
glEnd();
|
||||
/*
|
||||
if (RootKnot->Prev!=NULL)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(RootKnot->Point.x,RootKnot->Point.y,RootKnot->Point.z);
|
||||
glVertex3f(RootKnot->Prev->Point.x,RootKnot->Prev->Point.y,RootKnot->Prev->Point.z);
|
||||
glEnd();
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
89
Spline.h
Normal file
89
Spline.h
Normal file
@@ -0,0 +1,89 @@
|
||||
//---------------------------------------------------------------------------
|
||||
#ifndef SplineH
|
||||
#define SplineH
|
||||
|
||||
#include "dumb3d.h"
|
||||
#include "QueryParserComp.hpp"
|
||||
using namespace Math3D;
|
||||
|
||||
#define B1(t) (t*t*t)
|
||||
#define B2(t) (3*t*t*(1-t))
|
||||
#define B3(t) (3*t*(1-t)*(1-t))
|
||||
#define B4(t) ((1-t)*(1-t)*(1-t))
|
||||
#define Interpolate(t,p1,cp1,cp2,p2) (B4(t)*p1+B3(t)*cp1+B2(t)*cp2+B1(t)*p2)
|
||||
|
||||
class TKnot
|
||||
{
|
||||
public:
|
||||
// inline bool __fastcall IsCurve() { return (!(Point==CPointIn)); };
|
||||
// inline vector3 __fastcall GetDirection() { return (CPointOut-Point); };
|
||||
__fastcall TKnot();
|
||||
__fastcall TKnot(int n);
|
||||
__fastcall ~TKnot();
|
||||
inline float __fastcall GetRoll(float s)
|
||||
{
|
||||
if (Next)
|
||||
{
|
||||
s/= Length;
|
||||
return ((1-s)*fRoll+(s)*Next->fRoll);
|
||||
}
|
||||
else
|
||||
return fRoll;
|
||||
// (Length-s) (s-Length)
|
||||
}
|
||||
vector3 __fastcall GetDirection(float t= 0);
|
||||
inline vector3 __fastcall InterpolateSegm(float t) { return (Interpolate(t,Point,CPointOut,Next->CPointIn,Next->Point) ); };
|
||||
float __fastcall GetTFromS(float s);
|
||||
bool __fastcall Init(TKnot *NNext, TKnot *NPrev);
|
||||
bool __fastcall InitCPoints();
|
||||
bool __fastcall InitLength();
|
||||
vector3 Point,CPointIn,CPointOut;
|
||||
float fRoll;
|
||||
bool IsCurve;
|
||||
float Length;
|
||||
TKnot *Next,*Prev;
|
||||
float fLengthIn,fLengthOut;
|
||||
bool bSwitchDirectionForward;
|
||||
bool bSwitchDirectionBackward;
|
||||
|
||||
private:
|
||||
vector3 GetFirstDerivative(float fTime);
|
||||
float RombergIntegral (float fA, float fB);
|
||||
};
|
||||
|
||||
class TSpline
|
||||
{
|
||||
public:
|
||||
__fastcall TSpline();
|
||||
__fastcall TSpline(AnsiString asNName);
|
||||
__fastcall ~TSpline();
|
||||
bool __fastcall Create( int n, AnsiString asNName="foo" );
|
||||
bool __fastcall AssignKnots( TKnot *FirstKnot, int n );
|
||||
int __fastcall LoadFromFile( AnsiString FileName, TKnot *FirstKnot = NULL );
|
||||
int __fastcall Load( TQueryParserComp *Parser, AnsiString asEndString="endspline" );
|
||||
float __fastcall GetLength();
|
||||
vector3 __fastcall GetCenter();
|
||||
TKnot* __fastcall GetLastKnot();
|
||||
bool __fastcall Render();
|
||||
|
||||
// inline int NextIndex(int n) { return (n<KnotsCount-1 ? n+1 : 0); };
|
||||
|
||||
// inline vector3 InterpolateSegm(int i, float t) { return (Interpolate(t,Knots[i].Point,Knots[i].CPointOut,Knots[NextIndex(i)].CPointIn,Knots[NextIndex(i)].Point) ); };
|
||||
// inline vector3 InterpolateSegm(TKnot *Knot, float t) { return (Interpolate(t,Knots[i].Point,Knots[i].CPointOut,Knots[NextIndex(i)].CPointIn,Knots[NextIndex(i)].Point) ); };
|
||||
// bool Closed;
|
||||
// AnsiString asName;
|
||||
// TKnot *Knots;
|
||||
TKnot *RootKnot;
|
||||
bool KnotsAllocated;
|
||||
int iNumKnots;
|
||||
// TSpline *Next,*Prev;
|
||||
// TKnot Next,Prev;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
bool __fastcall Connect(TKnot *k1, TKnot *k2);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
79
Spring.cpp
Normal file
79
Spring.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#include "opengl/glew.h"
|
||||
#include "opengl/glut.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Spring.h"
|
||||
#include "Usefull.h"
|
||||
|
||||
|
||||
__fastcall TSpring::TSpring()
|
||||
{
|
||||
vForce1=vForce2= vector3(0,0,0);
|
||||
Ks= 0;
|
||||
Kd= 0;
|
||||
restLen= 0;
|
||||
}
|
||||
|
||||
__fastcall TSpring::~TSpring()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void __fastcall TSpring::Init(double nrestLen, double nKs, double nKd)
|
||||
{
|
||||
Ks= nKs;
|
||||
Kd= nKd;
|
||||
restLen= nrestLen;
|
||||
}
|
||||
|
||||
bool __fastcall TSpring::ComputateForces(vector3 pPosition1, vector3 pPosition2)
|
||||
{
|
||||
|
||||
double dist, Hterm, Dterm;
|
||||
vector3 springForce,deltaV,deltaP;
|
||||
// p1 = &system[spring->p1];
|
||||
// p2 = &system[spring->p2];
|
||||
// VectorDifference(&p1->pos,&p2->pos,&deltaP); // Vector distance
|
||||
deltaP= pPosition1 - pPosition2;
|
||||
// dist = VectorLength(&deltaP); // Magnitude of deltaP
|
||||
dist = deltaP.Length();
|
||||
if (dist==0)
|
||||
{
|
||||
vForce1=vForce2=vector3(0,0,0);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest)
|
||||
Hterm= (dist - restLen) * Ks; // Ks * (dist - rest)
|
||||
|
||||
// VectorDifference(&p1->v,&p2->v,&deltaV); // Delta Velocity Vector
|
||||
deltaV= pPosition1 - pPosition2;
|
||||
|
||||
// Dterm = (DotProduct(&deltaV,&deltaP) * spring->Kd) / dist; // Damping Term
|
||||
//Dterm = (DotProduct(deltaV,deltaP) * Kd) / dist;
|
||||
Dterm= 0;
|
||||
|
||||
// ScaleVector(&deltaP,1.0f / dist, &springForce); // Normalize Distance Vector
|
||||
// ScaleVector(&springForce,-(Hterm + Dterm),&springForce); // Calc Force
|
||||
springForce= deltaP/dist*(-(Hterm + Dterm));
|
||||
// VectorSum(&p1->f,&springForce,&p1->f); // Apply to Particle 1
|
||||
// VectorDifference(&p2->f,&springForce,&p2->f); // - Force on Particle 2
|
||||
vForce1= springForce;
|
||||
vForce2= springForce;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void __fastcall TSpring::Render()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
38
Spring.h
Normal file
38
Spring.h
Normal file
@@ -0,0 +1,38 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef ParticlesH
|
||||
#define ParticlesH
|
||||
|
||||
|
||||
#define STATIC_THRESHOLD 0.17f
|
||||
//efine STATIC_THRESHOLD 0.03f
|
||||
const double m_Kd = 0.02f; // DAMPING FACTOR
|
||||
const double m_Kr = 0.8f; // 1.0 = SUPERBALL BOUNCE 0.0 = DEAD WEIGHT
|
||||
const double m_Ksh = 5.0f; // HOOK'S SPRING CONSTANT
|
||||
const double m_Ksd = 0.1f; // SPRING DAMPING CONSTANT
|
||||
|
||||
const double m_Csf = 0.9f; // Default Static Friction
|
||||
const double m_Ckf = 0.7f; // Default Kinetic Friction
|
||||
|
||||
#include "dumb3d.h"
|
||||
using namespace Math3D;
|
||||
|
||||
class TSpring
|
||||
{
|
||||
public:
|
||||
__fastcall TSpring();
|
||||
__fastcall ~TSpring();
|
||||
// void __fastcall Init(TParticnp1, TParticle *np2, double nKs= 0.5f, double nKd= 0.002f, double nrestLen= -1.0f);
|
||||
void __fastcall Init(double nrestLen, double nKs= 0.5f, double nKd= 0.002f);
|
||||
bool __fastcall ComputateForces(vector3 pPosition1, vector3 pPosition2);
|
||||
void __fastcall Render();
|
||||
vector3 vForce1,vForce2;
|
||||
double restLen; // LENGTH OF SPRING AT REST
|
||||
double Ks; // SPRING CONSTANT
|
||||
double Kd; // SPRING DAMPING
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
835
Texture.cpp
Normal file
835
Texture.cpp
Normal file
@@ -0,0 +1,835 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak and others
|
||||
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include "opengl/glew.h"
|
||||
#include <ddraw>
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#include "stdio.h"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Usefull.h"
|
||||
#include "Texture.h"
|
||||
#include "TextureDDS.h"
|
||||
|
||||
#include "logs.h"
|
||||
#include "Globals.h"
|
||||
#include "io.h"
|
||||
|
||||
TTexturesManager::Alphas TTexturesManager::_alphas;
|
||||
TTexturesManager::Names TTexturesManager::_names;
|
||||
|
||||
void TTexturesManager::Init()
|
||||
{
|
||||
};
|
||||
|
||||
TTexturesManager::Names::iterator TTexturesManager::LoadFromFile(std::string fileName,int filter)
|
||||
{
|
||||
|
||||
std::string message("Loading - texture: ");
|
||||
|
||||
std::string realFileName(fileName);
|
||||
std::ifstream file(fileName.c_str());
|
||||
//Ra: niby bez tego jest lepiej, ale dzia³a gorzej, wiêc przywrócone jest oryginalne
|
||||
if (!file.is_open())
|
||||
realFileName.insert(0,szTexturePath);
|
||||
else
|
||||
file.close();
|
||||
|
||||
//char* cFileName = const_cast<char*>(fileName.c_str());
|
||||
|
||||
message += realFileName;
|
||||
WriteLog(message.c_str()); //Ra: chybaa mia³o byæ z komunikatem z przodu, a nie tylko nazwa
|
||||
|
||||
size_t pos = fileName.rfind('.');
|
||||
std::string ext(fileName, pos + 1, std::string::npos);
|
||||
|
||||
AlphaValue texinfo;
|
||||
|
||||
if (ext=="tga")
|
||||
texinfo=LoadTGA(realFileName,filter);
|
||||
else if (ext=="tex")
|
||||
texinfo=LoadTEX(realFileName);
|
||||
else if (ext=="bmp")
|
||||
texinfo=LoadBMP(realFileName);
|
||||
else if (ext=="dds")
|
||||
texinfo=LoadDDS(realFileName,filter);
|
||||
|
||||
_alphas.insert(texinfo); //zapamiêtanie stanu przezroczystoœci tekstury - mo¿na by tylko przezroczyste
|
||||
std::pair<Names::iterator, bool> ret = _names.insert(std::make_pair(fileName, texinfo.first));
|
||||
|
||||
if (!texinfo.first)
|
||||
{
|
||||
WriteLog("Failed");
|
||||
ErrorLog("Missed texture: "+AnsiString(realFileName.c_str()));
|
||||
return _names.end();
|
||||
};
|
||||
|
||||
_alphas.insert(texinfo);
|
||||
ret=_names.insert(std::make_pair(fileName,texinfo.first)); //dodanie tekstury do magazynu (spisu nazw)
|
||||
|
||||
//WriteLog("OK"); //Ra: "OK" nie potrzeba, samo "Failed" wystarczy
|
||||
return ret.first;
|
||||
|
||||
};
|
||||
|
||||
struct ReplaceSlash
|
||||
{
|
||||
const char operator()(const char input)
|
||||
{
|
||||
return input == '/' ? '\\' : input;
|
||||
}
|
||||
};
|
||||
|
||||
GLuint TTexturesManager::GetTextureID(char* dir,char* where,std::string fileName,int filter)
|
||||
{//ustalenie numeru tekstury, wczytanie jeœli nie jeszcze takiej nie by³o
|
||||
/*
|
||||
// Ra: niby tak jest lepiej, ale dzia³a gorzej, wiêc przywrócone jest oryginalne
|
||||
//najpierw szukamy w katalogu, z którego wywo³ywana jest tekstura, potem z wy¿szego
|
||||
//Ra: przerobiæ na wyszukiwanie w drzewie nazw, do którego zapisywaæ np. rozmiary, przezroczystoœæ
|
||||
//Ra: ustalaæ, które tekstury mo¿na wczytaæ ju¿ w trakcie symulacji
|
||||
size_t pos=fileName.find(':'); //szukamy dwukropka
|
||||
if (pos!=std::string::npos) //po dwukropku mog¹ byæ podane dodatkowe informacje
|
||||
fileName=fileName.substr(0,pos); //niebêd¹ce nazw¹ tekstury
|
||||
std::transform(fileName.begin(),fileName.end(),fileName.begin(),ReplaceSlash()); //zamiana "/" na "\"
|
||||
//jeœli bie¿aca œcie¿ka do tekstur nie zosta³a dodana to dodajemy domyœln¹
|
||||
//if (fileName.find('\\')==std::string::npos) //bz sensu
|
||||
// fileName.insert(0,szDefaultTexturePath);
|
||||
//najpierw szukamy w podanym katalogu, potem w domyœlnym
|
||||
Names::iterator iter;
|
||||
std::ifstream file;
|
||||
if ((fileName.find('.')==fileName.npos)?true:(fileName.rfind('.')<fileName.rfind('\\'))) //pierwsza kropka od prawej jest wczeœniej ni¿ "\"
|
||||
{//Ra: jeœli nie ma kropki w nazwie pliku, wypróbowanie rozszerzeñ po kolei, zaczynaj¹c od domyœlnego
|
||||
fileName.append("."); //kropkê trzeba dodaæ na pewno, resztê trzeba próbowaæ
|
||||
std::string test; //zmienna robocza
|
||||
for (int i=0;i<4;++i)
|
||||
{//najpierw szukamy w magazynie
|
||||
test=fileName;
|
||||
if (where) test.insert(0,where); //œcie¿ka obiektu wywo³uj¹cego
|
||||
test.append(Global::szDefaultExt[i]); //dodanie jednego z kilku rozszerzeñ
|
||||
iter=_names.find(test); //czy mamy ju¿ w magazynie?
|
||||
if (iter!=_names.end())
|
||||
return iter->second; //znalezione!
|
||||
if (dir)
|
||||
{//mo¿e we wskazanym katalogu?
|
||||
test=fileName;
|
||||
test.insert(0,dir); //jeszcze próba z dodatkow¹ œcie¿k¹
|
||||
test.append(Global::szDefaultExt[i]); //dodanie jednego z kilku rozszerzeñ
|
||||
iter=_names.find(test); //czy mamy ju¿ w magazynie?
|
||||
if (iter!=_names.end())
|
||||
return iter->second; //znalezione!
|
||||
}
|
||||
//}
|
||||
//for (int i=0;i<4;++i)
|
||||
//{//w magazynie nie ma, to sprawdzamy na dysku
|
||||
test=fileName;
|
||||
if (where) test.insert(0,where); //œcie¿ka obiektu wywo³uj¹cego
|
||||
test.append(Global::szDefaultExt[i]); //dodanie jednego z kilku rozszerzeñ
|
||||
file.open(test.c_str());
|
||||
if (!file.is_open())
|
||||
{test=fileName;
|
||||
if (dir) test.insert(0,dir); //próba z dodatkow¹ œcie¿k¹
|
||||
test.append(Global::szDefaultExt[i]); //dodanie jednego z kilku rozszerzeñ
|
||||
file.open(test.c_str());
|
||||
}
|
||||
if (file.is_open())
|
||||
{//jak znaleziony, to plik zostaje otwarty
|
||||
fileName=test; //zapamiêtanie znalezionego rozszerzenia
|
||||
break; //wyjœcie z pêtli na etapie danego rozszerzenia
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{//gdy jest kropka, to rozszerzenie jest jawne
|
||||
std::string test; //zmienna robocza
|
||||
//najpierw szukamy w magazynie
|
||||
test=fileName;
|
||||
if (where) test.insert(0,where); //œcie¿ka obiektu wywo³uj¹cego
|
||||
iter=_names.find(test); //czy mamy ju¿ w magazynie?
|
||||
if (iter!=_names.end())
|
||||
return iter->second; //znalezione!
|
||||
test=fileName;
|
||||
if (dir) test.insert(0,dir); //jeszcze próba z dodatkow¹ œcie¿k¹
|
||||
iter=_names.find(test); //czy mamy ju¿ w magazynie?
|
||||
if (iter!=_names.end())
|
||||
return iter->second; //znalezione!
|
||||
//w magazynie nie ma, to sprawdzamy na dysku
|
||||
test=fileName;
|
||||
if (where) test.insert(0,where); //œcie¿ka obiektu wywo³uj¹cego
|
||||
file.open(test.c_str());
|
||||
if (!file.is_open())
|
||||
{//jak znaleziony, to plik zostaje otwarty
|
||||
test=fileName;
|
||||
if (dir) test.insert(0,dir); //próba z dodatkow¹ œcie¿k¹
|
||||
file.open(test.c_str());
|
||||
if (file.is_open())
|
||||
fileName=test; //ustalenie nowej nazwy
|
||||
}
|
||||
}
|
||||
if (file.is_open())
|
||||
{//plik pozostaje otwarty, gdy znaleziono na dysku
|
||||
file.close(); //mo¿na ju¿ zamkn¹æ
|
||||
iter=LoadFromFile(fileName,filter); //doda siê do magazynu i zwróci swoj¹ pozycjê
|
||||
}
|
||||
*/
|
||||
size_t pos=fileName.find(':'); //szukamy dwukropka
|
||||
if (pos!=std::string::npos) //po dwukropku mog¹ byæ podane dodatkowe informacje
|
||||
fileName=fileName.substr(0,pos); //niebêd¹ce nazw¹ tekstury
|
||||
pos=fileName.find('|'); //szukamy separatora tekstur
|
||||
if (pos!=std::string::npos) //po | mo¿e byæ nazwa kolejnej tekstury
|
||||
fileName=fileName.substr(0,pos); //i trzeba to obci¹æ
|
||||
std::transform(fileName.begin(),fileName.end(),fileName.begin(),ReplaceSlash());
|
||||
//jeœli bie¿aca œcie¿ka do tekstur nie zosta³a dodana to dodajemy domyœln¹
|
||||
if (fileName.find('\\')==std::string::npos)
|
||||
fileName.insert(0,szTexturePath);
|
||||
Names::iterator iter;
|
||||
if (fileName.find('.')==std::string::npos)
|
||||
{//Ra: wypróbowanie rozszerzeñ po kolei, zaczynaj¹c od domyœlnego
|
||||
fileName.append("."); //kropka bêdze na pewno, resztê trzeba próbowaæ
|
||||
std::string test; //zmienna robocza
|
||||
for (int i=0;i<4;++i)
|
||||
{//najpierw szukamy w magazynie
|
||||
test=fileName;
|
||||
test.append(Global::szDefaultExt[i]);
|
||||
iter=_names.find(fileName); //czy mamy ju¿ w magazynie?
|
||||
if (iter!=_names.end())
|
||||
return iter->second; //znalezione!
|
||||
test.insert(0,szTexturePath); //jeszcze próba z dodatkow¹ œcie¿k¹
|
||||
iter=_names.find(fileName); //czy mamy ju¿ w magazynie?
|
||||
if (iter!=_names.end())
|
||||
return iter->second; //znalezione!
|
||||
}
|
||||
for (int i=0;i<4;++i)
|
||||
{//w magazynie nie ma, to sprawdzamy na dysku
|
||||
test=fileName;
|
||||
test.append(Global::szDefaultExt[i]);
|
||||
std::ifstream file(test.c_str());
|
||||
if (!file.is_open())
|
||||
{test.insert(0,szTexturePath);
|
||||
file.open(test.c_str());
|
||||
}
|
||||
if (file.is_open())
|
||||
{
|
||||
fileName.append(Global::szDefaultExt[i]); //dopisanie znalezionego
|
||||
file.close();
|
||||
break; //wyjœcie z pêtli na etapie danego rozszerzenia
|
||||
}
|
||||
}
|
||||
}
|
||||
iter=_names.find(fileName); //czy mamy ju¿ w magazynie
|
||||
if (iter==_names.end())
|
||||
iter=LoadFromFile(fileName,filter);
|
||||
return (iter!=_names.end()?iter->second:0);
|
||||
};
|
||||
|
||||
bool TTexturesManager::GetAlpha(GLuint id)
|
||||
{//atrybut przezroczystoœci dla tekstury o podanym numerze (id)
|
||||
Alphas::iterator iter=_alphas.find(id);
|
||||
return (iter!=_alphas.end()?iter->second:false);
|
||||
}
|
||||
|
||||
TTexturesManager::AlphaValue TTexturesManager::LoadBMP(std::string fileName)
|
||||
{
|
||||
|
||||
AlphaValue fail(0, false);
|
||||
std::ifstream file(fileName.c_str(), std::ios::binary);
|
||||
|
||||
if (!file.is_open())
|
||||
{
|
||||
//file.close();
|
||||
return fail;
|
||||
};
|
||||
|
||||
BITMAPFILEHEADER header;
|
||||
size_t bytes;
|
||||
|
||||
file.read((char*) &header, sizeof(BITMAPFILEHEADER));
|
||||
if(file.eof())
|
||||
{
|
||||
file.close();
|
||||
return fail;
|
||||
}
|
||||
|
||||
// Read in bitmap information structure
|
||||
BITMAPINFO info;
|
||||
long infoSize = header.bfOffBits - sizeof(BITMAPFILEHEADER);
|
||||
file.read((char*) &info, infoSize);
|
||||
|
||||
if(file.eof())
|
||||
{
|
||||
file.close();
|
||||
return fail;
|
||||
};
|
||||
|
||||
GLuint width = info.bmiHeader.biWidth;
|
||||
GLuint height = info.bmiHeader.biHeight;
|
||||
|
||||
unsigned long bitSize = info.bmiHeader.biSizeImage;
|
||||
if(!bitSize)
|
||||
bitSize = (width * info.bmiHeader.biBitCount + 7) / 8 * height;
|
||||
|
||||
GLubyte* data = new GLubyte[bitSize];
|
||||
file.read((char*) data, bitSize);
|
||||
|
||||
if(file.eof())
|
||||
{
|
||||
delete[] data;
|
||||
file.close();
|
||||
return fail;
|
||||
};
|
||||
|
||||
file.close();
|
||||
|
||||
GLuint id;
|
||||
|
||||
glGenTextures(1, &id);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
// This is specific to the binary format of the data read in.
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0,
|
||||
GL_BGR_EXT, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
delete[] data;
|
||||
return std::make_pair(id, false);
|
||||
|
||||
};
|
||||
|
||||
TTexturesManager::AlphaValue TTexturesManager::LoadTGA(std::string fileName,int filter)
|
||||
{
|
||||
AlphaValue fail(0,false);
|
||||
int writeback=-1; //-1 plik jest OK, >=0 - od którego bajtu zapisaæ poprawiony plik
|
||||
GLubyte TGACompheader[]={0,0,10,0,0,0,0,0,0,0,0,0}; //uncompressed TGA header
|
||||
GLubyte TGAcompare[12]; //used to compare TGA header
|
||||
GLubyte header[6]; //first 6 useful bytes from the header
|
||||
std::fstream file(fileName.c_str(),std::ios::binary|std::ios::in);
|
||||
file.read((char*)TGAcompare,sizeof(TGAcompare));
|
||||
file.read((char*)header,sizeof(header));
|
||||
//std::cout << file.tellg() << std::endl;
|
||||
if (file.eof())
|
||||
{
|
||||
file.close();
|
||||
return fail;
|
||||
};
|
||||
bool compressed=(memcmp(TGACompheader,TGAcompare,sizeof(TGACompheader))==0);
|
||||
GLint width =header[1]*256+header[0]; //determine the TGA width (highbyte*256+lowbyte)
|
||||
GLint height=header[3]*256+header[2]; //determine the TGA height (highbyte*256+lowbyte)
|
||||
// check if width, height and bpp is correct
|
||||
if ( !width || !height || (header[4]!=24 && header[4]!=32))
|
||||
{
|
||||
WriteLog("Bad texture: "+AnsiString(fileName.c_str())+" has wrong header or bits per pixel");
|
||||
file.close();
|
||||
return fail;
|
||||
};
|
||||
{//sprawdzenie prawid³owoœci rozmiarów
|
||||
int i,j;
|
||||
for (i=width,j=0;i;i>>=1) if (i&1) ++j;
|
||||
if (j==1)
|
||||
for (i=height,j=0;i;i>>=1) if (i&1) ++j;
|
||||
if (j!=1) WriteLog("Bad texture: "+AnsiString(fileName.c_str())+" is "+AnsiString(width)+"×"+AnsiString(height));
|
||||
}
|
||||
GLuint bpp=header[4]; //grab the TGA's bits per pixel (24 or 32)
|
||||
GLuint bytesPerPixel=bpp/8; // divide by 8 to get the bytes per pixel
|
||||
GLuint imageSize=width*height*bytesPerPixel; //calculate the memory required for the TGA data
|
||||
GLubyte *imageData=new GLubyte[imageSize]; //reserve memory to hold the TGA data
|
||||
if (!compressed)
|
||||
{//WriteLog("Not compressed.");
|
||||
file.read(imageData,imageSize);
|
||||
if (file.eof())
|
||||
{
|
||||
delete[] imageData;
|
||||
file.close();
|
||||
return fail;
|
||||
};
|
||||
}
|
||||
else
|
||||
{//skompresowany plik TGA
|
||||
GLuint filesize; //current byte
|
||||
GLuint colorbuffer[1]; // Storage for 1 pixel
|
||||
file.seekg(0,ios::end); //na koniec
|
||||
filesize=(int)file.tellg()-18; //rozmiar bez nag³ówka
|
||||
file.seekg(18,ios::beg); //ponownie za nag³ówkiem
|
||||
GLubyte *copyto=imageData; //gdzie wstawiaæ w buforze
|
||||
GLubyte *copyend=imageData+imageSize; //za ostatnim bajtem bufora
|
||||
GLubyte *copyfrom=imageData+imageSize-filesize; //gdzie jest pocz¹tek
|
||||
int chunkheader=0; //Ra: bêdziemy wczytywaæ najm³odszy bajt
|
||||
if (filesize<imageSize) //jeœli po kompresji jest mniejszy ni¿ przed
|
||||
{//Ra: nowe wczytywanie skompresowanych: czytamy ca³e od razu, dekompresja w pamiêci
|
||||
GLuint copybytes;
|
||||
file.read(copyfrom,filesize); //wczytanie reszty po nag³ówku
|
||||
//najpierw trzeba ustaliæ, ile skopiowanych pikseli jest na samym koñcu
|
||||
copyto=copyfrom; //roboczo przelatujemy wczytane dane
|
||||
copybytes=0; //licznik bajtów obrazka
|
||||
while (copybytes<imageSize)
|
||||
{
|
||||
chunkheader=(unsigned char)*copyto; //jeden bajt, pozosta³e zawsze zerowe
|
||||
copyto+=1+bytesPerPixel; //bajt licznika oraz jeden piksel jest zawsze
|
||||
copybytes+=(1+(chunkheader&127))*bytesPerPixel; //iloϾ pikseli
|
||||
if (chunkheader<128) //jeœli kopiowanie, pikseli jest wiêcej
|
||||
copyto+=(chunkheader)*bytesPerPixel; //rozmiar kopiowanego obszaru (bez jednego piksela)
|
||||
}
|
||||
if (copybytes>imageSize)
|
||||
{//nie ma prawa byæ wiêksze
|
||||
WriteLog("Compression error");
|
||||
delete[] imageData;
|
||||
file.close();
|
||||
return fail;
|
||||
}
|
||||
//na koñcu mog¹ byæ œmieci
|
||||
int extraend=copyend-copyto; //d³ugoœæ œmieci na koñcu
|
||||
if (extraend>0)
|
||||
{//przesuwamy bufor do koñca obszaru dekompresji
|
||||
WriteLog("Extra bytes: "+AnsiString(extraend));
|
||||
memmove(copyfrom+extraend,copyfrom,filesize-extraend);
|
||||
copyfrom+=extraend;
|
||||
file.close();
|
||||
filesize-=extraend; //to chyba nie ma znaczenia
|
||||
if (Global::iModifyTGA&2) //flaga obcinania œmieci
|
||||
{//najlepiej by by³o obci¹æ plik, ale fstream tego nie potrafi
|
||||
int handle;
|
||||
for (unsigned int i=0;i<fileName.length();++i)
|
||||
if (fileName[i]=='/')
|
||||
fileName[i]=='\\'; //bo to Windows
|
||||
WriteLog("Truncating extra bytes");
|
||||
handle=open(fileName.c_str(),O_RDWR|O_BINARY);
|
||||
chsize(handle,18+filesize); //obciêcie œmieci
|
||||
close(handle);
|
||||
extraend=0; //skoro obciêty, to siê ju¿ nie liczy
|
||||
}
|
||||
file.open(fileName.c_str(),std::ios::binary|std::ios::in);
|
||||
}
|
||||
if (chunkheader<128) //jeœli ostatnie piksele s¹ kopiowane
|
||||
copyend-=(1+chunkheader)*bytesPerPixel; //bajty kopiowane na koñcu nie podlegaj¹ce dekompresji
|
||||
else
|
||||
copyend-=bytesPerPixel; //ostatni piksel i tak siê nie zmieni
|
||||
copyto=imageData; //teraz bêdzie wype³nianie od pocz¹tku obszaru
|
||||
while (copyto<copyend)
|
||||
{
|
||||
chunkheader=(unsigned char)*copyfrom; //jeden bajt, pozosta³e zawsze zerowe
|
||||
if (copyto>copyfrom)
|
||||
{//jeœli piksele maj¹ byæ kopiowane, to mo¿liwe jest przesuniêcie ich o 1 bajt, na miejsce licznika
|
||||
filesize=(imageData+imageSize-copyto)/bytesPerPixel; //ile pikseli pozosta³o do koñca
|
||||
//WriteLog("Decompression buffer overflow at pixel "+AnsiString((copyto-imageData)/bytesPerPixel)+"+"+AnsiString(filesize));
|
||||
//pozycjê w pliku trzeba by zapamietaæ i po wczytaniu reszty pikseli star¹ metod¹
|
||||
//zapisaæ od niej dane od (copyto), poprzedzone bajtem o wartoœci (filesize-1)
|
||||
writeback=imageData+imageSize+extraend-copyfrom; //ile bajtów skompresowanych zosta³o do koñca
|
||||
copyfrom=copyto; //adres piksela do zapisania
|
||||
file.seekg(-writeback,ios::end); //odleg³oœæ od koñca (ujemna)
|
||||
if ((filesize>128)||!(Global::iModifyTGA&4)) //gdy za du¿o pikseli albo wy³¹czone
|
||||
writeback=-1; //zapis mo¿liwe jeœli iloœæ problematycznych pikseli nie przekaracza 128
|
||||
break; //bufor siê zatka³, dalej w ten sposób siê nie da
|
||||
}
|
||||
if (chunkheader<128)
|
||||
{//dla nag³ówka < 128 mamy podane ile pikseli przekopiowaæ minus 1
|
||||
copybytes=(++chunkheader)*bytesPerPixel; //rozmiar kopiowanego obszaru
|
||||
memcpy(copyto,++copyfrom,copybytes); //skopiowanie tylu bajtów
|
||||
copyto+=copybytes;
|
||||
copyfrom+=copybytes;
|
||||
}
|
||||
else
|
||||
{//chunkheader > 128 RLE data, next color reapeated chunkheader - 127 times
|
||||
chunkheader-=127;
|
||||
//copy the color into the image data as many times as dictated
|
||||
if (bytesPerPixel==4)
|
||||
{//przy czterech bajtach powinno byæ szybsze u¿ywanie int
|
||||
__int32 *ptr=(__int32*)(copyto); //wskaŸnik na int
|
||||
__int32 bgra=*((__int32*)++copyfrom); //kolor wype³niaj¹cy (4 bajty)
|
||||
for (int counter=0;counter<chunkheader;counter++)
|
||||
*ptr++=bgra;
|
||||
copyto=(char*)(ptr); //rzutowanie, ¿eby nie dodawaæ
|
||||
copyfrom+=4;
|
||||
}
|
||||
else
|
||||
{colorbuffer[0]=*((int*)(++copyfrom)); //pobranie koloru (3 bajty)
|
||||
for (int counter=0;counter<chunkheader;counter++)
|
||||
{ // by the header
|
||||
memcpy(copyto,colorbuffer,3);
|
||||
copyto+=3;
|
||||
}
|
||||
copyfrom+=3;
|
||||
}
|
||||
}
|
||||
} //while (copyto<copyend)
|
||||
}
|
||||
else
|
||||
{WriteLog("Compressed file is larger than uncompressed!");
|
||||
if (Global::iModifyTGA&1)
|
||||
writeback=0; //no zapisaæ ten krótszy zaczynajac od pocz¹tku...
|
||||
}
|
||||
//if (copyto<copyend) WriteLog("Slow loader...");
|
||||
while (copyto<copyend)
|
||||
{//Ra: stare wczytywanie skompresowanych, z nadu¿ywaniem file.read()
|
||||
//równie¿ wykonywane, jeœli dekompresja w buforze przekroczy jego rozmiar
|
||||
file.read((char*)&chunkheader,1); //jeden bajt, pozosta³e zawsze zerowe
|
||||
if (file.eof())
|
||||
{
|
||||
MessageBox(NULL,"Could not read RLE header","ERROR",MB_OK); //display error
|
||||
delete[] imageData;
|
||||
file.close();
|
||||
return fail;
|
||||
};
|
||||
if (chunkheader<128)
|
||||
{//if the header is < 128, it means the that is the number of RAW color packets minus 1
|
||||
chunkheader++; //add 1 to get number of following color values
|
||||
file.read(copyto,chunkheader*bytesPerPixel);
|
||||
copyto+=chunkheader*bytesPerPixel;
|
||||
}
|
||||
else
|
||||
{//chunkheader>128 RLE data, next color reapeated (chunkheader-127) times
|
||||
chunkheader-=127;
|
||||
file.read((char*)colorbuffer,bytesPerPixel);
|
||||
//copy the color into the image data as many times as dictated
|
||||
if (bytesPerPixel==4)
|
||||
{//przy czterech bajtach powinno byæ szybsze u¿ywanie int
|
||||
__int32 *ptr=(__int32*)(copyto),bgra=*((__int32*)colorbuffer);
|
||||
for (int counter=0;counter<chunkheader;counter++)
|
||||
*ptr++=bgra;
|
||||
copyto=(char*)(ptr); //rzutowanie, ¿eby nie dodawaæ
|
||||
}
|
||||
else
|
||||
for (int counter=0;counter<chunkheader;counter++)
|
||||
{ // by the header
|
||||
memcpy(copyto,colorbuffer,bytesPerPixel);
|
||||
copyto+=bytesPerPixel;
|
||||
}
|
||||
}
|
||||
} //while (copyto<copyend)
|
||||
if (writeback>=0)
|
||||
{//zapisanie pliku
|
||||
file.close(); //tamten zamykamy, bo by³ tylko do odczytu
|
||||
if (writeback)
|
||||
{//zapisanie samej koñcówki pliku, która utrudnia dekompresjê w buforze
|
||||
WriteLog("Rewriting end of file...");
|
||||
chunkheader=filesize-1; //licznik jest o 1 mniejszy
|
||||
file.open(fileName.c_str(),std::ios::binary|std::ios::out|std::ios::in);
|
||||
file.seekg(-writeback,ios::end); //odleg³oœæ od koñca (ujemna)
|
||||
file.write((char*)&chunkheader,1); //zapisanie licznika
|
||||
file.write(copyfrom,filesize*bytesPerPixel); //piksele bez kompresji
|
||||
}
|
||||
else
|
||||
{//zapisywanie ca³oœci pliku, bêdzie krótszy, wiêc trzeba usun¹æ go w ca³oœci
|
||||
WriteLog("Writing uncompressed file...");
|
||||
TGAcompare[2]=2; //bez kompresji
|
||||
file.open(fileName.c_str(),std::ios::binary|std::ios::out|std::ios::trunc);
|
||||
file.write((char*)TGAcompare,sizeof(TGAcompare));
|
||||
file.write((char*)header,sizeof(header));
|
||||
file.write(imageData,imageSize);
|
||||
}
|
||||
}
|
||||
};
|
||||
file.close(); //plik zamykamy dopiero na samym koñcu
|
||||
bool alpha = (bpp == 32);
|
||||
bool hash = (fileName.find('#') != std::string::npos); //true gdy w nazwie jest "#"
|
||||
bool dollar = (fileName.find('$') == std::string::npos); //true gdy w nazwie nie ma "$"
|
||||
size_t pos=fileName.rfind('%'); //ostatni % w nazwie
|
||||
if (pos!=std::string::npos)
|
||||
if (pos<fileName.size())
|
||||
{filter=(int)fileName[pos+1]-'0'; //zamiana cyfry za % na liczbê
|
||||
if ((filter<0)||(filter>10)) filter=-1; //jeœli nie jest cyfr¹
|
||||
}
|
||||
if (!alpha&&!hash&&dollar&&(filter<0))
|
||||
filter=Global::iDefaultFiltering; //dotyczy tekstur TGA bez kana³u alfa
|
||||
//ewentualne przeskalowanie tekstury do dopuszczalnego rozumiaru
|
||||
GLint w=width,h=height;
|
||||
if (width>Global::iMaxTextureSize) width=Global::iMaxTextureSize; //ogranizczenie wielkoœci
|
||||
if (height>Global::iMaxTextureSize) height=Global::iMaxTextureSize;
|
||||
if ((w!=width)||(h!=height))
|
||||
{//przeskalowanie tekstury, ¿eby siê nie wyœwietla³a jako bia³a
|
||||
GLubyte* imgData=new GLubyte[width*height*bytesPerPixel]; //nowy rozmiar
|
||||
gluScaleImage(bytesPerPixel==3?GL_RGB:GL_RGBA,w,h,GL_UNSIGNED_BYTE,imageData,width,height,GL_UNSIGNED_BYTE,imgData);
|
||||
delete imageData; //usuniêcie starego
|
||||
imageData=imgData;
|
||||
}
|
||||
GLuint id=CreateTexture(imageData,(alpha?GL_BGRA:GL_BGR),width,height,alpha,hash,dollar,filter);
|
||||
delete[] imageData;
|
||||
++Global::iTextures;
|
||||
return std::make_pair(id,alpha);
|
||||
};
|
||||
|
||||
TTexturesManager::AlphaValue TTexturesManager::LoadTEX(std::string fileName)
|
||||
{
|
||||
|
||||
AlphaValue fail(0, false);
|
||||
|
||||
std::ifstream file(fileName.c_str(), ios::binary);
|
||||
|
||||
char head[5];
|
||||
file.read(head, 4);
|
||||
head[4] = 0;
|
||||
|
||||
bool alpha;
|
||||
|
||||
if(std::string("RGB ") == head)
|
||||
{
|
||||
alpha = false;
|
||||
}
|
||||
else if(std::string("RGBA") == head)
|
||||
{
|
||||
alpha = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string message("Unrecognized texture format: ");
|
||||
message += head;
|
||||
Error(message.c_str());
|
||||
return fail;
|
||||
};
|
||||
|
||||
GLuint width;
|
||||
GLuint height;
|
||||
|
||||
file.read((char *) &width, sizeof(int));
|
||||
file.read((char *) &height, sizeof(int));
|
||||
|
||||
GLuint bpp = alpha ? 4 : 3;
|
||||
GLuint size = width * height * bpp;
|
||||
|
||||
GLubyte* data = new GLubyte[size];
|
||||
file.read(data, size);
|
||||
|
||||
bool hash = (fileName.find('#') != std::string::npos);
|
||||
|
||||
GLuint id = CreateTexture(data,(alpha?GL_RGBA:GL_RGB),width,height,alpha,hash);
|
||||
delete[] data;
|
||||
|
||||
return std::make_pair(id, alpha);
|
||||
|
||||
};
|
||||
|
||||
TTexturesManager::AlphaValue TTexturesManager::LoadDDS(std::string fileName,int filter)
|
||||
{
|
||||
|
||||
AlphaValue fail(0, false);
|
||||
|
||||
std::ifstream file(fileName.c_str(), ios::binary);
|
||||
|
||||
char filecode[5];
|
||||
file.read(filecode, 4);
|
||||
filecode[4] = 0;
|
||||
|
||||
if(std::string("DDS ") != filecode)
|
||||
{
|
||||
file.close();
|
||||
return fail;
|
||||
};
|
||||
|
||||
DDSURFACEDESC2 ddsd;
|
||||
file.read((char*) &ddsd, sizeof(ddsd));
|
||||
|
||||
DDS_IMAGE_DATA data;
|
||||
|
||||
//
|
||||
// This .dds loader supports the loading of compressed formats DXT1, DXT3
|
||||
// and DXT5.
|
||||
//
|
||||
|
||||
GLuint factor;
|
||||
|
||||
switch( ddsd.ddpfPixelFormat.dwFourCC )
|
||||
{
|
||||
case FOURCC_DXT1:
|
||||
// DXT1's compression ratio is 8:1
|
||||
data.format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
|
||||
factor = 2;
|
||||
break;
|
||||
|
||||
case FOURCC_DXT3:
|
||||
// DXT3's compression ratio is 4:1
|
||||
data.format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
factor = 4;
|
||||
break;
|
||||
|
||||
case FOURCC_DXT5:
|
||||
// DXT5's compression ratio is 4:1
|
||||
data.format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
factor = 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
file.close();
|
||||
return fail;
|
||||
}
|
||||
|
||||
GLuint bufferSize = (ddsd.dwMipMapCount > 1 ? ddsd.dwLinearSize * factor : ddsd.dwLinearSize);
|
||||
|
||||
data.pixels = new GLubyte[bufferSize];
|
||||
file.read((char*)data.pixels,bufferSize);
|
||||
|
||||
file.close();
|
||||
|
||||
data.width = ddsd.dwWidth;
|
||||
data.height = ddsd.dwHeight;
|
||||
data.numMipMaps = ddsd.dwMipMapCount;
|
||||
{//sprawdzenie prawid³owoœci rozmiarów
|
||||
int i,j;
|
||||
for (i=data.width,j=0;i;i>>=1) if (i&1) ++j;
|
||||
if (j==1)
|
||||
for (i=data.height,j=0;i;i>>=1) if (i&1) ++j;
|
||||
if (j!=1) WriteLog("Bad texture: "+AnsiString(fileName.c_str())+" is "+AnsiString(data.width)+"×"+AnsiString(data.height));
|
||||
}
|
||||
|
||||
if (ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1)
|
||||
data.components = 3;
|
||||
else
|
||||
data.components = 4;
|
||||
|
||||
data.blockSize = (data.format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ? 8 : 16);
|
||||
|
||||
GLuint id;
|
||||
glGenTextures(1, &id);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
if (filter>=0)
|
||||
SetFiltering(filter); //cyfra po % w nazwie
|
||||
else
|
||||
//SetFiltering(bHasAlpha&&bDollar,bHash); //znaki #, $ i kana³ alfa w nazwie
|
||||
SetFiltering(data.components==4,fileName.find('#')!=std::string::npos);
|
||||
|
||||
GLuint offset = 0;
|
||||
int firstMipMap = 0;
|
||||
|
||||
while ((data.width>Global::iMaxTextureSize)||(data.height>Global::iMaxTextureSize))
|
||||
{//pomijanie zbyt du¿ych mipmap, jeœli wymagane jest ograniczenie rozmiaru
|
||||
offset+=((data.width+3)/4)*((data.height+3)/4)*data.blockSize;
|
||||
data.width/=2;
|
||||
data.height/=2;
|
||||
firstMipMap++;
|
||||
};
|
||||
|
||||
for (int i=0;i<data.numMipMaps-firstMipMap;i++)
|
||||
{//wczytanie kolejnych poziomów mipmap
|
||||
if (!data.width) data.width=1;
|
||||
if (!data.height) data.height=1;
|
||||
GLuint size=((data.width+3)/4)*((data.height+3)/4)*data.blockSize;
|
||||
if (Global::bDecompressDDS)
|
||||
{//programowa dekompresja DDS
|
||||
//if (i==1) //should be i==0 but then problem with "glBindTexture()"
|
||||
{GLuint decomp_size=data.width*data.height*4;
|
||||
GLubyte* output=new GLubyte[decomp_size];
|
||||
DecompressDXT(data,data.pixels+offset,output);
|
||||
glTexImage2D(GL_TEXTURE_2D,i,GL_RGBA,data.width,data.height,0,GL_RGBA,GL_UNSIGNED_BYTE,output);
|
||||
delete[] output;
|
||||
}
|
||||
}
|
||||
else //przetwarzanie DDS przez OpenGL (istnieje odpowiednie rozszerzenie)
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D,i,data.format,data.width,data.height,0,size,data.pixels+offset);
|
||||
offset+=size;
|
||||
// Half the image size for the next mip-map level...
|
||||
data.width/=2;
|
||||
data.height/=2;
|
||||
};
|
||||
delete[] data.pixels;
|
||||
return std::make_pair(id, data.components == 4);
|
||||
};
|
||||
|
||||
void TTexturesManager::SetFiltering(int filter)
|
||||
{
|
||||
if (filter<4) //rozmycie przy powiêkszeniu
|
||||
{//brak rozmycia z bliska - tych jest 4: 0..3, aby nie by³o przeskoku
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
||||
filter+=4;
|
||||
}
|
||||
else
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
|
||||
switch (filter) //rozmycie przy oddaleniu
|
||||
{case 4: //najbli¿szy z tekstury
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); break;
|
||||
case 5: //œrednia z tekstury
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); break;
|
||||
case 6: //najbli¿szy z mipmapy
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST); break;
|
||||
case 7: //œrednia z mipmapy
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); break;
|
||||
case 8: //najbli¿szy z dwóch mipmap
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_LINEAR); break;
|
||||
case 9: //œrednia z dwóch mipmap
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); break;
|
||||
}
|
||||
};
|
||||
|
||||
void TTexturesManager::SetFiltering(bool alpha, bool hash)
|
||||
{
|
||||
|
||||
if ( alpha || hash )
|
||||
{
|
||||
if (alpha) // przezroczystosc: nie wlaczac mipmapingu
|
||||
{
|
||||
if (hash) // #: calkowity brak filtracji - pikseloza
|
||||
{
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
}
|
||||
else // filtruj ale bez dalekich mipmap - robi artefakty
|
||||
{
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
}
|
||||
else // $: filtruj wszystko - brzydko siê zlewa
|
||||
{
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
GLuint TTexturesManager::CreateTexture(char* buff,GLint bpp,int width,int height,bool bHasAlpha,bool bHash,bool bDollar,int filter)
|
||||
{//Ra: u¿ywane tylko dla TGA i TEX
|
||||
//Ra: dodana obs³uga GL_BGR oraz GL_BGRA dla TGA - szybciej siê wczytuje
|
||||
GLuint ID;
|
||||
glGenTextures(1,&ID);
|
||||
glBindTexture(GL_TEXTURE_2D,ID);
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
|
||||
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
|
||||
if (filter>=0)
|
||||
SetFiltering(filter); //cyfra po % w nazwie
|
||||
else
|
||||
SetFiltering(bHasAlpha&&bDollar,bHash); //znaki #, $ i kana³ alfa w nazwie
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH,0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_ROWS,0);
|
||||
glPixelStorei(GL_UNPACK_SKIP_PIXELS,0);
|
||||
if (bHasAlpha || bHash || (filter==0))
|
||||
glTexImage2D(GL_TEXTURE_2D,0,(bHasAlpha?GL_RGBA:GL_RGB),width,height,0,bpp,GL_UNSIGNED_BYTE,buff);
|
||||
else
|
||||
gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGB,width,height,bpp,GL_UNSIGNED_BYTE,buff);
|
||||
return ID;
|
||||
}
|
||||
|
||||
void TTexturesManager::Free()
|
||||
{//usuniêcie wszyskich tekstur (bez usuwania struktury)
|
||||
for (Names::iterator iter=_names.begin();iter!=_names.end();iter++)
|
||||
glDeleteTextures(1,&(iter->second));
|
||||
}
|
||||
|
||||
std::string TTexturesManager::GetName(GLuint id)
|
||||
{//pobranie nazwy tekstury
|
||||
for (Names::iterator iter=_names.begin();iter!=_names.end();iter++)
|
||||
if (iter->second==id)
|
||||
return iter->first;
|
||||
return "";
|
||||
};
|
||||
#pragma package(smart_init)
|
||||
|
||||
58
Texture.h
Normal file
58
Texture.h
Normal file
@@ -0,0 +1,58 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef TextureH
|
||||
#define TextureH
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "opengl/glew.h"
|
||||
#include "usefull.h"
|
||||
|
||||
/*
|
||||
//Ra: miejsce umieszczenia tego jest deczko bezsensowne
|
||||
void __fastcall glDebug()
|
||||
{//logowanie b³êdów OpenGL
|
||||
GLenum err;
|
||||
if (Global::iErorrCounter==326) //tu wpisz o 1 mniej niz wartoœæ, przy której siê wy³o¿y³o
|
||||
Global::iErorrCounter=Global::iErorrCounter+0; //do zastawiania pu³apki przed b³êdnym kodem
|
||||
while ((err=glGetError())!=GL_NO_ERROR) //dalej jest pu³apka po wykonaniu b³êdnego kodu
|
||||
WriteLog("OpenGL error found: "+AnsiString(err)+", step:"+AnsiString(Global::iErorrCounter));
|
||||
++Global::iErorrCounter;
|
||||
};
|
||||
*/
|
||||
|
||||
class TTexturesManager
|
||||
{
|
||||
public:
|
||||
static void Init();
|
||||
static void Free();
|
||||
|
||||
static GLuint GetTextureID(char* dir,char* where,std::string name,int filter=-1);
|
||||
static bool GetAlpha(GLuint ID); //McZapkie-141203: czy tekstura ma polprzeroczystosc
|
||||
static std::string GetName(GLuint id);
|
||||
|
||||
private:
|
||||
typedef std::pair<GLuint, bool> AlphaValue;
|
||||
|
||||
typedef std::map<std::string, GLuint> Names;
|
||||
typedef std::map<GLuint, bool> Alphas;
|
||||
|
||||
static Names::iterator LoadFromFile(std::string name,int filter=-1);
|
||||
|
||||
static AlphaValue LoadBMP(std::string fileName);
|
||||
static AlphaValue LoadTEX(std::string fileName);
|
||||
static AlphaValue LoadTGA(std::string fileName,int filter=-1);
|
||||
static AlphaValue LoadDDS(std::string fileName,int filter=-1);
|
||||
|
||||
static void SetFiltering(int filter);
|
||||
static void SetFiltering(bool alpha, bool hash);
|
||||
static GLuint CreateTexture(char *buff,GLint bpp,int width,int height,bool bHasAlpha,bool bHash,bool bDollar=true,int filter=-1);
|
||||
|
||||
static Names _names;
|
||||
static Alphas _alphas;
|
||||
// std::list<TTexture> Textures;
|
||||
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
299
TextureDDS.cpp
Normal file
299
TextureDDS.cpp
Normal file
@@ -0,0 +1,299 @@
|
||||
#include "TextureDDS.h"
|
||||
|
||||
void DxtcReadColors(const GLubyte* Data, Color8888* result)
|
||||
{
|
||||
GLubyte r0, g0, b0, r1, g1, b1;
|
||||
|
||||
b0 = Data[0] & 0x1F;
|
||||
g0 = ((Data[0] & 0xE0) >> 5) | ((Data[1] & 0x7) << 3);
|
||||
r0 = (Data[1] & 0xF8) >> 3;
|
||||
|
||||
b1 = Data[2] & 0x1F;
|
||||
g1 = ((Data[2] & 0xE0) >> 5) | ((Data[3] & 0x7) << 3);
|
||||
r1 = (Data[3] & 0xF8) >> 3;
|
||||
|
||||
result[0].r = r0 << 3 | r0 >> 2;
|
||||
result[0].g = g0 << 2 | g0 >> 3;
|
||||
result[0].b = b0 << 3 | b0 >> 2;
|
||||
|
||||
result[1].r = r1 << 3 | r1 >> 2;
|
||||
result[1].g = g1 << 2 | g1 >> 3;
|
||||
result[1].b = b1 << 3 | b1 >> 2;
|
||||
};
|
||||
|
||||
void DxtcReadColor(GLushort Data, Color8888* Out)
|
||||
{
|
||||
GLubyte r, g, b;
|
||||
|
||||
b = Data & 0x1f;
|
||||
g = (Data & 0x7E0) >> 5;
|
||||
r = (Data & 0xF800) >> 11;
|
||||
|
||||
Out->r = r << 3 | r >> 2;
|
||||
Out->g = g << 2 | g >> 3;
|
||||
Out->b = b << 3 | r >> 2;
|
||||
};
|
||||
|
||||
void DecompressDXT1(DDS_IMAGE_DATA lImage, const GLubyte *lCompData, GLubyte *Data)
|
||||
{
|
||||
GLint x, y, i, j, k;
|
||||
GLuint Select;
|
||||
const GLubyte *Temp;
|
||||
Color8888 colours[4], *col;
|
||||
GLushort color_0, color_1;
|
||||
GLuint bitmask, Offset;
|
||||
|
||||
Temp = lCompData;
|
||||
colours[0].a = 0xFF;
|
||||
colours[1].a = 0xFF;
|
||||
colours[2].a = 0xFF;
|
||||
|
||||
for (y = 0; y < lImage.height; y += 4) {
|
||||
for (x = 0; x < lImage.width; x += 4) {
|
||||
color_0 = *((const GLushort*)Temp);
|
||||
color_1 = *((const GLushort*)(Temp + 2));
|
||||
|
||||
DxtcReadColor(color_0, colours);
|
||||
DxtcReadColor(color_1, colours + 1);
|
||||
bitmask = ((const GLuint*)Temp)[1];
|
||||
|
||||
Temp += 8;
|
||||
|
||||
if (color_0 > color_1) {
|
||||
// Four-color block: derive the other two colors.
|
||||
// 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3
|
||||
// These 2-bit codes correspond to the 2-bit fields
|
||||
// stored in the 64-bit block.
|
||||
colours[2].b = (2 * colours[0].b + colours[1].b + 1) / 3;
|
||||
colours[2].g = (2 * colours[0].g + colours[1].g + 1) / 3;
|
||||
colours[2].r = (2 * colours[0].r + colours[1].r + 1) / 3;
|
||||
|
||||
colours[3].b = (colours[0].b + 2 * colours[1].b + 1) / 3;
|
||||
colours[3].g = (colours[0].g + 2 * colours[1].g + 1) / 3;
|
||||
colours[3].r = (colours[0].r + 2 * colours[1].r + 1) / 3;
|
||||
colours[3].a = 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Three-color block: derive the other color.
|
||||
// 00 = color_0, 01 = color_1, 10 = color_2,
|
||||
// 11 = transparent.
|
||||
// These 2-bit codes correspond to the 2-bit fields
|
||||
// stored in the 64-bit block.
|
||||
colours[2].b = (colours[0].b + colours[1].b) / 2;
|
||||
colours[2].g = (colours[0].g + colours[1].g) / 2;
|
||||
colours[2].r = (colours[0].r + colours[1].r) / 2;
|
||||
|
||||
colours[3].b = (colours[0].b + 2 * colours[1].b + 1) / 3;
|
||||
colours[3].g = (colours[0].g + 2 * colours[1].g + 1) / 3;
|
||||
colours[3].r = (colours[0].r + 2 * colours[1].r + 1) / 3;
|
||||
colours[3].a = 0x00;
|
||||
}
|
||||
|
||||
for (j = 0, k = 0; j < 4; j++) {
|
||||
for (i = 0; i < 4; i++, k++) {
|
||||
Select = (bitmask & (0x03 << k*2)) >> k*2;
|
||||
col = &colours[Select];
|
||||
|
||||
if (((x + i) < lImage.width) && ((y + j) < lImage.height)) {
|
||||
Offset = (y + j) * lImage.width * lImage.components + (x + i) * lImage.components;
|
||||
Data[Offset + 0] = col->r;
|
||||
Data[Offset + 1] = col->g;
|
||||
Data[Offset + 2] = col->b;
|
||||
Data[Offset + 3] = col->a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DecompressDXT3(DDS_IMAGE_DATA lImage, const GLubyte *lCompData, GLubyte *Data)
|
||||
{
|
||||
const GLubyte* Temp = lCompData;
|
||||
|
||||
Color8888 colours[4], *col;
|
||||
GLuint bitmask, Offset;
|
||||
const GLubyte* alpha;
|
||||
|
||||
for (GLint y = 0; y < lImage.height; y += 4) {
|
||||
for (GLint x = 0; x < lImage.width; x += 4) {
|
||||
alpha = Temp;
|
||||
Temp += 8;
|
||||
DxtcReadColors(Temp, colours);
|
||||
bitmask = ((GLuint*)Temp)[1];
|
||||
|
||||
Temp += 8;
|
||||
|
||||
// Four-color block: derive the other two colors.
|
||||
// 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3
|
||||
// These 2-bit codes correspond to the 2-bit fields
|
||||
// stored in the 64-bit block.
|
||||
colours[2].b = (2 * colours[0].b + colours[1].b + 1) / 3;
|
||||
colours[2].g = (2 * colours[0].g + colours[1].g + 1) / 3;
|
||||
colours[2].r = (2 * colours[0].r + colours[1].r + 1) / 3;
|
||||
|
||||
colours[3].b = (colours[0].b + 2 * colours[1].b + 1) / 3;
|
||||
colours[3].g = (colours[0].g + 2 * colours[1].g + 1) / 3;
|
||||
colours[3].r = (colours[0].r + 2 * colours[1].r + 1) / 3;
|
||||
|
||||
GLuint k = 0;
|
||||
for (GLint j = 0; j < 4; j++) {
|
||||
for (GLint i = 0; i < 4; i++, k++) {
|
||||
GLuint Select = (bitmask & (0x03 << k*2)) >> k*2;
|
||||
col = &colours[Select];
|
||||
|
||||
if (((x + i) < lImage.width) && ((y + j) < lImage.height)) {
|
||||
Offset = (y + j) * lImage.width * lImage.components + (x + i) * lImage.components;
|
||||
Data[Offset + 0] = col->r;
|
||||
Data[Offset + 1] = col->g;
|
||||
Data[Offset + 2] = col->b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (GLint j = 0; j < 4; j++) {
|
||||
GLushort word = alpha[2*j] + 256*alpha[2*j+1];
|
||||
for (GLint i = 0; i < 4; i++) {
|
||||
if (((x + i) < lImage.width) && ((y + j) < lImage.height)) {
|
||||
Offset = (y + j) * lImage.width * lImage.components + (x + i) * lImage.components + 3;
|
||||
Data[Offset] = word & 0x0F;
|
||||
Data[Offset] = Data[Offset] | (Data[Offset] << 4);
|
||||
}
|
||||
word >>= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DecompressDXT5(DDS_IMAGE_DATA lImage, const GLubyte *lCompData, GLubyte *Data)
|
||||
{
|
||||
GLint x, y, z, i, j, k;
|
||||
GLuint Select;
|
||||
const GLubyte *Temp; //, r0, g0, b0, r1, g1, b1;
|
||||
Color8888 colours[4], *col;
|
||||
GLuint bitmask, Offset;
|
||||
GLubyte alphas[8];
|
||||
GLuint bits;
|
||||
|
||||
Temp = lCompData;
|
||||
|
||||
for (y = 0; y < lImage.height; y += 4) {
|
||||
for (x = 0; x < lImage.width; x += 4) {
|
||||
if (y >= lImage.height || x >= lImage.width)
|
||||
break;
|
||||
alphas[0] = Temp[0];
|
||||
alphas[1] = Temp[1];
|
||||
const GLubyte* alphamask = Temp + 2;
|
||||
Temp += 8;
|
||||
|
||||
DxtcReadColors(Temp, colours);
|
||||
bitmask = ((const GLuint*)Temp)[1];
|
||||
|
||||
Temp += 8;
|
||||
|
||||
// Four-color block: derive the other two colors.
|
||||
// 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3
|
||||
// These 2-bit codes correspond to the 2-bit fields
|
||||
// stored in the 64-bit block.
|
||||
colours[2].b = (2 * colours[0].b + colours[1].b + 1) / 3;
|
||||
colours[2].g = (2 * colours[0].g + colours[1].g + 1) / 3;
|
||||
colours[2].r = (2 * colours[0].r + colours[1].r + 1) / 3;
|
||||
|
||||
colours[3].b = (colours[0].b + 2 * colours[1].b + 1) / 3;
|
||||
colours[3].g = (colours[0].g + 2 * colours[1].g + 1) / 3;
|
||||
colours[3].r = (colours[0].r + 2 * colours[1].r + 1) / 3;
|
||||
|
||||
k = 0;
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (i = 0; i < 4; i++, k++) {
|
||||
|
||||
Select = (bitmask & (0x03 << k*2)) >> k*2;
|
||||
col = &colours[Select];
|
||||
|
||||
// only put pixels out < width or height
|
||||
if (((x + i) < lImage.width) && ((y + j) < lImage.height)) {
|
||||
Offset = (y + j) * lImage.width * lImage.components + (x + i) * lImage.components;
|
||||
Data[Offset + 0] = col->r;
|
||||
Data[Offset + 1] = col->g;
|
||||
Data[Offset + 2] = col->b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 8-alpha or 6-alpha block?
|
||||
if (alphas[0] > alphas[1]) {
|
||||
// 8-alpha block: derive the other six alphas.
|
||||
// Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
|
||||
alphas[2] = (6 * alphas[0] + 1 * alphas[1] + 3) / 7; // bit code 010
|
||||
alphas[3] = (5 * alphas[0] + 2 * alphas[1] + 3) / 7; // bit code 011
|
||||
alphas[4] = (4 * alphas[0] + 3 * alphas[1] + 3) / 7; // bit code 100
|
||||
alphas[5] = (3 * alphas[0] + 4 * alphas[1] + 3) / 7; // bit code 101
|
||||
alphas[6] = (2 * alphas[0] + 5 * alphas[1] + 3) / 7; // bit code 110
|
||||
alphas[7] = (1 * alphas[0] + 6 * alphas[1] + 3) / 7; // bit code 111
|
||||
}
|
||||
else {
|
||||
// 6-alpha block.
|
||||
// Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
|
||||
alphas[2] = (4 * alphas[0] + 1 * alphas[1] + 2) / 5; // Bit code 010
|
||||
alphas[3] = (3 * alphas[0] + 2 * alphas[1] + 2) / 5; // Bit code 011
|
||||
alphas[4] = (2 * alphas[0] + 3 * alphas[1] + 2) / 5; // Bit code 100
|
||||
alphas[5] = (1 * alphas[0] + 4 * alphas[1] + 2) / 5; // Bit code 101
|
||||
alphas[6] = 0x00; // Bit code 110
|
||||
alphas[7] = 0xFF; // Bit code 111
|
||||
}
|
||||
|
||||
// Note: Have to separate the next two loops,
|
||||
// it operates on a 6-byte system.
|
||||
|
||||
// First three bytes
|
||||
//bits = *((ILint*)alphamask);
|
||||
bits = (alphamask[0]) | (alphamask[1] << 8) | (alphamask[2] << 16);
|
||||
for (j = 0; j < 2; j++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
// only put pixels out < width or height
|
||||
if (((x + i) < lImage.width) && ((y + j) < lImage.height)) {
|
||||
Offset = (y + j) * lImage.width * lImage.components + (x + i) * lImage.components + 3;
|
||||
Data[Offset] = alphas[bits & 0x07];
|
||||
}
|
||||
bits >>= 3;
|
||||
}
|
||||
}
|
||||
|
||||
// Last three bytes
|
||||
//bits = *((ILint*)&alphamask[3]);
|
||||
bits = (alphamask[3]) | (alphamask[4] << 8) | (alphamask[5] << 16);
|
||||
for (j = 2; j < 4; j++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
// only put pixels out < width or height
|
||||
if (((x + i) < lImage.width) && ((y + j) < lImage.height)) {
|
||||
Offset = (y + j) * lImage.width * lImage.components + (x + i) * lImage.components + 3;
|
||||
Data[Offset] = alphas[bits & 0x07];
|
||||
}
|
||||
bits >>= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DecompressDXT(DDS_IMAGE_DATA lImage, const GLubyte *lCompData, GLubyte *Data)
|
||||
{
|
||||
switch(lImage.format)
|
||||
{
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||
DecompressDXT1(lImage, lCompData, Data);
|
||||
break;
|
||||
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||
DecompressDXT3(lImage, lCompData, Data);
|
||||
break;
|
||||
|
||||
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||
DecompressDXT5(lImage, lCompData, Data);
|
||||
break;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
30
TextureDDS.h
Normal file
30
TextureDDS.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef TEXTURE_DDS_H
|
||||
#define TEXTURE_DDS_H 1
|
||||
|
||||
#include "opengl/glew.h"
|
||||
|
||||
#pragma hdrstop
|
||||
|
||||
struct Color8888
|
||||
{
|
||||
GLubyte r; // change the order of names to change the
|
||||
GLubyte g; // order of the output ARGB or BGRA, etc...
|
||||
GLubyte b; // Last one is MSB, 1st is LSB.
|
||||
GLubyte a;
|
||||
};
|
||||
|
||||
struct DDS_IMAGE_DATA
|
||||
{
|
||||
GLsizei width;
|
||||
GLsizei height;
|
||||
GLint components;
|
||||
GLenum format;
|
||||
GLuint blockSize;
|
||||
int numMipMaps;
|
||||
GLubyte *pixels;
|
||||
};
|
||||
|
||||
void DecompressDXT(DDS_IMAGE_DATA lImage, const GLubyte *lCompData, GLubyte *Data);
|
||||
|
||||
#endif
|
||||
|
||||
119
Timer.cpp
Normal file
119
Timer.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Timer.h"
|
||||
#include "Globals.h"
|
||||
|
||||
namespace Timer {
|
||||
|
||||
double DeltaTime,DeltaRenderTime;
|
||||
double fFPS =0.0f;
|
||||
double fLastTime =0.0f;
|
||||
DWORD dwFrames =0L;
|
||||
double fSimulationTime=0;
|
||||
double fSoundTimer=0;
|
||||
double fSinceStart=0;
|
||||
|
||||
|
||||
|
||||
double __fastcall GetTime()
|
||||
{
|
||||
return fSimulationTime;
|
||||
}
|
||||
|
||||
double __fastcall GetDeltaTime()
|
||||
{//czas symulacji (stoi gdy pauza)
|
||||
return DeltaTime;
|
||||
}
|
||||
|
||||
double __fastcall GetDeltaRenderTime()
|
||||
{//czas renderowania (do poruszania siê)
|
||||
return DeltaRenderTime;
|
||||
}
|
||||
|
||||
double __fastcall GetfSinceStart()
|
||||
{
|
||||
return fSinceStart;
|
||||
}
|
||||
|
||||
void __fastcall SetDeltaTime(double t)
|
||||
{
|
||||
DeltaTime= t;
|
||||
}
|
||||
|
||||
double __fastcall GetSimulationTime()
|
||||
{
|
||||
return fSimulationTime;
|
||||
}
|
||||
|
||||
void __fastcall SetSimulationTime(double t)
|
||||
{
|
||||
fSimulationTime=t;
|
||||
}
|
||||
|
||||
bool __fastcall GetSoundTimer()
|
||||
{//Ra: byæ mo¿e, by dŸwiêki nie modyfikowa³y siê zbyt czêsto, po 0.1s zeruje siê ten licznik
|
||||
return (fSoundTimer==0.0f);
|
||||
}
|
||||
|
||||
|
||||
double __fastcall GetFPS()
|
||||
{
|
||||
return fFPS;
|
||||
}
|
||||
|
||||
void __fastcall ResetTimers()
|
||||
{
|
||||
//double CurrentTime=
|
||||
GetTickCount();
|
||||
DeltaTime=0.1;
|
||||
DeltaRenderTime=0;
|
||||
fSoundTimer=0;
|
||||
};
|
||||
|
||||
LONGLONG fr,count,oldCount;
|
||||
//LARGE_INTEGER fr,count;
|
||||
void __fastcall UpdateTimers(bool pause)
|
||||
{
|
||||
QueryPerformanceFrequency((LARGE_INTEGER*)&fr);
|
||||
QueryPerformanceCounter((LARGE_INTEGER*)&count);
|
||||
DeltaRenderTime=double(count-oldCount)/double(fr);
|
||||
if (!pause)
|
||||
{DeltaTime=Global::fTimeSpeed*DeltaRenderTime;
|
||||
fSoundTimer+=DeltaTime;
|
||||
if (fSoundTimer>0.1) fSoundTimer=0;
|
||||
/*
|
||||
double CurrentTime= double(count)/double(fr);//GetTickCount();
|
||||
DeltaTime= (CurrentTime-OldTime);
|
||||
OldTime= CurrentTime;
|
||||
*/
|
||||
if (DeltaTime>1) DeltaTime=1;
|
||||
}
|
||||
else
|
||||
DeltaTime=0; //wszystko stoi, bo czas nie p³ynie
|
||||
oldCount=count;
|
||||
|
||||
// Keep track of the time lapse and frame count
|
||||
double fTime=GetTickCount()*0.001f; // Get current time in seconds
|
||||
++dwFrames; //licznik ramek
|
||||
//update the frame rate once per second
|
||||
if (fTime-fLastTime>1.0f)
|
||||
{
|
||||
fFPS =dwFrames/(fTime-fLastTime);
|
||||
fLastTime=fTime;
|
||||
dwFrames =0L;
|
||||
}
|
||||
fSimulationTime+=DeltaTime;
|
||||
};
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
|
||||
33
Timer.h
Normal file
33
Timer.h
Normal file
@@ -0,0 +1,33 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef TimerH
|
||||
#define TimerH
|
||||
|
||||
namespace Timer {
|
||||
|
||||
|
||||
double __fastcall GetTime();
|
||||
|
||||
double __fastcall GetDeltaTime();
|
||||
double __fastcall GetDeltaRenderTime();
|
||||
|
||||
double __fastcall GetfSinceStart();
|
||||
|
||||
void __fastcall SetDeltaTime(double v);
|
||||
|
||||
double __fastcall GetSimulationTime();
|
||||
|
||||
void __fastcall SetSimulationTime(double v);
|
||||
|
||||
bool __fastcall GetSoundTimer();
|
||||
|
||||
double __fastcall GetFPS();
|
||||
|
||||
void __fastcall ResetTimers();
|
||||
|
||||
void __fastcall UpdateTimers(bool pause);
|
||||
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
224
Track.h
Normal file
224
Track.h
Normal file
@@ -0,0 +1,224 @@
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef TrackH
|
||||
#define TrackH
|
||||
|
||||
#include "Segment.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "opengl/glew.h"
|
||||
#include <system.hpp>
|
||||
#include "Classes.h"
|
||||
|
||||
|
||||
class TEvent;
|
||||
|
||||
typedef enum { tt_Unknown, tt_Normal, tt_Switch, tt_Table, tt_Cross, tt_Tributary } TTrackType;
|
||||
//McZapkie-100502
|
||||
typedef enum {e_unknown=-1, e_flat=0, e_mountains, e_canyon, e_tunnel, e_bridge, e_bank} TEnvironmentType;
|
||||
//Ra: opracować alternatywny system cieni/świateł z definiowaniem koloru oświetlenia w halach
|
||||
|
||||
class TTrack;
|
||||
class TGroundNode;
|
||||
class TSubRect;
|
||||
class TTraction;
|
||||
|
||||
class TSwitchExtension
|
||||
{//dodatkowe dane do toru, który jest zwrotnicą
|
||||
public:
|
||||
__fastcall TSwitchExtension(TTrack *owner,int what);
|
||||
__fastcall ~TSwitchExtension();
|
||||
TSegment *Segments[6]; //dwa tory od punktu 1, pozostałe dwa od 2? Ra 140101: 6 połączeń dla skrzyżowań
|
||||
//TTrack *trNear[4]; //tory dołączone do punktów 1, 2, 3 i 4
|
||||
//dotychczasowe [2]+[2] wskaźniki zamienić na nowe [4]
|
||||
TTrack *pNexts[2]; //tory dołączone do punktów 2 i 4
|
||||
TTrack *pPrevs[2]; //tory dołączone do punktów 1 i 3
|
||||
int iNextDirection[2]; //to też z [2]+[2] przerobić na [4]
|
||||
int iPrevDirection[2];
|
||||
int CurrentIndex; //dla zwrotnicy
|
||||
double fOffset,fDesiredOffset; //aktualne i docelowe położenie napędu iglic
|
||||
double fOffsetSpeed; //prędkość liniowa ruchu iglic
|
||||
double fOffsetDelay; //opóźnienie ruchu drugiej iglicy względem pierwszej
|
||||
union
|
||||
{
|
||||
struct
|
||||
{//zmienne potrzebne tylko dla zwrotnicy
|
||||
double fOffset1,fOffset2; //przesunięcia iglic - 0=na wprost
|
||||
bool RightSwitch; //czy zwrotnica w prawo
|
||||
};
|
||||
struct
|
||||
{//zmienne potrzebne tylko dla obrotnicy/przesuwnicy
|
||||
TGroundNode *pMyNode; //dla obrotnicy do wtórnego podłączania torów
|
||||
//TAnimContainer *pAnim; //animator modelu dla obrotnicy
|
||||
TAnimModel *pModel; //na razie model
|
||||
};
|
||||
struct
|
||||
{//zmienne dla skrzyżowania
|
||||
vector3 *vPoints; //tablica wierzchołków nawierzchni, generowana przez pobocze
|
||||
int iPoints; //liczba faktycznie użytych wierzchołków nawierzchni
|
||||
bool bPoints; //czy utworzone?
|
||||
int iRoads; //ile dróg się spotyka?
|
||||
};
|
||||
};
|
||||
bool bMovement; //czy w trakcie animacji
|
||||
int iLeftVBO,iRightVBO; //indeksy iglic w VBO
|
||||
TSubRect *pOwner; //sektor, któremu trzeba zgłosić animację
|
||||
TTrack *pNextAnim; //następny tor do animowania
|
||||
TEvent *evPlus,*evMinus; //zdarzenia sygnalizacji rozprucia
|
||||
float fVelocity; //maksymalne ograniczenie prędkości (ustawianej eventem)
|
||||
vector3 vTrans; //docelowa translacja przesuwnicy
|
||||
private:
|
||||
};
|
||||
|
||||
const int iMaxNumDynamics=40; //McZapkie-100303
|
||||
|
||||
class TIsolated
|
||||
{//obiekt zbierający zajętości z kilku odcinków
|
||||
int iAxles; //ilość osi na odcinkach obsługiwanych przez obiekt
|
||||
TIsolated *pNext; //odcinki izolowane są trzymane w postaci listy jednikierunkowej
|
||||
static TIsolated *pRoot; //początek listy
|
||||
public:
|
||||
AnsiString asName; //nazwa obiektu, baza do nazw eventów
|
||||
TEvent *evBusy; //zdarzenie wyzwalane po zajęciu grupy
|
||||
TEvent *evFree; //zdarzenie wyzwalane po całkowitym zwolnieniu zajętości grupy
|
||||
TMemCell *pMemCell; //automatyczna komórka pamięci, która współpracuje z odcinkiem izolowanym
|
||||
__fastcall TIsolated();
|
||||
__fastcall TIsolated(const AnsiString &n,TIsolated *i);
|
||||
__fastcall ~TIsolated();
|
||||
static TIsolated* __fastcall Find(const AnsiString &n); //znalezienie obiektu albo utworzenie nowego
|
||||
void __fastcall Modify(int i,TDynamicObject *o); //dodanie lub odjęcie osi
|
||||
bool __fastcall Busy() { return (iAxles>0); };
|
||||
static TIsolated* __fastcall Root() { return (pRoot); };
|
||||
TIsolated* __fastcall Next() { return (pNext); };
|
||||
};
|
||||
|
||||
class TTrack : public Resource
|
||||
{//trajektoria ruchu - opakowanie
|
||||
private:
|
||||
TSwitchExtension *SwitchExtension; //dodatkowe dane do toru, który jest zwrotnicą
|
||||
TSegment *Segment;
|
||||
TTrack *trNext; //odcinek od strony punktu 2 - to powinno być w segmencie
|
||||
TTrack *trPrev; //odcinek od strony punktu 1
|
||||
//McZapkie-070402: dodalem zmienne opisujace rozmiary tekstur
|
||||
GLuint TextureID1; //tekstura szyn albo nawierzchni
|
||||
GLuint TextureID2; //tekstura automatycznej podsypki albo pobocza
|
||||
float fTexLength; //długość powtarzania tekstury w metrach
|
||||
float fTexRatio1; //proporcja rozmiarów tekstury dla nawierzchni drogi
|
||||
float fTexRatio2; //proporcja rozmiarów tekstury dla chodnika
|
||||
float fTexHeight1; //wysokość brzegu względem trajektorii
|
||||
float fTexWidth; //szerokość boku
|
||||
float fTexSlope;
|
||||
double fRadiusTable[2]; //dwa promienie, drugi dla zwrotnicy
|
||||
int iTrapezoid; //0-standard, 1-przechyłka, 2-trapez, 3-oba
|
||||
GLuint DisplayListID;
|
||||
TIsolated *pIsolated; //obwód izolowany obsługujący zajęcia/zwolnienia grupy torów
|
||||
TGroundNode *pMyNode; //Ra: proteza, żeby tor znał swoją nazwę TODO: odziedziczyć TTrack z TGroundNode
|
||||
public:
|
||||
int iNumDynamics;
|
||||
TDynamicObject *Dynamics[iMaxNumDynamics];
|
||||
int iEvents; //Ra: flaga informująca o obecności eventów
|
||||
TEvent *evEventall0; //McZapkie-140302: wyzwalany gdy pojazd stoi
|
||||
TEvent *evEventall1;
|
||||
TEvent *evEventall2;
|
||||
TEvent *evEvent0; //McZapkie-280503: wyzwalany tylko gdy headdriver
|
||||
TEvent *evEvent1;
|
||||
TEvent *evEvent2;
|
||||
AnsiString asEventall0Name; //nazwy eventów
|
||||
AnsiString asEventall1Name;
|
||||
AnsiString asEventall2Name;
|
||||
AnsiString asEvent0Name;
|
||||
AnsiString asEvent1Name;
|
||||
AnsiString asEvent2Name;
|
||||
int iNextDirection; //0:Point1, 1:Point2, 3:do odchylonego na zwrotnicy
|
||||
int iPrevDirection;
|
||||
TTrackType eType;
|
||||
int iCategoryFlag; //0x100 - usuwanie pojazów
|
||||
float fTrackWidth; //szerokość w punkcie 1
|
||||
float fTrackWidth2; //szerokość w punkcie 2 (głównie drogi i rzeki)
|
||||
float fFriction; //współczynnik tarcia
|
||||
float fSoundDistance;
|
||||
int iQualityFlag;
|
||||
int iDamageFlag;
|
||||
TEnvironmentType eEnvironment; //dźwięk i oświetlenie
|
||||
bool bVisible; //czy rysowany
|
||||
int iAction; //czy modyfikowany eventami (specjalna obsługa przy skanowaniu)
|
||||
float fOverhead; //informacja o stanie sieci: 0-jazda bezprądowa, >0-z opuszczonym i ograniczeniem prędkości
|
||||
private:
|
||||
double fVelocity; //prędkość dla AI (powyżej rośnie prawdopowobieństwo wykolejenia)
|
||||
public:
|
||||
//McZapkie-100502:
|
||||
double fTrackLength; //długość z wpisu, nigdzie nie używana
|
||||
double fRadius; //promień, dla zwrotnicy kopiowany z tabeli
|
||||
bool ScannedFlag; //McZapkie: do zaznaczania kolorem torów skanowanych przez AI
|
||||
TTraction *hvOverhead; //drut zasilający do szybkiego znalezienia (nie używany)
|
||||
TGroundNode *nFouling[2]; //współrzędne ukresu albo oporu kozła
|
||||
TTrack *trColides; //tor kolizyjny, na którym trzeba sprawdzać pojazdy pod kątem zderzenia
|
||||
|
||||
__fastcall TTrack(TGroundNode *g);
|
||||
__fastcall ~TTrack();
|
||||
void __fastcall Init();
|
||||
static TTrack* __fastcall Create400m(int what,double dx);
|
||||
TTrack* __fastcall NullCreate(int dir);
|
||||
inline bool __fastcall IsEmpty() { return (iNumDynamics<=0); };
|
||||
void __fastcall ConnectPrevPrev(TTrack *pNewPrev,int typ);
|
||||
void __fastcall ConnectPrevNext(TTrack *pNewPrev,int typ);
|
||||
void __fastcall ConnectNextPrev(TTrack *pNewNext,int typ);
|
||||
void __fastcall ConnectNextNext(TTrack *pNewNext,int typ);
|
||||
inline double __fastcall Length() { return Segment->GetLength(); };
|
||||
inline TSegment* __fastcall CurrentSegment() { return Segment; };
|
||||
inline TTrack* __fastcall CurrentNext() {return (trNext);};
|
||||
inline TTrack* __fastcall CurrentPrev() {return (trPrev);};
|
||||
TTrack* __fastcall Neightbour(int s,double &d);
|
||||
bool __fastcall SetConnections(int i);
|
||||
bool __fastcall Switch(int i,double t=-1.0,double d=-1.0);
|
||||
bool __fastcall SwitchForced(int i,TDynamicObject *o);
|
||||
int __fastcall CrossSegment(int from,int into);
|
||||
inline int __fastcall GetSwitchState() { return (SwitchExtension?SwitchExtension->CurrentIndex:-1); };
|
||||
void __fastcall Load(cParser *parser, vector3 pOrigin,AnsiString name);
|
||||
bool __fastcall AssignEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2);
|
||||
bool __fastcall AssignallEvents(TEvent *NewEvent0, TEvent *NewEvent1, TEvent *NewEvent2);
|
||||
bool __fastcall AssignForcedEvents(TEvent *NewEventPlus, TEvent *NewEventMinus);
|
||||
bool __fastcall CheckDynamicObject(TDynamicObject *Dynamic);
|
||||
bool __fastcall AddDynamicObject(TDynamicObject *Dynamic);
|
||||
bool __fastcall RemoveDynamicObject(TDynamicObject *Dynamic);
|
||||
void __fastcall MoveMe(vector3 pPosition);
|
||||
|
||||
void Release();
|
||||
void __fastcall Compile(GLuint tex=0);
|
||||
|
||||
void __fastcall Render(); //renderowanie z Display Lists
|
||||
int __fastcall RaArrayPrepare(); //zliczanie rozmiaru dla VBO sektroa
|
||||
void __fastcall RaArrayFill(CVertNormTex *Vert,const CVertNormTex *Start); //wypełnianie VBO
|
||||
void __fastcall RaRenderVBO(int iPtr); //renderowanie z VBO sektora
|
||||
void __fastcall RenderDyn(); //renderowanie nieprzezroczystych pojazdów (oba tryby)
|
||||
void __fastcall RenderDynAlpha(); //renderowanie przezroczystych pojazdów (oba tryby)
|
||||
void __fastcall RenderDynSounds(); //odtwarzanie dźwięków pojazdów jest niezależne od ich wyświetlania
|
||||
|
||||
void __fastcall RaOwnerSet(TSubRect *o)
|
||||
{if (SwitchExtension) SwitchExtension->pOwner=o;};
|
||||
bool __fastcall InMovement(); //czy w trakcie animacji?
|
||||
void __fastcall RaAssign(TGroundNode *gn,TAnimContainer *ac);
|
||||
void __fastcall RaAssign(TGroundNode *gn,TAnimModel *am,TEvent *done,TEvent *joined);
|
||||
void __fastcall RaAnimListAdd(TTrack *t);
|
||||
TTrack* __fastcall RaAnimate();
|
||||
|
||||
void __fastcall RadioStop();
|
||||
void __fastcall AxleCounter(int i,TDynamicObject *o)
|
||||
{if (pIsolated) pIsolated->Modify(i,o);}; //dodanie lub odjęcie osi
|
||||
AnsiString __fastcall IsolatedName();
|
||||
bool __fastcall IsolatedEventsAssign(TEvent *busy,TEvent *free);
|
||||
double __fastcall WidthTotal();
|
||||
GLuint TextureGet(int i) {return i?TextureID1:TextureID2;};
|
||||
bool __fastcall IsGroupable();
|
||||
int __fastcall TestPoint(vector3 *Point);
|
||||
void __fastcall MovedUp1(double dh);
|
||||
AnsiString __fastcall NameGet();
|
||||
void __fastcall VelocitySet(float v);
|
||||
float __fastcall VelocityGet();
|
||||
void __fastcall ConnectionsLog();
|
||||
private:
|
||||
void __fastcall EnvironmentSet();
|
||||
void __fastcall EnvironmentReset();
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
624
Traction.cpp
Normal file
624
Traction.cpp
Normal file
@@ -0,0 +1,624 @@
|
||||
//---------------------------------------------------------------------------
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
||||
|
||||
*/
|
||||
|
||||
#include "system.hpp"
|
||||
#include "classes.hpp"
|
||||
#pragma hdrstop
|
||||
|
||||
#include "Traction.h"
|
||||
#include "mctools.hpp"
|
||||
#include "Globals.h"
|
||||
#include "Usefull.h"
|
||||
#include "TractionPower.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#pragma package(smart_init)
|
||||
/*
|
||||
|
||||
=== Koncepcja dwustronnego zasilania sekcji sieci trakcyjnej, Ra 2014-02 ===
|
||||
0. Każde przęsło sieci może mieć wpisaną nazwę zasilacza, a także napięcie
|
||||
nominalne i maksymalny prąd, które stanowią redundancję do danych zasilacza.
|
||||
Rezystancja może się zmieniać, materiał i grubość drutu powinny być wspólny
|
||||
dla segmentu. Podanie punktów umożliwia łączenie przęseł w listy dwukierunkowe,
|
||||
co usprawnia wyszukiwania kolejnych przeseł podczas jazdy. Dla bieżni wspólnej
|
||||
powinna być podana nazwa innego przęsła w parametrze "parallel". Wskaźniki
|
||||
na przęsła bieżni wspólnej mają być układane w jednokierunkowy pierścień.
|
||||
1. Problemem jest ustalenie topologii sekcji dla linii dwutorowych. Nad każdym
|
||||
torem powinna znajdować się oddzielna sekcja sieci, aby mogła zostać odłączona
|
||||
w przypadku zwarcia. Sekcje nad równoległymi torami są również łączone
|
||||
równolegle przez kabiny sekcyjne, co zmniejsza płynące prądy i spadki napięć.
|
||||
2. Drugim zagadnieniem jest zasilanie sekcji jednocześnie z dwóch stron, czyli
|
||||
sekcja musi mieć swoją nazwę oraz wskazanie dwóch zasilaczy ze wskazaniem
|
||||
geograficznym ich położenia. Dodatkową trudnością jest brak połączenia
|
||||
pomiędzy segmentami naprężania. Podsumowując, każdy segment naprężania powinien
|
||||
mieć przypisanie do sekcji zasilania, a dodatkowo skrajne segmenty powinny
|
||||
wskazywać dwa różne zasilacze.
|
||||
3. Zasilaczem sieci może być podstacja, która w wersji 3kV powinna generować
|
||||
pod obciążeniem napięcie maksymalne rzędu 3600V, a spadek napięcia następuje
|
||||
na jej rezystancji wewnętrznej oraz na przewodach trakcyjnych. Zasilaczem może
|
||||
być również kabina sekcyjna, która jest zasilana z podstacji poprzez przewody
|
||||
trakcyjne.
|
||||
4. Dla uproszczenia można przyjąć, że zasilanie pojazdu odbywać się będzie z
|
||||
dwóch sąsiednich podstacji, pomiędzy którymi może być dowolna liczba kabin
|
||||
sekcyjnych. W przypadku wyłączenia jednej z tych podstacji, zasilanie może
|
||||
być pobierane z kolejnej. Łącznie należy rozważać 4 najbliższe podstacje,
|
||||
przy czym do obliczeń można przyjmować 2 z nich.
|
||||
5. Przęsła sieci są łączone w listę dwukierunkową, więc wystarczy nazwę
|
||||
sekcji wpisać w jednym z nich, wpisanie w każdym nie przeszkadza.
|
||||
Alternatywnym sposobem łączenia segmentów naprężania może być wpisywanie
|
||||
nazw przęseł jako "parallel", co może być uciążliwe dla autorów scenerii.
|
||||
W skrajnych przęsłach należałoby dodatkowo wpisać nazwę zasilacza, będzie
|
||||
to jednocześnie wskazanie przęsła, do którego podłączone są przewody
|
||||
zasilające. Konieczne jest odróżnienie nazwy sekcji od nazwy zasilacza, co
|
||||
można uzyskać różnicując ich nazwy albo np. specyficznie ustawiając wartość
|
||||
prądu albo napięcia przęsła.
|
||||
6. Jeśli dany segment naprężania jest wspólny dla dwóch sekcji zasilania,
|
||||
to jedno z przęseł musi mieć nazwę "*" (gwiazdka), co będzie oznaczało, że
|
||||
ma zamontowany izolator. Dla uzyskania efektów typu łuk elektryczny, należało
|
||||
by wskazać położenie izolatora i jego długość (ew. typ).
|
||||
7. Również w parametrach zasilacza należało by określić, czy jest podstacją,
|
||||
czy jedynie kabiną sekcyjną. Różnić się one będą fizyką działania.
|
||||
8. Dla zbudowanej topologii sekcji i zasilaczy należało by zbudować dynamiczny
|
||||
schemat zastępczy. Dynamika polega na wyłączaniu sekcji ze zwarciem oraz
|
||||
przeciążonych podstacji. Musi być też możliwość wyłączenia sekcji albo
|
||||
podstacji za pomocą eventu.
|
||||
9. Dla każdej sekcji musi być tworzony obiekt, wskazujący na podstacje
|
||||
zasilające na końcach, stan włączenia, zwarcia, przepięcia. Do tego obiektu
|
||||
musi wskazywać każde przęsło z aktywnym zasilaniem.
|
||||
|
||||
z.1 z.2 z.3
|
||||
-=-a---1*1---c-=---c---=-c--2*2--e---=---e-3-*-3--g-=-
|
||||
-=-b---1*1---d-=---d---=-d--2*2--f---=---e-3-*-3--h-=-
|
||||
|
||||
nazwy sekcji (@): a,b,c,d,e,f,g,h
|
||||
nazwy zasilaczy (#): 1,2,3
|
||||
przęsło z izolatorem: *
|
||||
przęsła bez wskazania nazwy sekcji/zasilacza: -
|
||||
segment napręzania: =-x-=
|
||||
segment naprężania z izolatorem: =---@---#*#---@---=
|
||||
segment naprężania bez izolatora: =--------@------=
|
||||
|
||||
Obecnie brak nazwy sekcji nie jest akceptowany i każde przęsło musi mieć wpisaną
|
||||
jawnie nazwę sekcji, ewentualnie nazwę zasilacza (zostanie zastąpiona wskazaniem
|
||||
sekcji z sąsiedniego przęsła).
|
||||
*/
|
||||
|
||||
|
||||
TTraction::TTraction()
|
||||
{
|
||||
pPoint1=pPoint2=pPoint3=pPoint4=vector3(0,0,0);
|
||||
//vFront=vector3(0,0,1);
|
||||
//vUp=vector3(0,1,0);
|
||||
//vLeft=vector3(1,0,0);
|
||||
fHeightDifference=0;
|
||||
iNumSections=0;
|
||||
iLines=0;
|
||||
// dwFlags= 0;
|
||||
Wires=2;
|
||||
// fU=fR= 0;
|
||||
uiDisplayList=0;
|
||||
asPowerSupplyName="";
|
||||
// mdPole= NULL;
|
||||
// ReplacableSkinID= 0;
|
||||
hvNext[0]=hvNext[1]=NULL;
|
||||
iLast=1; //że niby ostatni drut
|
||||
psPowered=psPower[0]=psPower[1]=NULL; //na początku zasilanie nie podłączone
|
||||
psSection=NULL; //na początku nie podłączone
|
||||
hvParallel=NULL; //normalnie brak bieżni wspólnej
|
||||
fResistance[0]=fResistance[1]=-1.0; //trzeba dopiero policzyć
|
||||
iTries=0; //ile razy próbować podłączyć, ustawiane później
|
||||
}
|
||||
|
||||
TTraction::~TTraction()
|
||||
{
|
||||
if (!Global::bUseVBO)
|
||||
glDeleteLists(uiDisplayList,1);
|
||||
}
|
||||
|
||||
void __fastcall TTraction::Optimize()
|
||||
{
|
||||
if (Global::bUseVBO) return;
|
||||
uiDisplayList=glGenLists(1);
|
||||
glNewList(uiDisplayList,GL_COMPILE);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
// glColor3ub(0,0,0); McZapkie: to do render
|
||||
|
||||
// glPushMatrix();
|
||||
// glTranslatef(pPosition.x,pPosition.y,pPosition.z);
|
||||
|
||||
if (Wires!=0)
|
||||
{
|
||||
//Dlugosc odcinka trakcji 'Winger
|
||||
double ddp=hypot(pPoint2.x-pPoint1.x,pPoint2.z-pPoint1.z);
|
||||
|
||||
if (Wires==2) WireOffset=0;
|
||||
//Przewoz jezdny 1 'Marcin
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(pPoint1.x-(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset,pPoint1.y,pPoint1.z-(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset);
|
||||
glVertex3f(pPoint2.x-(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset,pPoint2.y,pPoint2.z-(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset);
|
||||
glEnd();
|
||||
//Nie wiem co 'Marcin
|
||||
vector3 pt1,pt2,pt3,pt4,v1,v2;
|
||||
v1= pPoint4-pPoint3;
|
||||
v2= pPoint2-pPoint1;
|
||||
float step= 0;
|
||||
if (iNumSections>0)
|
||||
step= 1.0f/(float)iNumSections;
|
||||
float f= step;
|
||||
float mid= 0.5;
|
||||
float t;
|
||||
|
||||
//Przewod nosny 'Marcin
|
||||
if (Wires != 1)
|
||||
{
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(pPoint3.x,pPoint3.y,pPoint3.z);
|
||||
for (int i=0; i<iNumSections-1; i++)
|
||||
{
|
||||
pt3= pPoint3+v1*f;
|
||||
t= (1-fabs(f-mid)*2);
|
||||
if ((Wires<4)||((i!=0)&&(i!=iNumSections-2)))
|
||||
glVertex3f(pt3.x,pt3.y-sqrt(t)*fHeightDifference,pt3.z);
|
||||
f+= step;
|
||||
}
|
||||
glVertex3f(pPoint4.x,pPoint4.y,pPoint4.z);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
//Drugi przewod jezdny 'Winger
|
||||
if (Wires > 2)
|
||||
{
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(pPoint1.x+(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset,pPoint1.y,pPoint1.z+(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset);
|
||||
glVertex3f(pPoint2.x+(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset,pPoint2.y,pPoint2.z+(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
f= step;
|
||||
|
||||
if (Wires == 4)
|
||||
{
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(pPoint3.x,pPoint3.y-0.65f*fHeightDifference,pPoint3.z);
|
||||
for (int i=0; i<iNumSections-1; i++)
|
||||
{
|
||||
pt3= pPoint3+v1*f;
|
||||
t= (1-fabs(f-mid)*2);
|
||||
glVertex3f(pt3.x,pt3.y-sqrt(t)*fHeightDifference-((i==0)||(i==iNumSections-2)?0.25f*fHeightDifference:+0.05),pt3.z);
|
||||
f+= step;
|
||||
}
|
||||
glVertex3f(pPoint4.x,pPoint4.y-0.65f*fHeightDifference,pPoint4.z);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
f= step;
|
||||
|
||||
//Przewody pionowe (wieszaki) 'Marcin, poprawki na 2 przewody jezdne 'Winger
|
||||
if (Wires != 1)
|
||||
{
|
||||
glBegin(GL_LINES);
|
||||
for (int i=0; i<iNumSections-1; i++)
|
||||
{
|
||||
float flo,flo1;
|
||||
flo=(Wires==4?0.25f*fHeightDifference:0);
|
||||
flo1=(Wires==4?+0.05:0);
|
||||
pt3= pPoint3+v1*f;
|
||||
pt4= pPoint1+v2*f;
|
||||
t= (1-fabs(f-mid)*2);
|
||||
if ((i%2) == 0)
|
||||
{
|
||||
glVertex3f(pt3.x,pt3.y-sqrt(t)*fHeightDifference-((i==0)||(i==iNumSections-2)?flo:flo1),pt3.z);
|
||||
glVertex3f(pt4.x-(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset,pt4.y,pt4.z-(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
glVertex3f(pt3.x,pt3.y-sqrt(t)*fHeightDifference-((i==0)||(i==iNumSections-2)?flo:flo1),pt3.z);
|
||||
glVertex3f(pt4.x+(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset,pt4.y,pt4.z+(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset);
|
||||
}
|
||||
if((Wires==4)&&((i==1)||(i==iNumSections-3)))
|
||||
{
|
||||
glVertex3f(pt3.x,pt3.y-sqrt(t)*fHeightDifference-0.05,pt3.z);
|
||||
glVertex3f(pt3.x,pt3.y-sqrt(t)*fHeightDifference,pt3.z);
|
||||
}
|
||||
//endif;
|
||||
f+= step;
|
||||
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
glEndList();
|
||||
}
|
||||
}
|
||||
/*
|
||||
void __fastcall TTraction::InitCenter(vector3 Angles, vector3 pOrigin)
|
||||
{
|
||||
pPosition= (pPoint2+pPoint1)*0.5f;
|
||||
fSquaredRadius= SquareMagnitude((pPoint2-pPoint1)*0.5f);
|
||||
} */
|
||||
|
||||
void __fastcall TTraction::RenderDL(float mgn) //McZapkie: mgn to odleglosc od obserwatora
|
||||
{
|
||||
//McZapkie: ustalanie przezroczystosci i koloru linii:
|
||||
if (Wires!=0 && !TestFlag(DamageFlag,128)) //rysuj jesli sa druty i nie zerwana
|
||||
{
|
||||
//glDisable(GL_LIGHTING); //aby nie używało wektorów normalnych do kolorowania
|
||||
glColor4f(0,0,0,1); //jak nieznany kolor to czarne nieprzezroczyste
|
||||
if (!Global::bSmoothTraction)
|
||||
glDisable(GL_LINE_SMOOTH); //na liniach kiepsko wygląda - robi gradient
|
||||
float linealpha=5000*WireThickness/(mgn+1.0); //*WireThickness
|
||||
if (linealpha>1.2) linealpha=1.2; //zbyt grube nie są dobre
|
||||
glLineWidth(linealpha);
|
||||
if (linealpha>1.0) linealpha = 1.0;
|
||||
//McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
||||
float r,g,b;
|
||||
switch (Material)
|
||||
{//Ra: kolory podzieliłem przez 2, bo po zmianie ambient za jasne były
|
||||
//trzeba uwzględnić kierunek świecenia Słońca - tylko ze Słońcem widać kolor
|
||||
case 1:
|
||||
if (TestFlag(DamageFlag,1))
|
||||
{
|
||||
r=0.00000; g=0.32549; b=0.2882353; //zielona miedź
|
||||
}
|
||||
else
|
||||
{
|
||||
r=0.35098; g=0.22549; b=0.1; //czerwona miedź
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (TestFlag(DamageFlag,1))
|
||||
{
|
||||
r=0.10; g=0.10; b=0.10; //czarne Al
|
||||
}
|
||||
else
|
||||
{
|
||||
r=0.25; g=0.25; b=0.25; //srebrne Al
|
||||
}
|
||||
break;
|
||||
//tymczasowo pokazanie zasilanych odcinków
|
||||
case 4: r=0.5; g=0.5; b=1.0; break; //niebieskie z podłączonym zasilaniem
|
||||
case 5: r=1.0; g=0.0; b=0.0; break; //czerwone z podłączonym zasilaniem 1
|
||||
case 6: r=0.0; g=1.0; b=0.0; break; //zielone z podłączonym zasilaniem 2
|
||||
case 7: r=1.0; g=1.0; b=0.0; break; //żółte z podłączonym zasilaniem z obu stron
|
||||
}
|
||||
if (DebugModeFlag)
|
||||
if (hvParallel)
|
||||
{//jeśli z bieżnią wspólną, to dodatkowo przyciemniamy
|
||||
r*=0.6; g*=0.6; b*=0.6;
|
||||
}
|
||||
r*=Global::ambientDayLight[0]; //w zaleźności od koloru swiatła
|
||||
g*=Global::ambientDayLight[1];
|
||||
b*=Global::ambientDayLight[2];
|
||||
if (linealpha>1.0) linealpha=1.0; //trzeba ograniczyć do <=1
|
||||
glColor4f(r,g,b,linealpha);
|
||||
if (!uiDisplayList)
|
||||
Optimize(); //generowanie DL w miarę potrzeby
|
||||
glCallList(uiDisplayList);
|
||||
glLineWidth(1.0);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
//glEnable(GL_LIGHTING); //bez tego się modele nie oświetlają
|
||||
}
|
||||
}
|
||||
|
||||
int __fastcall TTraction::RaArrayPrepare()
|
||||
{//przygotowanie tablic do skopiowania do VBO (zliczanie wierzchołków)
|
||||
//if (bVisible) //o ile w ogóle widać
|
||||
switch (Wires)
|
||||
{
|
||||
case 1: iLines=2; break;
|
||||
case 2: iLines=iNumSections?4*(iNumSections)-2+2:4; break;
|
||||
case 3: iLines=iNumSections?4*(iNumSections)-2+4:6; break;
|
||||
case 4: iLines=iNumSections?4*(iNumSections)-2+6:8; break;
|
||||
default: iLines=0;
|
||||
}
|
||||
//else iLines=0;
|
||||
return iLines;
|
||||
};
|
||||
|
||||
void __fastcall TTraction::RaArrayFill(CVertNormTex *Vert)
|
||||
{//wypełnianie tablic VBO
|
||||
CVertNormTex *old=Vert;
|
||||
double ddp=hypot(pPoint2.x-pPoint1.x,pPoint2.z-pPoint1.z);
|
||||
if (Wires==2) WireOffset=0;
|
||||
//jezdny
|
||||
Vert->x=pPoint1.x-(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset;
|
||||
Vert->y=pPoint1.y;
|
||||
Vert->z=pPoint1.z-(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset;
|
||||
++Vert;
|
||||
Vert->x=pPoint2.x-(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset;
|
||||
Vert->y=pPoint2.y;
|
||||
Vert->z=pPoint2.z-(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset;
|
||||
++Vert;
|
||||
//Nie wiem co 'Marcin
|
||||
vector3 pt1,pt2,pt3,pt4,v1,v2;
|
||||
v1=pPoint4-pPoint3;
|
||||
v2=pPoint2-pPoint1;
|
||||
float step=0;
|
||||
if (iNumSections>0)
|
||||
step=1.0f/(float)iNumSections;
|
||||
float f=step;
|
||||
float mid=0.5;
|
||||
float t;
|
||||
//Przewod nosny 'Marcin
|
||||
if (Wires>1)
|
||||
{//lina nośna w kawałkach
|
||||
Vert->x=pPoint3.x;
|
||||
Vert->y=pPoint3.y;
|
||||
Vert->z=pPoint3.z;
|
||||
++Vert;
|
||||
for (int i=0;i<iNumSections-1;i++)
|
||||
{
|
||||
pt3=pPoint3+v1*f;
|
||||
t=(1-fabs(f-mid)*2);
|
||||
Vert->x=pt3.x;
|
||||
Vert->y=pt3.y-sqrt(t)*fHeightDifference;
|
||||
Vert->z=pt3.z;
|
||||
++Vert;
|
||||
Vert->x=pt3.x; //drugi raz, bo nie jest line_strip
|
||||
Vert->y=pt3.y-sqrt(t)*fHeightDifference;
|
||||
Vert->z=pt3.z;
|
||||
++Vert;
|
||||
f+=step;
|
||||
}
|
||||
Vert->x=pPoint4.x;
|
||||
Vert->y=pPoint4.y;
|
||||
Vert->z=pPoint4.z;
|
||||
++Vert;
|
||||
}
|
||||
//Drugi przewod jezdny 'Winger
|
||||
if (Wires==3)
|
||||
{
|
||||
Vert->x=pPoint1.x+(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset;
|
||||
Vert->y=pPoint1.y;
|
||||
Vert->z=pPoint1.z+(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset;
|
||||
++Vert;
|
||||
Vert->x=pPoint2.x+(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset;
|
||||
Vert->y=pPoint2.y;
|
||||
Vert->z=pPoint2.z+(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset;
|
||||
++Vert;
|
||||
}
|
||||
f=step;
|
||||
//Przewody pionowe (wieszaki) 'Marcin, poprawki na 2 przewody jezdne 'Winger
|
||||
if (Wires>1)
|
||||
{
|
||||
for (int i=0;i<iNumSections-1;i++)
|
||||
{
|
||||
pt3=pPoint3+v1*f;
|
||||
pt4=pPoint1+v2*f;
|
||||
t=(1-fabs(f-mid)*2);
|
||||
Vert->x=pt3.x;
|
||||
Vert->y=pt3.y-sqrt(t)*fHeightDifference;
|
||||
Vert->z=pt3.z;
|
||||
++Vert;
|
||||
if ((i%2)==0)
|
||||
{
|
||||
Vert->x=pt4.x-(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset;
|
||||
Vert->y=pt4.y;
|
||||
Vert->z=pt4.z-(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vert->x=pt4.x+(pPoint2.z/ddp-pPoint1.z/ddp)*WireOffset;
|
||||
Vert->y=pt4.y;
|
||||
Vert->z=pt4.z+(-pPoint2.x/ddp+pPoint1.x/ddp)*WireOffset;
|
||||
}
|
||||
++Vert;
|
||||
f+=step;
|
||||
}
|
||||
}
|
||||
if ((Vert-old)!=iLines)
|
||||
WriteLog("!!! Wygenerowano punktów "+AnsiString(Vert-old)+", powinno być "+AnsiString(iLines));
|
||||
};
|
||||
|
||||
void __fastcall TTraction::RenderVBO(float mgn,int iPtr)
|
||||
{//renderowanie z użyciem VBO
|
||||
if (Wires!=0 && !TestFlag(DamageFlag,128)) //rysuj jesli sa druty i nie zerwana
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D,0);
|
||||
glDisable(GL_LIGHTING); //aby nie używało wektorów normalnych do kolorowania
|
||||
glColor4f(0,0,0,1); //jak nieznany kolor to czarne nieprzezroczyste
|
||||
if (!Global::bSmoothTraction)
|
||||
glDisable(GL_LINE_SMOOTH); //na liniach kiepsko wygląda - robi gradient
|
||||
float linealpha=5000*WireThickness/(mgn+1.0); //*WireThickness
|
||||
if (linealpha>1.2) linealpha=1.2; //zbyt grube nie są dobre
|
||||
glLineWidth(linealpha);
|
||||
//McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
||||
float r,g,b;
|
||||
switch (Material)
|
||||
{//Ra: kolory podzieliłem przez 2, bo po zmianie ambient za jasne były
|
||||
//trzeba uwzględnić kierunek świecenia Słońca - tylko ze Słońcem widać kolor
|
||||
case 1:
|
||||
if (TestFlag(DamageFlag,1))
|
||||
{
|
||||
r=0.00000; g=0.32549; b=0.2882353; //zielona miedź
|
||||
}
|
||||
else
|
||||
{
|
||||
r=0.35098; g=0.22549; b=0.1; //czerwona miedź
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (TestFlag(DamageFlag,1))
|
||||
{
|
||||
r=0.10; g=0.10; b=0.10; //czarne Al
|
||||
}
|
||||
else
|
||||
{
|
||||
r=0.25; g=0.25; b=0.25; //srebrne Al
|
||||
}
|
||||
break;
|
||||
//tymczasowo pokazanie zasilanych odcinków
|
||||
case 4: r=0.5; g=0.5; b=1.0; break; //niebieskie z podłączonym zasilaniem
|
||||
case 5: r=1.0; g=0.0; b=0.0; break; //czerwone z podłączonym zasilaniem 1
|
||||
case 6: r=0.0; g=1.0; b=0.0; break; //zielone z podłączonym zasilaniem 2
|
||||
case 7: r=1.0; g=1.0; b=0.0; break; //żółte z podłączonym zasilaniem z obu stron
|
||||
}
|
||||
r=r*Global::ambientDayLight[0]; //w zaleznosci od koloru swiatla
|
||||
g=g*Global::ambientDayLight[1];
|
||||
b=b*Global::ambientDayLight[2];
|
||||
if (linealpha>1.0) linealpha=1.0; //trzeba ograniczyć do <=1
|
||||
glColor4f(r,g,b,linealpha);
|
||||
glDrawArrays(GL_LINES,iPtr,iLines);
|
||||
glLineWidth(1.0);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_LIGHTING); //bez tego się modele nie oświetlają
|
||||
}
|
||||
};
|
||||
|
||||
int __fastcall TTraction::TestPoint(vector3 *Point)
|
||||
{//sprawdzanie, czy przęsła można połączyć
|
||||
if (!hvNext[0])
|
||||
if (pPoint1.Equal(Point))
|
||||
return 0;
|
||||
if (!hvNext[1])
|
||||
if (pPoint2.Equal(Point))
|
||||
return 1;
|
||||
return -1;
|
||||
};
|
||||
|
||||
void __fastcall TTraction::Connect(int my,TTraction *with,int to)
|
||||
{//łączenie segmentu (with) od strony (my) do jego (to)
|
||||
if (my)
|
||||
{//do mojego Point2
|
||||
hvNext[1]=with;
|
||||
iNext[1]=to;
|
||||
}
|
||||
else
|
||||
{//do mojego Point1
|
||||
hvNext[0]=with;
|
||||
iNext[0]=to;
|
||||
}
|
||||
if (to)
|
||||
{//do jego Point2
|
||||
with->hvNext[1]=this;
|
||||
with->iNext[1]=my;
|
||||
}
|
||||
else
|
||||
{//do jego Point1
|
||||
with->hvNext[0]=this;
|
||||
with->iNext[0]=my;
|
||||
}
|
||||
if (hvNext[0]) //jeśli z obu stron podłączony
|
||||
if (hvNext[1])
|
||||
iLast=0; //to nie jest ostatnim
|
||||
if (with->hvNext[0]) //temu też, bo drugi raz łączenie się nie nie wykona
|
||||
if (with->hvNext[1])
|
||||
with->iLast=0; //to nie jest ostatnim
|
||||
};
|
||||
|
||||
bool __fastcall TTraction::WhereIs()
|
||||
{//ustalenie przedostatnich przęseł
|
||||
if (iLast) return (iLast==1); //ma już ustaloną informację o położeniu
|
||||
if (hvNext[0]?hvNext[0]->iLast==1:false) //jeśli poprzedni jest ostatnim
|
||||
iLast=2; //jest przedostatnim
|
||||
else
|
||||
if (hvNext[1]?hvNext[1]->iLast==1:false) //jeśli następny jest ostatnim
|
||||
iLast=2; //jest przedostatnim
|
||||
return (iLast==1); //ostatnie będą dostawać zasilanie
|
||||
};
|
||||
|
||||
void __fastcall TTraction::Init()
|
||||
{//przeliczenie parametrów
|
||||
vParametric=pPoint2-pPoint1; //wektor mnożników parametru dla równania parametrycznego
|
||||
};
|
||||
|
||||
void __fastcall TTraction::ResistanceCalc(int d,double r,TTractionPowerSource *ps)
|
||||
{//(this) jest przęsłem zasilanym, o rezystancji (r), policzyć rezystancję zastępczą sąsiednich
|
||||
if (d>=0)
|
||||
{//podążanie we wskazanym kierunku
|
||||
TTraction *t=hvNext[d],*p;
|
||||
if (ps)
|
||||
psPower[d^1]=ps; //podłączenie podanego
|
||||
else
|
||||
ps=psPower[d^1]; //zasilacz od przeciwnej strony niż idzie analiza
|
||||
d=iNext[d]; //kierunek
|
||||
//double r; //sumaryczna rezystancja
|
||||
if (DebugModeFlag) //tylko podczas testów
|
||||
Material=4; //pokazanie, że to przęsło ma podłączone zasilanie
|
||||
while (t?!t->psPower[d]:false) //jeśli jest jakiś kolejny i nie ma ustalonego zasilacza
|
||||
{//ustawienie zasilacza i policzenie rezystancji zastępczej
|
||||
if (DebugModeFlag) //tylko podczas testów
|
||||
if (t->Material!=4) //przęsła zasilającego nie modyfikować
|
||||
{if (t->Material<4) t->Material=4; //tymczasowo, aby zmieniła kolor
|
||||
t->Material|=d?2:1; //kolor zależny od strony, z której jest zasilanie
|
||||
}
|
||||
t->psPower[d]=ps; //skopiowanie wskaźnika zasilacza od danej strony
|
||||
t->fResistance[d]=r; //wpisanie rezystancji w kierunku tego zasilacza
|
||||
r+=t->fResistivity*Length3(t->vParametric); //doliczenie oporu kolejnego odcinka
|
||||
p=t; //zapamiętanie dotychczasowego
|
||||
t=p->hvNext[d^1]; //podążanie w tę samą stronę
|
||||
d=p->iNext[d^1];
|
||||
//w przypadku zapętlenia sieci może się zawiesić?
|
||||
}
|
||||
}
|
||||
else
|
||||
{//podążanie w obu kierunkach, można by rekurencją, ale szkoda zasobów
|
||||
r=0.5*fResistivity*Length3(vParametric); //powiedzmy, że w zasilanym przęśle jest połowa
|
||||
if (fResistance[0]==0.0) ResistanceCalc(0,r); //do tyłu (w stronę Point1)
|
||||
if (fResistance[1]==0.0) ResistanceCalc(1,r); //do przodu (w stronę Point2)
|
||||
}
|
||||
};
|
||||
|
||||
void __fastcall TTraction::PowerSet(TTractionPowerSource *ps)
|
||||
{//podłączenie przęsła do zasilacza
|
||||
if (ps->bSection)
|
||||
psSection=ps; //ustalenie sekcji zasilania
|
||||
else
|
||||
{//ustalenie punktu zasilania (nie ma jeszcze połączeń między przęsłami)
|
||||
psPowered=ps; //ustawienie bezpośredniego zasilania dla przęsła
|
||||
psPower[0]=psPower[1]=ps; //a to chyba nie jest dobry pomysł, bo nawet zasilane przęsło powinno mieć wskazania na inne
|
||||
fResistance[0]=fResistance[1]=0.0; //a liczy się tylko rezystancja zasilacza
|
||||
}
|
||||
};
|
||||
|
||||
double __fastcall TTraction::VoltageGet(double u,double i)
|
||||
{//pobranie napięcia na przęśle po podłączeniu do niego rezystancji (res) - na razie jest to prąd
|
||||
if (!psSection)
|
||||
if (!psPowered)
|
||||
return NominalVoltage; //jak nie ma zasilacza, to napięcie podane w przęśle
|
||||
//na początek można założyć, że wszystkie podstacje mają to samo napięcie i nie płynie prąd pomiędzy nimi
|
||||
//dla danego przęsła mamy 3 źródła zasilania
|
||||
//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;
|
||||
if (psPowered) return psPowered->CurrentGet(res)*res; //yB: dla zasilanego nie baw się w gwiazdy, tylko bierz bezpośrednio
|
||||
double r0t,r1t,r0g,r1g;
|
||||
double u0,u1,i0,i1;
|
||||
r0t=fResistance[0]; //średni pomysł, ale lepsze niż nic
|
||||
r1t=fResistance[1]; //bo nie uwzględnia spadków z innych pojazdów
|
||||
if (psPower[0]&&psPower[1])
|
||||
{//gdy przęsło jest zasilane z obu stron - mamy trójkąt: res, r0t, r1t
|
||||
//yB: Gdy wywali podstacja, to zaczyna się robić nieciekawie - napięcie w sekcji na jednym końcu jest równe zasilaniu,
|
||||
//yB: a na drugim końcu jest równe 0. Kolejna sprawa to rozróżnienie uszynienia sieci na podstacji/odłączniku (czyli
|
||||
//yB: potencjał masy na sieci) od braku zasilania (czyli odłączenie źródła od sieci i brak jego wpływu na napięcie).
|
||||
if ((r0t>0.0)&&(r1t>0.0))
|
||||
{//rezystancje w mianowniku nie mogą być zerowe
|
||||
r0g=res+r0t+(res*r0t)/r1t; //przeliczenie z trójkąta na gwiazdę
|
||||
r1g=res+r1t+(res*r1t)/r0t;
|
||||
//pobierane są prądy dla każdej rezystancji, a suma jest mnożona przez rezystancję pojazdu w celu uzyskania napięcia
|
||||
i0=psPower[0]->CurrentGet(r0g); //oddzielnie dla sprawdzenia
|
||||
i1=psPower[1]->CurrentGet(r1g);
|
||||
return (i0+i1)*res;
|
||||
}
|
||||
else if (r0t>=0.0)
|
||||
return psPower[0]->CurrentGet(res+r0t)*res;
|
||||
else if (r1t>=0.0)
|
||||
return psPower[1]->CurrentGet(res+r1t)*res;
|
||||
else
|
||||
return 0.0; //co z tym zrobić?
|
||||
}
|
||||
else if (psPower[0]&&(r0t>=0.0))
|
||||
{//jeśli odcinek podłączony jest tylko z jednej strony
|
||||
return psPower[0]->CurrentGet(res+r0t)*res;
|
||||
}
|
||||
else if (psPower[1]&&(r1t>=0.0))
|
||||
return psPower[1]->CurrentGet(res+r1t)*res;
|
||||
return 0.0; //gdy nie podłączony wcale?
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user