16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 02:49:19 +02:00

Format source code using clang-format

This commit is contained in:
Zbigniew Mandziejewicz
2015-04-03 22:00:22 +08:00
parent 91470458b4
commit cb19354db4
99 changed files with 40728 additions and 36059 deletions

View File

@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
#include "Timer.h"
@@ -11,171 +11,166 @@
__fastcall TAdvancedSound::TAdvancedSound()
{
// SoundStart=SoundCommencing=SoundShut= NULL;
State=ss_Off;
fTime=0;
fStartLength=0;
fShutLength=0;
// 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();
{ // Ra: stopowanie siê sypie
// SoundStart.Stop();
// SoundCommencing.Stop();
// SoundShut.Stop();
}
void __fastcall TAdvancedSound::Free()
{
}
void __fastcall TAdvancedSound::Free() {}
void __fastcall TAdvancedSound::Init(char *NameOn, char *Name, char *NameOff, double DistanceAttenuation, vector3 pPosition)
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;
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);
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))
// 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;
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))
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);
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))
if ((State == ss_Commencing) && (SoundCommencing.AM > 0))
{
// SoundCommencing->SetFrequency();
SoundShut.Stop(); //hunter-311211
SoundCommencing.Play(1,DSBPLAY_LOOPING,ListenerInside,NewPosition);
// SoundCommencing->SetFrequency();
SoundShut.Stop(); // hunter-311211
SoundCommencing.Play(1, DSBPLAY_LOOPING, ListenerInside, NewPosition);
}
else
if (State==ss_Starting)
else if (State == ss_Starting)
{
fTime+= Timer::GetDeltaTime();
// SoundStart->SetVolume(-1000*(4-fTime)/4);
if (fTime>=fStartLength)
fTime += Timer::GetDeltaTime();
// SoundStart->SetVolume(-1000*(4-fTime)/4);
if (fTime >= fStartLength)
{
State= ss_Commencing;
State = ss_Commencing;
SoundCommencing.ResetPosition();
SoundCommencing.Play(1,DSBPLAY_LOOPING,ListenerInside,NewPosition);
SoundCommencing.Play(1, DSBPLAY_LOOPING, ListenerInside, NewPosition);
SoundStart.Stop();
}
else
SoundStart.Play(1,0,ListenerInside,NewPosition);
SoundStart.Play(1, 0, ListenerInside, NewPosition);
}
else
if (State==ss_ShuttingDown)
else if (State == ss_ShuttingDown)
{
fTime-= Timer::GetDeltaTime();
// SoundShut->SetVolume(-1000*(4-fTime)/4);
if (fTime<=0)
fTime -= Timer::GetDeltaTime();
// SoundShut->SetVolume(-1000*(4-fTime)/4);
if (fTime <= 0)
{
State= ss_Off;
State = ss_Off;
SoundShut.Stop();
}
else
SoundShut.Play(1,0,ListenerInside,NewPosition);
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))
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);
SoundShut.Stop(); // hunter-311211
SoundCommencing.Play(A, DSBPLAY_LOOPING, ListenerInside, NewPosition);
}
else
if (State==ss_Starting)
else if (State == ss_Starting)
{
fTime+= Timer::GetDeltaTime();
// SoundStart->SetVolume(-1000*(4-fTime)/4);
if (fTime>=fStartLength)
fTime += Timer::GetDeltaTime();
// SoundStart->SetVolume(-1000*(4-fTime)/4);
if (fTime >= fStartLength)
{
State= ss_Commencing;
State = ss_Commencing;
SoundCommencing.ResetPosition();
SoundCommencing.Play(A,DSBPLAY_LOOPING,ListenerInside,NewPosition);
SoundCommencing.Play(A, DSBPLAY_LOOPING, ListenerInside, NewPosition);
SoundStart.Stop();
}
else
SoundStart.Play(A,0,ListenerInside,NewPosition);
SoundStart.Play(A, 0, ListenerInside, NewPosition);
}
else
if (State==ss_ShuttingDown)
else if (State == ss_ShuttingDown)
{
fTime-= Timer::GetDeltaTime();
// SoundShut->SetVolume(-1000*(4-fTime)/4);
if (fTime<=0)
fTime -= Timer::GetDeltaTime();
// SoundShut->SetVolume(-1000*(4-fTime)/4);
if (fTime <= 0)
{
State= ss_Off;
State = ss_Off;
SoundShut.Stop();
}
else
SoundShut.Play(A,0,ListenerInside,NewPosition);
SoundShut.Play(A, 0, ListenerInside, NewPosition);
}
SoundCommencing.AdjFreq(F,Timer::GetDeltaTime());
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;
{ // 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;
};

View File

@@ -6,10 +6,16 @@
#include "RealSound.h"
#include "QueryParserComp.hpp"
typedef enum {ss_Off, ss_Starting, ss_Commencing, ss_ShuttingDown} TSoundState;
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)
{ // klasa dŸwiêków maj¹cych pocz¹tek, dowolnie d³ugi œrodek oraz zakoñczenie (np. Rp1)
TRealSound SoundStart;
TRealSound SoundCommencing;
TRealSound SoundShut;
@@ -20,17 +26,18 @@ class TAdvancedSound
double defAM;
double defFM;
public:
public:
__fastcall TAdvancedSound();
__fastcall ~TAdvancedSound();
void __fastcall Init(char *NameOn, char *Name, char *NameOff, double DistanceAttenuation, vector3 pPosition);
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);
void __fastcall CopyIfEmpty(TAdvancedSound &s);
};
//---------------------------------------------------------------------------

View File

@@ -1,71 +1,68 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
#include "AirCoupler.h"
#include "Timer.h"
__fastcall TAirCoupler::TAirCoupler()
{
Clear();
}
__fastcall TAirCoupler::TAirCoupler() { Clear(); }
__fastcall TAirCoupler::~TAirCoupler()
{
}
__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;
{ // 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;
{ // 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
{ // 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;
}
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;
}
// if ((pModelOn!=NULL) && (pModelOn!=NULL))
{
if (pModelOn)
pModelOn->iVisible = bOn;
if (pModelOff)
pModelOff->iVisible = !(bOn || bxOn);
if (pModelxOn)
pModelxOn->iVisible = bxOn;
}
}
//---------------------------------------------------------------------------

View File

@@ -8,24 +8,40 @@
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();
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();
};
//---------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@@ -5,144 +5,162 @@
#include "Model3d.h"
const int iMaxNumLights=8;
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
// 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
{ // 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;};
{ // 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();
{ // 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);
{ // 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;
TAnimContainer *TAnimModel::acAnimList = NULL;
//---------------------------------------------------------------------------
#endif

View File

@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
#include "Button.h"
@@ -13,58 +13,61 @@
__fastcall TButton::TButton()
{
iFeedbackBit=0;
Clear();
iFeedbackBit = 0;
Clear();
};
__fastcall TButton::~TButton()
{
};
__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
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)
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();
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)
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;
}
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);
}
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);
}
};

View File

@@ -7,24 +7,41 @@
#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);
{ // 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);
};
//---------------------------------------------------------------------------

View File

@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#include "opengl/glew.h"
#include "opengl/glut.h"
@@ -16,181 +16,189 @@
//---------------------------------------------------------------------------
#pragma package(smart_init)
//TViewPyramid TCamera::OrgViewPyramid;
// 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);
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;
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;
// 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);
}
// 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);
// 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;
a = a * 100;
// OldVelocity=Velocity;
if (FreeFlyModeFlag == true)
Type = tp_Free;
else
Type=tp_Follow;
if (Type==tp_Free)
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(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_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 (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 (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_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;
*/
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-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;
// 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;
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 = vector3(0, 0, 1);
Vec.RotateY(Yaw);
return (Normalize(Vec));
}
//bool __fastcall TCamera::GetMatrix(matrix4x4 &Matrix)
// 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
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)
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;
// 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_Satelite)
Pitch = M_PI * 0.5;
if (Type!=tp_Follow)
if (Type != tp_Follow)
{
glTranslated(-Pos.x,-Pos.y,-Pos.z); //nie zmienia kierunku patrzenia
glTranslated(-Pos.x, -Pos.y, -Pos.z); // nie zmienia kierunku patrzenia
}
Global::SetCameraPosition(Pos); //by³o +pOffset
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
{ // 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
{ // 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);
{ // wy³¹cznie bezw³adnego ruchu po powrocie do kabiny
Type = tp_Follow;
Velocity = vector3(0, 0, 0);
};

View File

@@ -2,46 +2,45 @@
#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)
{ // 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; };
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;
bool __fastcall SetMatrix();
void __fastcall SetCabMatrix(vector3 &p);
void __fastcall RaLook();
void __fastcall Stop();
// bool __fastcall GetMatrix(matrix4x4 &Matrix);
vector3 PtNext, PtPrev;
};
#endif

View File

@@ -3,24 +3,24 @@
#ifndef ClassesH
#define ClassesH
//---------------------------------------------------------------------------
//Ra: zestaw klas do robienia wskaźników, aby uporządkować nagłówki
// Ra: zestaw klas do robienia wskaźników, aby uporządkować nagłówki
//---------------------------------------------------------------------------
class TTrack; //odcinek trajektorii
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 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 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 TTraction; // drut
class TTractionPowerSource; // zasilanie drutów
class TMoverParameters;
namespace _mover
@@ -31,24 +31,24 @@ class TRotation;
namespace Mtable
{
class TTrainParameters; //rozkład jazdy
class TTrainParameters; // rozkład jazdy
};
class TController; //obiekt sterujący pociągiem (AI)
class TNames; //obiekt sortujący nazwy
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
{ // 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

View File

@@ -11,9 +11,9 @@
//---------------------------------------------------------------------------
#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)
// 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.
@@ -73,275 +73,278 @@ public static Int32 GetScreenSaverTimeout()
};
*/
//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);
};
// 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
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]
}
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];
delete PoKeys55[0];
delete PoKeys55[1];
};
void __fastcall Console::ModeSet(int m,int h)
{//ustawienie trybu pracy
iMode=m;
iConfig=h;
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;
{ // 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;
{ // 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::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::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;
}
{ // 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);
};
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::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
}
{ // 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;
{ // 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;
{ // 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
}
}
{ // 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
{ // 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);
};
int __fastcall Console::KeyDownConvert(int k) { return int(ktTable[k & 0x3FF].iDown); };
int __fastcall Console::KeyUpConvert(int k) { return int(ktTable[k & 0x3FF].iUp); };

View File

@@ -3,53 +3,52 @@
#ifndef ConsoleH
#define ConsoleH
//---------------------------------------------------------------------------
class TConsoleDevice; //urządzenie podłączalne za pomocą DLL
class TConsoleDevice; // urządzenie podłączalne za pomocą DLL
class TPoKeys55;
class TLPT;
//klasy konwersji znaków wprowadzanych z klawiatury
// klasy konwersji znaków wprowadzanych z klawiatury
class TKeyTrans
{//przekodowanie kodu naciśnięcia i zwolnienia klawisza
public:
short int iDown,iUp;
{ // 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);
{ // 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

View File

@@ -3,44 +3,42 @@
#include "LPT.h"
#include <windows.h>
//LPT na USB:
//USB\VID_067B&PID_2305&REV_0200
// 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
// 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);
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);
// 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); };

View File

@@ -6,10 +6,11 @@
class TLPT
{
private:
int address;
public:
bool __fastcall Connect(int port);
void __fastcall Out(int x);
private:
int address;
public:
bool __fastcall Connect(int port);
void __fastcall Out(int x);
};
#endif

View File

@@ -6,311 +6,360 @@
#include "PoKeys55.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//HIDscaner: http://forum.simflight.com/topic/68257-latest-lua-package-for-fsuipc-and-wideclient/
// 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)
// 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};
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;
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();
};
__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;
{ // 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");
{ // 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;
}
}
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)
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
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;
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;
{ // 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 "";
{ // 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::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
{ // 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
};

View File

@@ -3,29 +3,30 @@
#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);
{ // 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

124
Curve.cpp
View File

@@ -1,110 +1,109 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
#include "Curve.h"
__fastcall TCurve::TCurve()
{
Values= NULL;
iNumValues= 0;
iNumCols= 0;
Values = NULL;
iNumValues = 0;
iNumCols = 0;
}
__fastcall TCurve::~TCurve()
{
for (int i=0; i<iNumValues; i++)
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++)
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];
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;
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);
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)
int a = floor(p);
int b = ceil(p);
if (a < 0)
return false;
p-= floor(p);
if (p<0.5)
Values[a][c]= v;
if (b >= iNumValues)
return false;
p -= floor(p);
if (p < 0.5)
Values[a][c] = v;
else
Values[b][c]= v;
Values[b][c] = v;
return true;
}
bool __fastcall TCurve::Load(TQueryParserComp *Parser)
{
DecimalSeparator= '.';
DecimalSeparator = '.';
AnsiString Token;
int n= Parser->GetNextSymbol().ToInt();
int c= Parser->GetNextSymbol().ToInt();
Init(n,c);
int n = Parser->GetNextSymbol().ToInt();
int c = Parser->GetNextSymbol().ToInt();
Init(n, c);
n=0;
n = 0;
int i;
while (!Parser->EOF && n<iNumValues)
while (!Parser->EOF && n < iNumValues)
{
for (i=0; i<iNumCols; i++)
Values[n][i]= Parser->GetNextSymbol().ToDouble();
for (i = 0; i < iNumCols; i++)
Values[n][i] = Parser->GetNextSymbol().ToDouble();
n++;
}
DecimalSeparator= ',';
DecimalSeparator = ',';
}
bool __fastcall TCurve::LoadFromFile(AnsiString asName)
{
DecimalSeparator= '.';
DecimalSeparator = '.';
TFileStream *fs;
fs= new TFileStream(asName, fmOpenRead | fmShareCompat );
AnsiString str= "xxx";
int size= fs->Size;
fs = new TFileStream(asName, fmOpenRead | fmShareCompat);
AnsiString str = "xxx";
int size = fs->Size;
str.SetLength(size);
fs->Read(str.c_str(),size);
str+= "";
fs->Read(str.c_str(), size);
str += "";
delete fs;
TQueryParserComp *Parser;
Parser= new TQueryParserComp(NULL);
Parser->TextToParse= str;
Parser = new TQueryParserComp(NULL);
Parser->TextToParse = str;
Parser->First();
Load(Parser);
delete Parser;
DecimalSeparator= ',';
DecimalSeparator = ',';
}
#include <stdio.h>
@@ -112,28 +111,27 @@ bool __fastcall TCurve::LoadFromFile(AnsiString asName)
bool __fastcall TCurve::SaveToFile(AnsiString asName)
{
DecimalSeparator= '.';
FILE *stream=NULL;
DecimalSeparator = '.';
FILE *stream = NULL;
stream = fopen(asName.c_str(), "w");
AnsiString str;
str= AnsiString(iNumValues);
str = AnsiString(iNumValues);
fprintf(stream, str.c_str());
fprintf(stream, "\n");
for (int i=0; i<iNumValues; i++)
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");
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= ',';
DecimalSeparator = ',';
}
//---------------------------------------------------------------------------

View File

@@ -8,7 +8,7 @@
class TCurve
{
public:
public:
__fastcall TCurve();
__fastcall ~TCurve();
bool __fastcall Init(int n, int c);
@@ -21,9 +21,8 @@ public:
int iNumValues;
int iNumCols;
private:
private:
float **Values;
};
//---------------------------------------------------------------------------
#endif

806
Data.h
View File

@@ -8,411 +8,409 @@
struct TDist
{
int x,y;
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)
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

8614
Driver.cpp

File diff suppressed because it is too large Load Diff

602
Driver.h
View File

@@ -9,312 +9,340 @@
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?)
{ // 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
{ // 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
{ // 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)
{ // 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();
{ // 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
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();
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

8590
DynObj.cpp

File diff suppressed because it is too large Load Diff

650
DynObj.h
View File

@@ -8,7 +8,7 @@
#include "QueryParserComp.hpp"
#include "Mover.h"
#include "TractionPower.h"
//McZapkie:
// McZapkie:
#include "MdlMngr.h"
#include "RealSound.h"
#include "AdvSound.h"
@@ -17,22 +17,22 @@
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
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
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
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
// 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ć
@@ -45,86 +45,89 @@ szczeg
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
{ // 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();
{ // 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
{ // 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
};
//---------------------------------------------------------------------------
@@ -132,149 +135,156 @@ public:
//---------------------------------------------------------------------------
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
{ // 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: //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?)
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
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
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:
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);
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
TButton btCoupler1; //sprzegi
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
btCPneumatic1; // sprzegi powietrzne //yB - zmienione z Button na AirCoupler - krzyzyki
TAirCoupler btCPneumatic2;
TAirCoupler btCPneumatic1r; //ABu: to zeby nie bylo problemow przy laczeniu wagonow,
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 btPneumatic1; // ABu: sprzegi powietrzne zolte
TAirCoupler btPneumatic2;
TAirCoupler btPneumatic1r; //ABu: analogicznie jak 4 linijki wyzej
TAirCoupler btPneumatic1r; // ABu: analogicznie jak 4 linijki wyzej
TAirCoupler btPneumatic2r;
TButton btCCtrl1; //sprzegi sterowania
TButton btCCtrl1; // sprzegi sterowania
TButton btCCtrl2;
TButton btCPass1; //mostki przejsciowe
TButton btCPass1; // mostki przejsciowe
TButton btCPass2;
char cp1, sp1, cp2, sp2; //ustawienia węży
char cp1, sp1, cp2, sp2; // ustawienia węży
TButton btEndSignals11; //sygnalu konca pociagu
TButton btEndSignals11; // sygnalu konca pociagu
TButton btEndSignals13;
TButton btEndSignals21;
TButton btEndSignals23;
TButton btEndSignals1; //zeby bylo kompatybilne ze starymi modelami...
TButton btEndSignals1; // zeby bylo kompatybilne ze starymi modelami...
TButton btEndSignals2;
TButton btEndSignalsTab1; //sygnaly konca pociagu (blachy)
TButton btEndSignalsTab1; // sygnaly konca pociagu (blachy)
TButton btEndSignalsTab2;
TButton btHeadSignals11; //oswietlenie czolowe - przod
TButton btHeadSignals11; // oswietlenie czolowe - przod
TButton btHeadSignals12;
TButton btHeadSignals13;
TButton btHeadSignals21; //oswietlenie czolowe - tyl
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
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
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
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 sCompressor; // NBMX wrzesien 2003
TAdvancedSound sConverter;
TAdvancedSound sSmallCompressor;
TAdvancedSound sDepartureSignal;
TAdvancedSound sTurbo;
//Winger 010304
// TRealSound rsPanTup; //PSound sPantUp;
// Winger 010304
// TRealSound rsPanTup; //PSound sPantUp;
TRealSound sPantUp;
TRealSound sPantDown;
TRealSound rsDoorOpen; //Ra: przeniesione z kabiny
TRealSound rsDoorOpen; // Ra: przeniesione z kabiny
TRealSound rsDoorClose;
double eng_vol_act;
@@ -285,89 +295,90 @@ private:
void __fastcall ABuModelRoll();
vector3 modelShake;
bool renderme; //yB - czy renderowac
//TRealSound sBrakeAcc; //dźwięk przyspieszacza
bool renderme; // yB - czy renderowac
// TRealSound sBrakeAcc; //dźwięk przyspieszacza
PSound sBrakeAcc;
bool bBrakeAcc;
TRealSound rsUnbrake; //yB - odglos luzowania
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:
int iInventory; // flagi bitowe posiadanych submodeli (np. świateł)
void __fastcall TurnOff();
//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
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);
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;}
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("");
};
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;
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);
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
// McZapkie-010302
TController *Mechanik;
TController *ctOwner; //wskażnik na obiekt zarządzający składem
TController *ctOwner; // wskażnik na obiekt zarządzający składem
bool MechInside;
//McZapkie-270202
// 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
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
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ą
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
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);
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);
@@ -377,64 +388,79 @@ public:
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 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();
inline TTrack *__fastcall GetTrack()
{
return (iAxleFirst ? Axle1.GetTrack() : Axle0.GetTrack());
};
// void __fastcall UpdatePos();
// McZapkie-260202
void __fastcall LoadMMediaFile(AnsiString BaseDir, AnsiString TypeName,
AnsiString ReplacableSkin);
//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);
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

1172
EU07.cpp

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
*/
#include "system.hpp"
#include "system.hpp"
#pragma hdrstop
#include "mtable.hpp"
@@ -20,164 +20,161 @@
#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;
{ // 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);
}
__fastcall TEventLauncher::~TEventLauncher() { SafeDeleteArray(szText); }
void __fastcall TEventLauncher::Init()
{
}
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;
{ // 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)
{ //"renderowanie" wyzwalacza
bool bCond = false;
if (iKey != 0)
{
UpdatedTime=20; //czas do kolejnego wyzwolenia?
bCond=true;
if (Global::bActive) // tylko jeœli okno jest aktywne
bCond = (Console::Pressed(iKey)); // czy klawisz wciœniêty
}
}
}
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
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;
{ // 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;
};
//---------------------------------------------------------------------------

View File

@@ -7,29 +7,29 @@
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();
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();
};
//---------------------------------------------------------------------------

1172
Event.cpp

File diff suppressed because it is too large Load Diff

132
Event.h
View File

@@ -7,30 +7,49 @@
#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;
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
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
{
@@ -52,39 +71,40 @@ union TParam
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);
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);
};
//---------------------------------------------------------------------------

View File

@@ -5,101 +5,86 @@
*/
#include "system.hpp"
#include "classes.hpp"
#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;
Sound = NULL;
fFade = 0;
dt = 0;
fTime = 0;
}
__fastcall TFadeSound::~TFadeSound() { Free(); }
__fastcall TFadeSound::~TFadeSound()
{
Free();
}
void __fastcall TFadeSound::Free()
{
}
void __fastcall TFadeSound::Free() {}
void __fastcall TFadeSound::Init(char *Name, float fNewFade)
{
Sound= TSoundsManager::GetFromName(Name,false);
Sound = TSoundsManager::GetFromName(Name, false);
if (Sound)
Sound->SetVolume(0);
fFade= fNewFade;
fTime= 0;
fFade = fNewFade;
fTime = 0;
}
void __fastcall TFadeSound::TurnOn()
{
State= ss_Starting;
Sound->Play(0,0,DSBPLAY_LOOPING);
fTime= fFade;
State = ss_Starting;
Sound->Play(0, 0, DSBPLAY_LOOPING);
fTime = fFade;
}
void __fastcall TFadeSound::TurnOff()
{
State= ss_ShuttingDown;
}
void __fastcall TFadeSound::TurnOff() { State = ss_ShuttingDown; }
void __fastcall TFadeSound::Update()
{
if (State==ss_Starting)
if (State == ss_Starting)
{
fTime+= Timer::GetDeltaTime();
// SoundStart->SetVolume(-1000*(4-fTime)/4);
if (fTime>=fFade)
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);
fTime = fFade;
State = ss_Commencing;
Sound->SetVolume(-2000 * (fFade - fTime) / fFade);
Sound->SetFrequency(44100 - 500 + 500 * (fTime) / fFade);
}
else
if (Timer::GetSoundTimer())
else if (Timer::GetSoundTimer())
{
Sound->SetVolume(-2000*(fFade-fTime)/fFade);
Sound->SetFrequency(44100-500+500*(fTime)/fFade);
Sound->SetVolume(-2000 * (fFade - fTime) / fFade);
Sound->SetFrequency(44100 - 500 + 500 * (fTime) / fFade);
}
}
else
if (State==ss_ShuttingDown)
else if (State == ss_ShuttingDown)
{
fTime-= Timer::GetDeltaTime();
fTime -= Timer::GetDeltaTime();
if (fTime<=0)
if (fTime <= 0)
{
State= ss_Off;
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);
{ // 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);
float glos = 1;
Sound->SetVolume(vol * glos);
}
//---------------------------------------------------------------------------
#pragma package(smart_init)

View File

@@ -10,19 +10,19 @@ class TFadeSound
{
PSound Sound;
float fFade;
float dt,fTime;
float dt, fTime;
TSoundState State;
public:
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); };
bool __fastcall Playing() { return (State == ss_Commencing || State == ss_Starting); };
void __fastcall Free();
void __fastcall Update();
void __fastcall Volume(long vol);
};
//---------------------------------------------------------------------------

View File

@@ -10,18 +10,18 @@
#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
{ // 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
};

448
Float3d.h
View File

@@ -6,264 +6,274 @@
//---------------------------------------------------------------------------
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;
{ // 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 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+=(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 &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);
};
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 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;
{ // 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);
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);};
{ // 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 &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 &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 &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 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
{ // 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;
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 &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
);
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;
{ // 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);}
{ // 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 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)
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;
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;
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 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);
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);
{ // 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

View File

@@ -5,6 +5,6 @@
//---------------------------------------------------------------------------
class Forth
{//klasa obs³ugi jêzyka
{ // klasa obs³ugi jêzyka
};
#endif

303
Gauge.cpp
View File

@@ -6,8 +6,8 @@
*/
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
#include "Timer.h"
@@ -18,200 +18,199 @@
__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;
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()
{
};
__fastcall TGauge::~TGauge(){};
void __fastcall TGauge::Clear()
{
SubModel=NULL;
eType=gt_Unknown;
fValue=0;
fDesiredValue=0;
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
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
}
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)
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
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);
}
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;
{ // 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;
{ // 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;
{ // 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;
{ // 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);
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;
}
}
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::Render(){};
void __fastcall TGauge::AssignFloat(float* fValue)
void __fastcall TGauge::AssignFloat(float *fValue)
{
cDataType='f';
fData=fValue;
cDataType = 'f';
fData = fValue;
};
void __fastcall TGauge::AssignDouble(double* dValue)
void __fastcall TGauge::AssignDouble(double *dValue)
{
cDataType='d';
dData=dValue;
cDataType = 'd';
dData = dValue;
};
void __fastcall TGauge::AssignInt(int* iValue)
void __fastcall TGauge::AssignInt(int *iValue)
{
cDataType='i';
iData=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;
}
{ // 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)

91
Gauge.h
View File

@@ -5,57 +5,60 @@
//#include "Classes.h"
#include "QueryParserComp.hpp"
//class Queryparsercomp::TQueryParserComp;
// 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
{ // 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
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

163
Geom.cpp
View File

@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#include <gl/gl.h>
#include <gl/glu.h>
#include "opengl/glut.h"
@@ -12,108 +12,101 @@
#include "Globals.h"
#include "Geom.h"
__fastcall TGeometry::TGeometry() {}
__fastcall TGeometry::TGeometry()
{
}
__fastcall TGeometry::~TGeometry()
{
}
bool __fastcall TGeometry::Init()
{
}
__fastcall TGeometry::~TGeometry() {}
bool __fastcall TGeometry::Init() {}
vector3 __fastcall TGeometry::Load(TQueryParserComp *Parser)
{
str= Parser->GetNextSymbol().LowerCase();
tmp->TextureID= TTexturesManager::GetTextureID(str.c_str());
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;
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].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();;
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;
// 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.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;
TempVerts[i].Point += pOrigin;
tmp->pCenter += TempVerts[i].Point;
i++;
i++;
// }
} while ( Parser->GetNextSymbol().LowerCase()!="endtri" );
// }
} while (Parser->GetNextSymbol().LowerCase() != "endtri");
nv= i;
tmp->Init(nv);
tmp->pCenter/= (nv>0?nv:1);
nv = i;
tmp->Init(nv);
tmp->pCenter /= (nv > 0 ? nv : 1);
// memcpy(tmp->Vertices,TempVerts,nv*sizeof(TGroundVertex));
// 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;
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()
{
}
bool __fastcall TGeometry::Render() {}
//---------------------------------------------------------------------------
#pragma package(smart_init)

7
Geom.h
View File

@@ -10,12 +10,12 @@ struct TGeomVertex
{
vector3 Point;
vector3 Normal;
double tu,tv;
double tu, tv;
};
class TGeometry
{
private:
private:
GLuint iType;
union
{
@@ -26,7 +26,8 @@ private:
TMaterialColor Ambient;
TMaterialColor Diffuse;
TMaterialColor Specular;
public:
public:
__fastcall TGeometry();
__fastcall ~TGeometry();
bool __fastcall Init();

File diff suppressed because it is too large Load Diff

507
Globals.h
View File

@@ -11,295 +11,298 @@
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;
// 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_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_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_Czuwak = 32;
const int k_Horn = 33;
const int k_Horn2 = 34;
const int k_FailedEngineCutOff= 35;
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_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_CabForward = 42;
const int k_CabBackward = 43;
const int k_Couple= 44;
const int k_DeCouple= 45;
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_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_Heating = 58;
//const int k_FreeFlyMode= 59;
// const int k_FreeFlyMode= 59;
const int k_LeftSign = 60;
const int k_UpperSign= 61;
const int k_RightSign= 62;
const int k_UpperSign = 61;
const int k_RightSign = 62;
const int k_SmallCompressor= 63;
const int k_SmallCompressor = 63;
const int k_StLinOff= 64;
const int k_StLinOff = 64;
const int k_CurrentNext=65;
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_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;
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
// klasy dla wskaŸników globalnych
class TGround;
class TWorld;
class TCamera;
class TDynamicObject;
class TAnimModel; //obiekt terenu
class TAnimModel; // obiekt terenu
namespace Queryparsercomp
{
class TQueryParserComp; //stary(?) parser
class TQueryParserComp; // stary(?) parser
}
class cParser; //nowy (powolny!) 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
{ // 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ê)
{ // 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);
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);
};
//---------------------------------------------------------------------------

8808
Ground.cpp

File diff suppressed because it is too large Load Diff

665
Ground.h
View File

@@ -10,358 +10,379 @@
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
// 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
};
{ // 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;
}
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 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
{ // 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();
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)
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;
};
// 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 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
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
{ // 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;
// 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();
{ // 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]; };
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();
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;
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);
__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);
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

123
Logs.cpp
View File

@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
#include "Logs.h"
@@ -11,84 +11,85 @@
#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
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";
char endstring[10] = "\n";
void __fastcall WriteConsoleOnly(const char* str, double value)
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);
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)
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);
// 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)
void __fastcall WriteLog(const char *str, double value)
{
if (Global::iWriteLogEnabled)
{
if (str)
{
char buf[255];
sprintf(buf,"%s %f",str,value);
WriteLog(buf);
}
}
if (Global::iWriteLogEnabled)
{
if (str)
{
char buf[255];
sprintf(buf, "%s %f", str, value);
WriteLog(buf);
}
}
};
void __fastcall WriteLog(const char* str)
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);
}
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 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)
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());
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¿
{ // 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());
};
void __fastcall WriteLog(const AnsiString &str) { // Ra: wersja z AnsiString jest zamienna z Error() WriteLog(str.c_str()); };
//---------------------------------------------------------------------------
#pragma package(smart_init)

2
Logs.h
View File

@@ -8,7 +8,7 @@ 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 Error(const AnsiString &asMessage, bool box = true);
void __fastcall ErrorLog(const AnsiString &asMessage);
void __fastcall WriteLog(const AnsiString &str);
//---------------------------------------------------------------------------

View File

@@ -1,23 +1,16 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#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() : TTrain() { TTrain::TTrain(); }
__fastcall TMachajka::~TMachajka()
{
}
__fastcall TMachajka::~TMachajka() {}
bool __fastcall TMachajka::Init(TDynamicObject *NewDynamicObject)
{
@@ -27,68 +20,47 @@ bool __fastcall TMachajka::Init(TDynamicObject *NewDynamicObject)
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));
}
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::Update(double dt) { TTrain::Update(dt); }
bool __fastcall TMachajka::UpdateMechPosition()
{
TTrain::UpdateMechPosition();
}
bool __fastcall TMachajka::UpdateMechPosition() { TTrain::UpdateMechPosition(); }
bool __fastcall TMachajka::Render()
{
TTrain::Render();
}
bool __fastcall TMachajka::Render() { TTrain::Render(); }
//---------------------------------------------------------------------------
#pragma package(smart_init)

View File

@@ -5,17 +5,17 @@
#include "Train.h"
class TMachajka:public TTrain
class TMachajka : public TTrain
{
public:
public:
TSubModel *wajcha;
// double v;
// double m;
// double a;
// double f;
// bool enter;
// bool space;
// double wa,wv;
// 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);
@@ -25,6 +25,5 @@ public:
virtual bool __fastcall Render();
};
//---------------------------------------------------------------------------
#endif

View File

@@ -6,8 +6,8 @@
*/
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#include "Texture.h"
#pragma hdrstop
@@ -16,26 +16,26 @@
#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;
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;
const MAX_MODELS = 1000;
void __fastcall TModelsManager::Init()
{
Models=new TMdlContainer[MAX_MODELS];
Count=0;
Models = new TMdlContainer[MAX_MODELS];
Count = 0;
}
/*
__fastcall TModelsManager::TModelsManager()
@@ -50,115 +50,122 @@ __fastcall TModelsManager::~TModelsManager()
Free();
};
*/
void __fastcall TModelsManager::Free()
{
SafeDeleteArray(Models);
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::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(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
};
/*

View File

@@ -2,33 +2,41 @@
#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);
__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:
{ // 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 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);
// McZapkie: dodalem sciezke, notabene Path!=Patch :)
static TModel3d *__fastcall GetModel(const char *Name, bool dynamic = false);
};
//---------------------------------------------------------------------------
#endif

View File

@@ -6,7 +6,6 @@
*/
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
@@ -26,151 +25,153 @@
__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;
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);
}
__fastcall TMemCell::~TMemCell() { SafeDeleteArray(szText); }
void __fastcall TMemCell::Init()
{
}
void __fastcall TMemCell::Init() {}
void __fastcall TMemCell::UpdateValues(char *szNewText, double fNewValue1, double fNewValue2, int CheckMask)
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ê
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;
{ // 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;
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);
{ // 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::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::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);
{ // 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);
{ //
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;
};
void __fastcall TMemCell::AssignEvents(TEvent *e) { // powi¹zanie eventu OnSent = e; };

View File

@@ -9,34 +9,37 @@ 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);
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);
};
//---------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

581
Model3d.h
View File

@@ -11,44 +11,47 @@ using namespace Math3D;
struct GLVERTEX
{
vector3 Point;
vector3 Normal;
float tu,tv;
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;};
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)
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;
r = R;
g = G;
b = B;
};
char r,g,b;
char r, g, b;
};
/*
@@ -56,7 +59,8 @@ struct TMaterial
{
int ID;
AnsiString Name;
//McZapkie-240702: lepiej uzywac wartosci float do opisu koloru bo funkcje opengl chyba tego na ogol uzywaja
//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];
@@ -100,265 +104,298 @@ typedef enum
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;
// 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
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();
{ // 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() {};
{ // 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);
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);
};
//---------------------------------------------------------------------------

1007
Mover.cpp

File diff suppressed because it is too large Load Diff

310
Mover.h
View File

@@ -13,161 +13,167 @@
#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
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);
//
{ // 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

231
Names.cpp
View File

@@ -31,137 +31,146 @@ Obiekty sortowane wg nazw, mo
*/
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::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::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;
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;
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*));
{ // 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)
{ // 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 __fastcall TNames::Add(int t, const char *n, void *d)
{
int i=Add(t,n);
rRecords[iLast].pData=d;
return i;
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
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];
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;
{ // 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;
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;
};

85
Names.h
View File

@@ -4,50 +4,53 @@
#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);
{ // 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));};
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

View File

@@ -5,8 +5,8 @@
*/
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
#include "math.h"
@@ -18,260 +18,273 @@
__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
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();
// if (this) if (pSound) pSound->Stop();
}
void __fastcall TRealSound::Free()
{
}
void __fastcall TRealSound::Free() {}
void __fastcall TRealSound::Init(char *SoundName, double DistanceAttenuation, double X, double Y, double Z,bool Dynamic,bool freqmod,double rmin)
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;
// 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); }
if (dSoundAtt == -1)
{
return 0.0;
}
else
{
return SquareMagnitude(ListenerPosition - vSoundPosition);
}
}
void __fastcall TRealSound::Play(double Volume, int Looping, bool ListenerInside, vector3 NewPosition)
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
*/
}
}
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::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();
}
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
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
float df, Vlist, Vsrc;
if ((Global::bSoundEnabled) && (AM != 0))
{
Vlist=(sqrt(fPreviousDistance)-sqrt(fDistance))/dt;
df= Freq*(1+Vlist/299.8);
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)));
}
}
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
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);
}
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;
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);
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);
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;
}
} while (i>0);
}
}
TRealSound::Play(Volume,Looping,ListenerInside,NewPosition);
};
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)

View File

@@ -7,60 +7,62 @@
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;};
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);
{ // 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?
{ // 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

View File

@@ -8,16 +8,13 @@ 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::Register(Resource *resource) { _resources.push_back(resource); };
void ResourceManager::Unregister(Resource* resource)
void ResourceManager::Unregister(Resource *resource)
{
Resources::iterator iter = std::find(_resources.begin(), _resources.end(), resource);
if(iter != _resources.end())
if (iter != _resources.end())
_resources.erase(iter);
resource->Release();
@@ -25,35 +22,33 @@ void ResourceManager::Unregister(Resource* resource)
class ResourceExpired
{
public:
ResourceExpired(double time): _time(time) { };
bool operator()(Resource* resource)
{
return (resource->GetLastUsage() < _time);
}
public:
ResourceExpired(double time) : _time(time){};
bool operator()(Resource *resource) { return (resource->GetLastUsage() < _time); }
private:
private:
double _time;
};
void ResourceManager::Sweep(double currentTime)
{
if(currentTime - _lastUpdate < _expiry)
if (currentTime - _lastUpdate < _expiry)
return;
Resources::iterator begin = std::remove_if(_resources.begin(), _resources.end(), ResourceExpired(currentTime - _expiry));
Resources::iterator begin = std::remove_if(_resources.begin(), _resources.end(),
ResourceExpired(currentTime - _expiry));
#ifdef RESOURCE_REPORTING
if(begin != _resources.end())
if (begin != _resources.end())
WriteLog("Releasing resources");
#endif
for(Resources::iterator iter = begin; iter != _resources.end(); iter++)
for (Resources::iterator iter = begin; iter != _resources.end(); iter++)
(*iter)->Release();
#ifdef RESOURCE_REPORTING
if(begin != _resources.end())
if (begin != _resources.end())
{
std::ostringstream msg;
msg << "Released " << (_resources.end() - begin) << " resources";
@@ -64,7 +59,7 @@ void ResourceManager::Sweep(double currentTime)
_resources.erase(begin, _resources.end());
#ifdef RESOURCE_REPORTING
if(currentTime - _lastReport > 30.0f)
if (currentTime - _lastReport > 30.0f)
{
std::ostringstream msg;
msg << "Resources count: " << _resources.size();
@@ -74,5 +69,4 @@ void ResourceManager::Sweep(double currentTime)
#endif
_lastUpdate = currentTime;
};

View File

@@ -9,37 +9,35 @@
class Resource
{
public:
public:
virtual void Release() = 0;
double GetLastUsage() const { return _lastUsage; }
protected:
protected:
void SetLastUsage(double lastUsage) { _lastUsage = lastUsage; }
private:
private:
double _lastUsage;
};
class ResourceManager
{
public:
static void Register(Resource* resource);
static void Unregister(Resource* resource);
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;
private:
typedef std::vector<Resource *> Resources;
static double _expiry;
static double _lastUpdate;
static double _lastReport;
static Resources _resources;
};
#endif

File diff suppressed because it is too large Load Diff

193
Segment.h
View File

@@ -9,95 +9,120 @@
using namespace Math3D;
//110405 Ra: klasa punktów przekroju z normalnymi
// 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;};
{ // 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
{ // 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
};
//---------------------------------------------------------------------------

441
Sound.cpp
View File

@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
#define STRICT
@@ -9,114 +9,115 @@
#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; } }
#define SAFE_RELEASE(p) \
{ \
if (p) \
{ \
(p)->Release(); \
(p) = NULL; \
} \
}
char Directory[]= "sounds\\";
char Directory[] = "sounds\\";
LPDIRECTSOUND TSoundsManager::pDS;
LPDIRECTSOUND TSoundsManager::pDS;
LPDIRECTSOUNDNOTIFY TSoundsManager::pDSNotify;
int TSoundsManager::Count= 0;
TSoundContainer *TSoundsManager::First=NULL;
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
__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;
Concurrent= NConcurrent;
Oldest = 0;
// strcpy(Name, strFileName);
Oldest= 0;
// strcpy(Name, strFileName);
strcpy(Name,Directory);
strcat(Name,strFileName);
CWaveSoundRead* pWaveSoundRead;
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));
}
if (FAILED(pWaveSoundRead->Open(strFileName)))
{
// SetFileUI( hDlg, TEXT("Bad wave file.") );
return;
ErrorLog("Missed sound: " + AnsiString(strFileName));
}
strcpy(Name,AnsiString(strFileName).LowerCase().c_str());
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
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;
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;
// 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;
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;
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;
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 ;
// 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 ;
// 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 );
memcpy(pbData, pbWavData, dwBufferBytes);
// Unlock the buffer, we don't need it anymore.
DSBuffer->Unlock( pbData, dwBufferBytes, NULL, 0 );
DSBuffer->Unlock(pbData, dwBufferBytes, NULL, 0);
pbData = NULL;
// We dont need the wav file data buffer anymore, so delete it
@@ -126,154 +127,149 @@ __fastcall TSoundContainer::TSoundContainer( LPDIRECTSOUND pDS, char *Directory,
DSBuffers.push(DSBuffer);
/*
for (int i=1; i<Concurrent; i++)
{
if( FAILED( hr= pDS->DuplicateSoundBuffer(pDSBuffer[0],&(pDSBuffer[i]))))
/*
for (int i=1; i<Concurrent; i++)
{
Concurrent= i;
break;
};
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);
// 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 );
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();
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();
};
__fastcall TSoundsManager::~TSoundsManager() { Free(); };
void __fastcall TSoundsManager::Free()
{
SafeDelete( First );
SAFE_RELEASE( pDS );
SafeDelete(First);
SAFE_RELEASE(pDS);
};
TSoundContainer* __fastcall TSoundsManager::LoadFromFile(char *Dir,char *Name,int Concurrent)
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)
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);
{ // 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]);
};
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++)
{
/* 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);
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;
TSoundContainer *Next = First;
HRESULT hr;
DWORD dwStatus;
for (int i=0; i<Count; i++)
for (int i = 0; i < Count; i++)
{
if (FAILED(hr = Next->DSBuffer->GetStatus(&dwStatus)))
;
// return hr;
if( FAILED( hr = Next->DSBuffer->GetStatus( &dwStatus ) ) );
// return hr;
if( dwStatus & DSBSTATUS_BUFFERLOST )
if (dwStatus & DSBSTATUS_BUFFERLOST)
{
// Since the app could have just been activated, then
// DirectSound may not be giving us control yet, so
@@ -282,96 +278,91 @@ void __fastcall TSoundsManager::RestoreAll()
do
{
hr = Next->DSBuffer->Restore();
if( hr == DSERR_BUFFERLOST )
Sleep( 10 );
}
while ((hr=Next->DSBuffer->Restore())!=NULL);
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;
// 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;
Next = Next->Next;
};
};
//void __fastcall TSoundsManager::Init(char *Name, int Concurrent)
// 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, char *NDirectory)
void __fastcall TSoundsManager::Init(HWND hWnd)
{
First= NULL;
Count= 0;
pDS= NULL;
pDSNotify= NULL;
First = NULL;
Count = 0;
pDS = NULL;
pDSNotify = NULL;
HRESULT hr; //=222;
HRESULT hr; //=222;
LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;
// strcpy(Directory, NDirectory);
// strcpy(Directory, NDirectory);
// Create IDirectSound using the primary sound device
hr = DirectSoundCreate( NULL, &pDS, NULL );
if( hr!=DS_OK )
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;
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;
// hr=0;
};
// return ;
// return ;
// Set coop level to DSSCL_PRIORITY
// if( FAILED( hr = pDS->SetCooperativeLevel( hWnd, DSSCL_PRIORITY ) ) );
// return ;
pDS->SetCooperativeLevel( hWnd, 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
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;
dsbd.lpwfxFormat = NULL;
if( FAILED( hr = pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL ) ) )
return ;
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;
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 );
if (FAILED(hr = pDSBPrimary->SetFormat(&wfx)))
return;
SAFE_RELEASE(pDSBPrimary);
};
//---------------------------------------------------------------------------
#pragma package(smart_init)

64
Sound.h
View File

@@ -14,47 +14,49 @@
typedef LPDIRECTSOUNDBUFFER PSound;
//inline __fastcall Playing(PSound Sound)
// 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();
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();
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();
};
//---------------------------------------------------------------------------

View File

@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
#include "Geometry.h"
@@ -11,13 +11,12 @@
//#define asSplinesPatch AnsiString("Scenery\\")
bool __fastcall Connect(TKnot *k1, TKnot *k2)
{
if (k1 && k2)
{
k1->Next= k2;
k2->Prev= k1;
k1->Next = k2;
k2->Prev = k1;
k1->InitLength();
return true;
}
@@ -28,140 +27,142 @@ bool __fastcall Connect(TKnot *k1, TKnot *k2)
#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++)
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;
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;
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)
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;
Next = new TKnot(n - 1);
Next->Prev = this;
}
}
__fastcall TKnot::~TKnot()
{
}
__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);
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);
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);
int it = 0;
float fTolerance = 0.001;
float fRatio = s / RombergIntegral(0, 1);
float fOmRatio = 1.0 - fRatio;
float fTime = fOmRatio*0 + fRatio*1;
float fTime = fOmRatio * 0 + fRatio * 1;
// for (int i = 0; i < iIterations; i++)
// for (int i = 0; i < iIterations; i++)
while (true)
{
it++;
if (it>10)
MessageBox(0,"Too many iterations","TSpline->GetTFromS",MB_OK);
if (it > 10)
MessageBox(0, "Too many iterations", "TSpline->GetTFromS", MB_OK);
float fDifference = RombergIntegral(0,fTime) - s;
if ( ( fDifference>0 ? fDifference : -fDifference) < fTolerance )
float fDifference = RombergIntegral(0, fTime) - s;
if ((fDifference > 0 ? fDifference : -fDifference) < fTolerance)
return fTime;
fTime -= fDifference/GetFirstDerivative(fTime).Length();
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)
if (NNext != NULL)
{
Next= NNext;
Next->Prev= this;
Next = NNext;
Next->Prev = this;
}
if (NPrev!=NULL)
if (NPrev != NULL)
{
Prev= NPrev;
Prev->Next= this;
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 (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);
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()
@@ -169,15 +170,13 @@ bool __fastcall TKnot::InitLength()
if (IsCurve)
if (Next)
Length= RombergIntegral(0,1);
else;
else
if (Next)
Length= (Point-Next->Point).Length();
Length = RombergIntegral(0, 1);
else
;
else if (Next)
Length = (Point - Next->Point).Length();
return true;
}
vector3 TKnot::GetFirstDerivative(float fTime)
@@ -185,15 +184,15 @@ vector3 TKnot::GetFirstDerivative(float fTime)
float fOmTime = 1.0 - fTime;
float fPowTime = fTime;
vector3 kResult = fOmTime*(CPointOut-Point);
vector3 kResult = fOmTime * (CPointOut - Point);
int iDegreeM1 = 3 - 1;
float fCoeff = 2*fPowTime;
kResult = (kResult+fCoeff*(Next->CPointIn-CPointOut))*fOmTime;
float fCoeff = 2 * fPowTime;
kResult = (kResult + fCoeff * (Next->CPointIn - CPointOut)) * fOmTime;
fPowTime *= fTime;
kResult += fPowTime*(Next->Point-Next->CPointIn);
kResult += fPowTime * (Next->Point - Next->CPointIn);
kResult *= 3;
return kResult;
@@ -203,316 +202,309 @@ float TKnot::RombergIntegral(float fA, float fB)
{
float fH = fB - fA;
const int ms_iOrder= 5;
const int ms_iOrder = 5;
float ms_apfRom[2][ms_iOrder];
ms_apfRom[0][0] = 0.5*fH*((GetFirstDerivative(fA).Length())+(GetFirstDerivative(fB).Length()));
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());
fSum += (GetFirstDerivative(fA + fH * (i1 - 0.5)).Length());
// Richardson extrapolation
ms_apfRom[1][0] = 0.5*(ms_apfRom[0][0] + fH*fSum);
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);
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];
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;
// 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;
// Closed= true;
// asName= asNName;
// Knots= NULL;
RootKnot = NULL;
iNumKnots = 0;
KnotsAllocated = false;
// Next=Prev= this;
}
__fastcall TSpline::~TSpline()
{
// if (KnotsAllocated)
// SafeDeleteArray(Knots);
// if (KnotsAllocated)
// SafeDeleteArray(Knots);
// SafeDelete(RootKnot);
// SafeDelete(RootKnot);
TKnot *ck,*tk;
ck= RootKnot;
TKnot *ck, *tk;
ck = RootKnot;
for (int i=0; i<iNumKnots; i++)
for (int i = 0; i < iNumKnots; i++)
{
tk= ck;
ck= ck->Next;
tk = ck;
ck = ck->Next;
SafeDelete(tk);
}
}
bool __fastcall TSpline::Create( int n, AnsiString asNName )
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);
*/
/*
// 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 )
bool __fastcall TSpline::AssignKnots(TKnot *FirstKnot, int n)
{
// iNumKnots= n;
// Knots= FirstKnot;
// KnotsAllocated= false;
// iNumKnots= n;
// Knots= FirstKnot;
// KnotsAllocated= false;
}
int __fastcall TSpline::LoadFromFile( AnsiString FileName, TKnot *FirstKnot )
int __fastcall TSpline::LoadFromFile(AnsiString FileName, TKnot *FirstKnot)
{
return false;
/*
int i;
/*
int i;
iNumKnots= -1;
iNumKnots= -1;
AnsiString buf;
buf.SetLength(255);
AnsiString buf;
buf.SetLength(255);
TMapTextfile *tf= new TMapTextfile();
tf->Open(asSceneryPatch+FileName,mmRead);
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++)
if (buf==AnsiString("\"SPLINE\""))
{
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);
}
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++)
{
CurrentKnot->CPointOut= 2*CurrentKnot->Point-CurrentKnot->CPointIn;
CurrentKnot->Next->CPointIn= CurrentKnot->Point;
CurrentKnot->Length= (CurrentKnot->Point-CurrentKnot->Next->Point).Length();
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;
}
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;
}
CurrentKnot->Length= -1;
}
tf->Close();
tf->Close();
delete tf;
delete tf;
return (iNumKnots);
*/
return (iNumKnots);
*/
}
int __fastcall TSpline::Load( TQueryParserComp *Parser, AnsiString asEndString )
int __fastcall TSpline::Load(TQueryParserComp *Parser, AnsiString asEndString)
{
TKnot *LastKnot= NULL;;
if (RootKnot!=NULL)
for (LastKnot= RootKnot; LastKnot->Next!=NULL; LastKnot= LastKnot->Next);
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;
tmp = new TKnot(0);
tmp->Prev = LastKnot;
if (LastKnot != NULL)
LastKnot->Next = tmp;
else
RootKnot= tmp;
RootKnot = tmp;
LastKnot= tmp;
LastKnot = tmp;
float tf,r,pr;
float tf, r, pr;
vector3 dir;
// asName= Parser->GetNextSymbol();
// asName= Parser->GetNextSymbol();
iNumKnots= 0;
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->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->fLengthOut = Parser->GetNextSymbol().ToDouble();
LastKnot->IsCurve= (LastKnot->fLengthOut!=0);
LastKnot->IsCurve = (LastKnot->fLengthOut != 0);
LastKnot->Next= new TKnot(0);
LastKnot->Next->Prev= LastKnot;
LastKnot= LastKnot->Next;
LastKnot->Next = new TKnot(0);
LastKnot->Next->Prev = LastKnot;
LastKnot = LastKnot->Next;
iNumKnots++;
} while (Parser->GetNextSymbol().LowerCase() != asEndString && !Parser->EOF);
} while (Parser->GetNextSymbol().LowerCase()!=asEndString && !Parser->EOF);
LastKnot->Prev->Next= NULL;
LastKnot->Prev->Next = NULL;
delete LastKnot;
if (RootKnot!=NULL)
for (LastKnot= RootKnot; LastKnot!=NULL; LastKnot= LastKnot->Next)
if (RootKnot != NULL)
for (LastKnot = RootKnot; LastKnot != NULL; LastKnot = LastKnot->Next)
LastKnot->InitCPoints();
if (RootKnot!=NULL)
for (LastKnot= RootKnot; LastKnot!=NULL; LastKnot= LastKnot->Next)
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++)
TKnot *tmp = RootKnot;
float l = 0;
for (int i = 0; i < iNumKnots; i++)
{
l+= tmp->Length;
tmp= tmp->Next;
l += tmp->Length;
tmp = tmp->Next;
}
return l;
}
vector3 __fastcall TSpline::GetCenter()
{
TKnot *ck,*tk;
ck= RootKnot;
vector3 pt= vector3(0,0,0);
TKnot *ck, *tk;
ck = RootKnot;
vector3 pt = vector3(0, 0, 0);
for (int i=0; i<iNumKnots; i++)
for (int i = 0; i < iNumKnots; i++)
{
pt+= ck->Point;
ck= ck->Next;
pt += ck->Point;
ck = ck->Next;
}
if (iNumKnots>0)
pt/= iNumKnots;
if (iNumKnots > 0)
pt /= iNumKnots;
}
TKnot* __fastcall TSpline::GetLastKnot()
TKnot *__fastcall TSpline::GetLastKnot()
{
TKnot *ck;
ck= RootKnot;
ck = RootKnot;
for (int i=0; i<iNumKnots-1; i++)
for (int i = 0; i < iNumKnots - 1; i++)
{
ck= ck->Next;
ck = ck->Next;
}
return ck;
}
bool __fastcall TSpline::Render()
{
TKnot *LastKnot= NULL;;
TKnot *LastKnot = NULL;
;
// if (RootKnot==NULL)
// RootKnot= Knots;
// if (RootKnot==NULL)
// RootKnot= Knots;
if (RootKnot!=NULL)
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);
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();
}*/
/*
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)

View File

@@ -6,17 +6,17 @@
#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)
#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); };
public:
// inline bool __fastcall IsCurve() { return (!(Point==CPointIn)); };
// inline vector3 __fastcall GetDirection() { return (CPointOut-Point); };
__fastcall TKnot();
__fastcall TKnot(int n);
__fastcall ~TKnot();
@@ -24,63 +24,69 @@ public:
{
if (Next)
{
s/= Length;
return ((1-s)*fRoll+(s)*Next->fRoll);
s /= Length;
return ((1 - s) * fRoll + (s)*Next->fRoll);
}
else
return fRoll;
// (Length-s) (s-Length)
// (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) ); };
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;
vector3 Point, CPointIn, CPointOut;
float fRoll;
bool IsCurve;
float Length;
TKnot *Next,*Prev;
float fLengthIn,fLengthOut;
TKnot *Next, *Prev;
float fLengthIn, fLengthOut;
bool bSwitchDirectionForward;
bool bSwitchDirectionBackward;
private:
private:
vector3 GetFirstDerivative(float fTime);
float RombergIntegral (float fA, float fB);
float RombergIntegral(float fA, float fB);
};
class TSpline
{
public:
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" );
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();
TKnot *__fastcall GetLastKnot();
bool __fastcall Render();
// inline int NextIndex(int n) { return (n<KnotsCount-1 ? n+1 : 0); };
// 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;
// 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:
// TSpline *Next,*Prev;
// TKnot Next,Prev;
private:
};
bool __fastcall Connect(TKnot *k1, TKnot *k2);

View File

@@ -1,7 +1,7 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#include "opengl/glew.h"
#include "opengl/glut.h"
#pragma hdrstop
@@ -9,70 +9,63 @@
#include "Spring.h"
#include "Usefull.h"
__fastcall TSpring::TSpring()
{
vForce1=vForce2= vector3(0,0,0);
Ks= 0;
Kd= 0;
restLen= 0;
vForce1 = vForce2 = vector3(0, 0, 0);
Ks = 0;
Kd = 0;
restLen = 0;
}
__fastcall TSpring::~TSpring()
{
}
__fastcall TSpring::~TSpring() {}
void __fastcall TSpring::Init(double nrestLen, double nKs, double nKd)
{
Ks= nKs;
Kd= nKd;
restLen= nrestLen;
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)
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);
vForce1 = vForce2 = vector3(0, 0, 0);
return false;
}
// Hterm = (dist - spring->restLen) * spring->Ks; // Ks * (dist - rest)
Hterm= (dist - restLen) * Ks; // Ks * (dist - rest)
// 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;
// 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;
// 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()
{
// 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() {}
//---------------------------------------------------------------------------

View File

@@ -3,36 +3,35 @@
#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
#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
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:
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);
// 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:
vector3 vForce1, vForce2;
double restLen; // LENGTH OF SPRING AT REST
double Ks; // SPRING CONSTANT
double Kd; // SPRING DAMPING
private:
};
//---------------------------------------------------------------------------
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -24,35 +24,35 @@ void __fastcall glDebug()
class TTexturesManager
{
public:
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 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:
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 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 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 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;
// std::list<TTexture> Textures;
};
//---------------------------------------------------------------------------
#endif

View File

@@ -1,299 +1,330 @@
#include "TextureDDS.h"
void DxtcReadColors(const GLubyte* Data, Color8888* result)
void DxtcReadColors(const GLubyte *Data, Color8888 *result)
{
GLubyte r0, g0, b0, r1, g1, b1;
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;
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;
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[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;
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)
void DxtcReadColor(GLushort Data, Color8888 *Out)
{
GLubyte r, g, b;
GLubyte r, g, b;
b = Data & 0x1f;
g = (Data & 0x7E0) >> 5;
r = (Data & 0xF800) >> 11;
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;
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;
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;
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));
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];
DxtcReadColor(color_0, colours);
DxtcReadColor(color_1, colours + 1);
bitmask = ((const GLuint *)Temp)[1];
Temp += 8;
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
if (color_0 > color_1)
{
// 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;
// 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 = 0x00;
}
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;
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];
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;
}
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;
}
}
}
}
}
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;
const GLubyte *Temp = lCompData;
Color8888 colours[4], *col;
GLuint bitmask, Offset;
const GLubyte* alpha;
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];
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;
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;
// 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].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];
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;
}
}
}
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;
}
}
}
}
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;
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;
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;
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];
DxtcReadColors(Temp, colours);
bitmask = ((const GLuint *)Temp)[1];
Temp += 8;
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;
// 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].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++) {
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];
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;
}
}
}
// 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
}
// 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.
// 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;
}
}
// 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;
}
}
}
}
// 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)
switch (lImage.format)
{
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
DecompressDXT1(lImage, lCompData, Data);
break;
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;
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
DecompressDXT3(lImage, lCompData, Data);
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
DecompressDXT5(lImage, lCompData, Data);
break;
};
}

View File

@@ -7,24 +7,23 @@
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;
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;
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

144
Timer.cpp
View File

@@ -7,113 +7,85 @@
#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()
namespace Timer
{
return fSimulationTime;
}
double __fastcall GetDeltaTime()
{//czas symulacji (stoi gdy pauza)
return DeltaTime;
}
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 GetDeltaRenderTime()
{//czas renderowania (do poruszania siê)
return DeltaRenderTime;
}
double __fastcall GetTime() { return fSimulationTime; }
double __fastcall GetfSinceStart()
{
return fSinceStart;
}
double __fastcall GetDeltaTime() { // czas symulacji (stoi gdy pauza) return DeltaTime; }
void __fastcall SetDeltaTime(double t)
{
DeltaTime= t;
}
double __fastcall GetDeltaRenderTime() { // czas renderowania (do poruszania siê) return DeltaRenderTime; }
double __fastcall GetSimulationTime()
{
return fSimulationTime;
}
double __fastcall GetfSinceStart() { return fSinceStart; }
void __fastcall SetSimulationTime(double t)
{
fSimulationTime=t;
}
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);
}
{ // 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;
}
double __fastcall GetFPS() { return fFPS; }
void __fastcall ResetTimers()
{
//double CurrentTime=
GetTickCount();
DeltaTime=0.1;
DeltaRenderTime=0;
fSoundTimer=0;
// double CurrentTime=
GetTickCount();
DeltaTime = 0.1;
DeltaRenderTime = 0;
fSoundTimer = 0;
};
LONGLONG fr,count,oldCount;
//LARGE_INTEGER fr,count;
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;
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;
// 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)

View File

@@ -3,8 +3,8 @@
#ifndef TimerH
#define TimerH
namespace Timer {
namespace Timer
{
double __fastcall GetTime();
@@ -26,7 +26,6 @@ double __fastcall GetFPS();
void __fastcall ResetTimers();
void __fastcall UpdateTimers(bool pause);
};
//---------------------------------------------------------------------------

5324
Track.cpp

File diff suppressed because it is too large Load Diff

407
Track.h
View File

@@ -9,13 +9,29 @@
#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
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;
@@ -23,201 +39,216 @@ 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:
{ // 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
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); };
{ // 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
{ // 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);
__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 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 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 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();
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();
};
//---------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@@ -12,66 +12,69 @@ using namespace Math3D;
class TTractionPowerSource;
class TTraction
{//drut zasilaj¹cy, dla wskaŸników u¿ywaæ przedrostka "hv"
private:
//vector3 vUp,vFront,vLeft;
//matrix4x4 mMatrix;
//matryca do wyliczania pozycji drutu w zale¿noœci od [X,Y,k¹t] w scenerii:
// - x: odleg³oœæ w bok (czy odbierak siê nie zsun¹³)
// - y: przyjmuje wartoœæ <0,1>, jeœli pod drutem (wzd³u¿)
// - z: wysokoœæ bezwzglêdna drutu w danym miejsu
public: //na razie
TTractionPowerSource *psPower[2]; //najbli¿sze zasilacze z obu kierunków
TTractionPowerSource *psPowered; //ustawione tylko dla bezpoœrednio zasilanego przês³a
TTraction *hvNext[2]; //³¹czenie drutów w sieæ
int iNext[2]; //do którego koñca siê ³¹czy
int iLast; //ustawiony bit 0, jeœli jest ostatnim drutem w sekcji; bit1 - przedostatni
public:
GLuint uiDisplayList;
vector3 pPoint1,pPoint2,pPoint3,pPoint4;
vector3 vParametric; //wspó³czynniki równania parametrycznego odcinka
double fHeightDifference;//,fMiddleHeight;
//int iCategory,iMaterial,iDamageFlag;
//float fU,fR,fMaxI,fWireThickness;
int iNumSections;
int iLines; //ilosc linii dla VBO
float NominalVoltage;
float MaxCurrent;
float fResistivity; //[om/m], przeliczone z [om/km]
DWORD Material; //1: Cu, 2: Al
float WireThickness;
DWORD DamageFlag; //1: zasniedziale, 128: zerwana
int Wires;
float WireOffset;
AnsiString asPowerSupplyName; //McZapkie: nazwa podstacji trakcyjnej
TTractionPowerSource *psSection; //zasilacz (opcjonalnie mo¿e to byæ pulpit steruj¹cy EL2 w hali!)
AnsiString asParallel; //nazwa przês³a, z którym mo¿e byæ bie¿nia wspólna
TTraction *hvParallel; //jednokierunkowa i zapêtlona lista przêse³ ewentualnej bie¿ni wspólnej
float fResistance[2]; //rezystancja zastêpcza do punktu zasilania (0: przês³o zasilane, <0: do policzenia)
int iTries;
//bool bVisible;
//DWORD dwFlags;
{ // drut zasilaj¹cy, dla wskaŸników u¿ywaæ przedrostka "hv"
private:
// vector3 vUp,vFront,vLeft;
// matrix4x4 mMatrix;
// matryca do wyliczania pozycji drutu w zale¿noœci od [X,Y,k¹t] w scenerii:
// - x: odleg³oœæ w bok (czy odbierak siê nie zsun¹³)
// - y: przyjmuje wartoœæ <0,1>, jeœli pod drutem (wzd³u¿)
// - z: wysokoœæ bezwzglêdna drutu w danym miejsu
public: // na razie
TTractionPowerSource *psPower[2]; // najbli¿sze zasilacze z obu kierunków
TTractionPowerSource *psPowered; // ustawione tylko dla bezpoœrednio zasilanego przês³a
TTraction *hvNext[2]; //³¹czenie drutów w sieæ
int iNext[2]; // do którego koñca siê ³¹czy
int iLast; // ustawiony bit 0, jeœli jest ostatnim drutem w sekcji; bit1 - przedostatni
public:
GLuint uiDisplayList;
vector3 pPoint1, pPoint2, pPoint3, pPoint4;
vector3 vParametric; // wspó³czynniki równania parametrycznego odcinka
double fHeightDifference; //,fMiddleHeight;
// int iCategory,iMaterial,iDamageFlag;
// float fU,fR,fMaxI,fWireThickness;
int iNumSections;
int iLines; // ilosc linii dla VBO
float NominalVoltage;
float MaxCurrent;
float fResistivity; //[om/m], przeliczone z [om/km]
DWORD Material; // 1: Cu, 2: Al
float WireThickness;
DWORD DamageFlag; // 1: zasniedziale, 128: zerwana
int Wires;
float WireOffset;
AnsiString asPowerSupplyName; // McZapkie: nazwa podstacji trakcyjnej
TTractionPowerSource *
psSection; // zasilacz (opcjonalnie mo¿e to byæ pulpit steruj¹cy EL2 w hali!)
AnsiString asParallel; // nazwa przês³a, z którym mo¿e byæ bie¿nia wspólna
TTraction *hvParallel; // jednokierunkowa i zapêtlona lista przêse³ ewentualnej bie¿ni wspólnej
float fResistance[2]; // rezystancja zastêpcza do punktu zasilania (0: przês³o zasilane, <0: do
// policzenia)
int iTries;
// bool bVisible;
// DWORD dwFlags;
void __fastcall Optimize();
TTraction();
~TTraction();
// virtual void __fastcall InitCenter(vector3 Angles, vector3 pOrigin);
// virtual bool __fastcall Hit(double x, double z, vector3 &hitPoint, vector3 &hitDirection) { return TNode::Hit(x,z,hitPoint,hitDirection); };
// virtual bool __fastcall Move(double dx, double dy, double dz) { return false; };
// virtual void __fastcall SelectedRender();
void __fastcall RenderDL(float mgn);
int __fastcall RaArrayPrepare();
void __fastcall RaArrayFill(CVertNormTex *Vert);
void __fastcall RenderVBO(float mgn,int iPtr);
int __fastcall TestPoint(vector3 *Point);
void __fastcall Connect(int my,TTraction *with,int to);
void __fastcall Init();
bool __fastcall WhereIs();
void __fastcall ResistanceCalc(int d=-1,double r=0,TTractionPowerSource *ps=NULL);
void __fastcall PowerSet(TTractionPowerSource *ps);
double __fastcall VoltageGet(double u,double i);
// virtual void __fastcall InitCenter(vector3 Angles, vector3 pOrigin);
// virtual bool __fastcall Hit(double x, double z, vector3 &hitPoint, vector3 &hitDirection)
// { return TNode::Hit(x,z,hitPoint,hitDirection); };
// virtual bool __fastcall Move(double dx, double dy, double dz) { return false; };
// virtual void __fastcall SelectedRender();
void __fastcall RenderDL(float mgn);
int __fastcall RaArrayPrepare();
void __fastcall RaArrayFill(CVertNormTex *Vert);
void __fastcall RenderVBO(float mgn, int iPtr);
int __fastcall TestPoint(vector3 *Point);
void __fastcall Connect(int my, TTraction *with, int to);
void __fastcall Init();
bool __fastcall WhereIs();
void __fastcall ResistanceCalc(int d = -1, double r = 0, TTractionPowerSource *ps = NULL);
void __fastcall PowerSet(TTractionPowerSource *ps);
double __fastcall VoltageGet(double u, double i);
};
//---------------------------------------------------------------------------
#endif

View File

@@ -6,9 +6,8 @@
*/
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
#include "Mover.h"
@@ -24,131 +23,137 @@
__fastcall TTractionPowerSource::TTractionPowerSource()
{
NominalVoltage=0;
VoltageFrequency=0;
InternalRes=0.2;
MaxOutputCurrent=0;
FastFuseTimeOut=1;
FastFuseRepetition=3;
SlowFuseTimeOut=60;
Recuperation=false;
NominalVoltage = 0;
VoltageFrequency = 0;
InternalRes = 0.2;
MaxOutputCurrent = 0;
FastFuseTimeOut = 1;
FastFuseRepetition = 3;
SlowFuseTimeOut = 60;
Recuperation = false;
TotalAdmitance=1e-10; //10Mom - jakaœ tam up³ywnoœæ
TotalPreviousAdmitance=1e-10; //zero jest szkodliwe
OutputVoltage=0;
FastFuse=false;
SlowFuse=false;
FuseTimer=0;
FuseCounter=0;
psNode[0]=NULL; //sekcje zostan¹ pod³¹czone do zasilaczy
psNode[1]=NULL;
bSection=false; //sekcja nie jest Ÿród³em zasilania, tylko grupuje przês³a
TotalAdmitance = 1e-10; // 10Mom - jakaœ tam up³ywnoœæ
TotalPreviousAdmitance = 1e-10; // zero jest szkodliwe
OutputVoltage = 0;
FastFuse = false;
SlowFuse = false;
FuseTimer = 0;
FuseCounter = 0;
psNode[0] = NULL; // sekcje zostan¹ pod³¹czone do zasilaczy
psNode[1] = NULL;
bSection = false; // sekcja nie jest Ÿród³em zasilania, tylko grupuje przês³a
};
__fastcall TTractionPowerSource::~TTractionPowerSource()
{
};
__fastcall TTractionPowerSource::~TTractionPowerSource(){};
void __fastcall TTractionPowerSource::Init(double u,double i)
{//ustawianie zasilacza przy braku w scenerii
NominalVoltage=u;
VoltageFrequency=0;
MaxOutputCurrent=i;
void __fastcall TTractionPowerSource::Init(double u, double i)
{ // ustawianie zasilacza przy braku w scenerii
NominalVoltage = u;
VoltageFrequency = 0;
MaxOutputCurrent = i;
};
bool __fastcall TTractionPowerSource::Load(cParser *parser)
{
std::string token;
//AnsiString str;
//str= Parser->GetNextSymbol()LowerCase();
//asName= str;
parser->getTokens(5);
*parser >> NominalVoltage >> VoltageFrequency >> InternalRes >> MaxOutputCurrent >> FastFuseTimeOut;
parser->getTokens();
*parser >> FastFuseRepetition;
parser->getTokens();
*parser >> SlowFuseTimeOut;
parser->getTokens();
*parser >> token;
if (token.compare("recuperation")==0)
Recuperation=true;
else if (token.compare("section")==0) //od³¹cznik sekcyjny
bSection=true; //nie jest Ÿród³em zasilania, a jedynie informuje o pr¹dzie od³¹czenia sekcji z obwodu
parser->getTokens();
*parser >> token;
if (token.compare("end")!=0)
Error("tractionpowersource end statement missing");
//if (!bSection) //od³¹cznik sekcji zasadniczo nie ma impedancji (0.01 jest OK)
if (InternalRes<0.1) //coœ ma³a ta rezystancja by³a...
InternalRes=0.2; //tak oko³o 0.2, wg http://www.ikolej.pl/fileadmin/user_upload/Seminaria_IK/13_05_07_Prezentacja_Kruczek.pdf
return true;
std::string token;
// AnsiString str;
// str= Parser->GetNextSymbol()LowerCase();
// asName= str;
parser->getTokens(5);
*parser >> NominalVoltage >> VoltageFrequency >> InternalRes >> MaxOutputCurrent >>
FastFuseTimeOut;
parser->getTokens();
*parser >> FastFuseRepetition;
parser->getTokens();
*parser >> SlowFuseTimeOut;
parser->getTokens();
*parser >> token;
if (token.compare("recuperation") == 0)
Recuperation = true;
else if (token.compare("section") == 0) // od³¹cznik sekcyjny
bSection = true; // nie jest Ÿród³em zasilania, a jedynie informuje o pr¹dzie od³¹czenia
// sekcji z obwodu
parser->getTokens();
*parser >> token;
if (token.compare("end") != 0)
Error("tractionpowersource end statement missing");
// if (!bSection) //od³¹cznik sekcji zasadniczo nie ma impedancji (0.01 jest OK)
if (InternalRes < 0.1) // coœ ma³a ta rezystancja by³a...
InternalRes =
0.2; // tak oko³o 0.2, wg
// http://www.ikolej.pl/fileadmin/user_upload/Seminaria_IK/13_05_07_Prezentacja_Kruczek.pdf
return true;
};
bool __fastcall TTractionPowerSource::Render()
{
return true;
};
bool __fastcall TTractionPowerSource::Render() { return true; };
bool __fastcall TTractionPowerSource::Update(double dt)
{//powinno byæ wykonane raz na krok fizyki
if (NominalVoltage*TotalPreviousAdmitance>MaxOutputCurrent) //iloczyn napiêcia i admitancji daje pr¹d
{
FastFuse=true;
FuseCounter+=1;
if (FuseCounter>FastFuseRepetition)
{SlowFuse=true;
ErrorLog("Power overload: \""+gMyNode->asName+"\" disabled for "+AnsiString(SlowFuseTimeOut)+"s");
}
else
ErrorLog("Power overload: \""+gMyNode->asName+"\" disabled for "+AnsiString(FastFuseTimeOut)+"s");
FuseTimer=0;
}
if (FastFuse||SlowFuse)
{//jeœli któryœ z bezpieczników zadzia³a³
TotalAdmitance=0;
FuseTimer+=dt;
if (!SlowFuse)
{//gdy szybki, odczekaæ krótko i za³¹czyæ
if (FuseTimer>FastFuseTimeOut)
FastFuse=false;
}
else
if (FuseTimer>SlowFuseTimeOut)
{SlowFuse=false;
FuseCounter=0; //dajemy znów szansê
}
}
TotalPreviousAdmitance=TotalAdmitance; //u¿ywamy admitancji z poprzedniego kroku
if (TotalPreviousAdmitance==0.0)
TotalPreviousAdmitance=1e-10; //przynajmniej minimalna up³ywnoœæ
TotalAdmitance=1e-10; //a w aktualnym kroku sumujemy admitancjê
return true;
{ // powinno byæ wykonane raz na krok fizyki
if (NominalVoltage * TotalPreviousAdmitance >
MaxOutputCurrent) // iloczyn napiêcia i admitancji daje pr¹d
{
FastFuse = true;
FuseCounter += 1;
if (FuseCounter > FastFuseRepetition)
{
SlowFuse = true;
ErrorLog("Power overload: \"" + gMyNode->asName + "\" disabled for " +
AnsiString(SlowFuseTimeOut) + "s");
}
else
ErrorLog("Power overload: \"" + gMyNode->asName + "\" disabled for " +
AnsiString(FastFuseTimeOut) + "s");
FuseTimer = 0;
}
if (FastFuse || SlowFuse)
{ // jeœli któryœ z bezpieczników zadzia³a³
TotalAdmitance = 0;
FuseTimer += dt;
if (!SlowFuse)
{ // gdy szybki, odczekaæ krótko i za³¹czyæ
if (FuseTimer > FastFuseTimeOut)
FastFuse = false;
}
else if (FuseTimer > SlowFuseTimeOut)
{
SlowFuse = false;
FuseCounter = 0; // dajemy znów szansê
}
}
TotalPreviousAdmitance = TotalAdmitance; // u¿ywamy admitancji z poprzedniego kroku
if (TotalPreviousAdmitance == 0.0)
TotalPreviousAdmitance = 1e-10; // przynajmniej minimalna up³ywnoœæ
TotalAdmitance = 1e-10; // a w aktualnym kroku sumujemy admitancjê
return true;
};
double __fastcall TTractionPowerSource::CurrentGet(double res)
{//pobranie wartoœci pr¹du przypadaj¹cego na rezystancjê (res)
//niech pamiêta poprzedni¹ admitancjê i wg niej przydziela pr¹d
if (SlowFuse||FastFuse)
{//czekanie na zanik obci¹¿enia sekcji
if (res<100.0) //liczenie czasu dopiero, gdy obci¹¿enie zniknie
FuseTimer=0;
return 0;
}
if ((res>0)||((res<0)&&(Recuperation)))
TotalAdmitance+=1.0/res; //po³¹czenie równoleg³e rezystancji jest równowa¿ne sumie admitancji
TotalCurrent=(TotalPreviousAdmitance!=0.0)?NominalVoltage/(InternalRes+1.0/TotalPreviousAdmitance):0.0; //napiêcie dzielone przez sumê rezystancji wewnêtrznej i obci¹¿enia
OutputVoltage=NominalVoltage-InternalRes*TotalCurrent; //napiêcie na obci¹¿eniu
return TotalCurrent/(res*TotalPreviousAdmitance); //pr¹d proporcjonalny do udzia³u (1/res) w ca³kowitej admitancji
{ // pobranie wartoœci pr¹du przypadaj¹cego na rezystancjê (res)
// niech pamiêta poprzedni¹ admitancjê i wg niej przydziela pr¹d
if (SlowFuse || FastFuse)
{ // czekanie na zanik obci¹¿enia sekcji
if (res < 100.0) // liczenie czasu dopiero, gdy obci¹¿enie zniknie
FuseTimer = 0;
return 0;
}
if ((res > 0) || ((res < 0) && (Recuperation)))
TotalAdmitance +=
1.0 / res; // po³¹czenie równoleg³e rezystancji jest równowa¿ne sumie admitancji
TotalCurrent = (TotalPreviousAdmitance != 0.0) ?
NominalVoltage / (InternalRes + 1.0 / TotalPreviousAdmitance) :
0.0; // napiêcie dzielone przez sumê rezystancji wewnêtrznej i obci¹¿enia
OutputVoltage = NominalVoltage - InternalRes * TotalCurrent; // napiêcie na obci¹¿eniu
return TotalCurrent / (res * TotalPreviousAdmitance); // pr¹d proporcjonalny do udzia³u (1/res)
// w ca³kowitej admitancji
};
void __fastcall TTractionPowerSource::PowerSet(TTractionPowerSource *ps)
{//wskazanie zasilacza w obiekcie sekcji
if (!psNode[0])
psNode[0]=ps;
else if (!psNode[1])
psNode[1]=ps;
//else ErrorLog("nie mo¿e byæ wiêcej punktów zasilania ni¿ dwa");
{ // wskazanie zasilacza w obiekcie sekcji
if (!psNode[0])
psNode[0] = ps;
else if (!psNode[1])
psNode[1] = ps;
// else ErrorLog("nie mo¿e byæ wiêcej punktów zasilania ni¿ dwa");
};
//---------------------------------------------------------------------------

View File

@@ -8,41 +8,41 @@ class TGroundNode;
class TTractionPowerSource
{
private:
double NominalVoltage;
double VoltageFrequency;
double InternalRes;
double MaxOutputCurrent;
double FastFuseTimeOut;
int FastFuseRepetition;
double SlowFuseTimeOut;
bool Recuperation;
private:
double NominalVoltage;
double VoltageFrequency;
double InternalRes;
double MaxOutputCurrent;
double FastFuseTimeOut;
int FastFuseRepetition;
double SlowFuseTimeOut;
bool Recuperation;
double TotalCurrent;
double TotalAdmitance;
double TotalPreviousAdmitance;
double OutputVoltage;
bool FastFuse;
bool SlowFuse;
double FuseTimer;
int FuseCounter;
protected:
double TotalCurrent;
double TotalAdmitance;
double TotalPreviousAdmitance;
double OutputVoltage;
bool FastFuse;
bool SlowFuse;
double FuseTimer;
int FuseCounter;
public: //zmienne publiczne
TTractionPowerSource *psNode[2]; //zasilanie na koñcach dla sekcji
bool bSection; //czy jest sekcj¹
TGroundNode *gMyNode; //Ra 2015-03: znowu prowizorka, aby mieæ nazwê do logowania
public:
//AnsiString asName;
__fastcall TTractionPowerSource();
__fastcall ~TTractionPowerSource();
void __fastcall Init(double u,double i);
bool __fastcall Load(cParser *parser);
bool __fastcall Render();
bool __fastcall Update(double dt);
double __fastcall CurrentGet(double res);
void __fastcall VoltageSet(double v) {NominalVoltage=v;};
void __fastcall PowerSet(TTractionPowerSource *ps);
protected:
public: // zmienne publiczne
TTractionPowerSource *psNode[2]; // zasilanie na koñcach dla sekcji
bool bSection; // czy jest sekcj¹
TGroundNode *gMyNode; // Ra 2015-03: znowu prowizorka, aby mieæ nazwê do logowania
public:
// AnsiString asName;
__fastcall TTractionPowerSource();
__fastcall ~TTractionPowerSource();
void __fastcall Init(double u, double i);
bool __fastcall Load(cParser *parser);
bool __fastcall Render();
bool __fastcall Update(double dt);
double __fastcall CurrentGet(double res);
void __fastcall VoltageSet(double v) { NominalVoltage = v; };
void __fastcall PowerSet(TTractionPowerSource *ps);
};
//---------------------------------------------------------------------------

10592
Train.cpp

File diff suppressed because it is too large Load Diff

344
Train.h
View File

@@ -17,106 +17,105 @@
#include "RealSound.h"
#include "FadeSound.h"
// typedef enum {st_Off, st_Starting, st_On, st_ShuttingDown} T4State;
const int maxcab=2;
const int maxcab = 2;
// const double fCzuwakTime= 90.0f;
const double fCzuwakBlink=0.15;
const float fConverterPrzekaznik=1.5; //hunter-261211: do przekaznika nadmiarowego przetwornicy
//0.33f
const double fCzuwakBlink = 0.15;
const float fConverterPrzekaznik = 1.5; // hunter-261211: do przekaznika nadmiarowego przetwornicy
// 0.33f
// const double fBuzzerTime= 5.0f;
const float fHaslerTime=1.2;
const float fHaslerTime = 1.2;
// const double fStycznTime= 0.5f;
// const double fDblClickTime= 0.2f;
class TCab
{
public:
__fastcall TCab();
__fastcall ~TCab();
void __fastcall Init(double Initx1,double Inity1,double Initz1,double Initx2,double Inity2,double Initz2,bool InitEnabled,bool InitOccupied);
void __fastcall Load(TQueryParserComp *Parser);
vector3 CabPos1;
vector3 CabPos2;
bool bEnabled;
bool bOccupied;
double dimm_r, dimm_g, dimm_b; //McZapkie-120503: tlumienie swiatla
double intlit_r, intlit_g, intlit_b; //McZapkie-120503: oswietlenie kabiny
double intlitlow_r, intlitlow_g, intlitlow_b; //McZapkie-120503: przyciemnione oswietlenie kabiny
private:
//bool bChangePossible;
TGauge *ggList; //Ra 2014-08: lista animacji macierzowych (ga³ek) w kabinie
int iGaugesMax,iGauges; //ile miejsca w tablicy i ile jest w u¿yciu
TButton *btList; //Ra 2014-08: lista animacji dwustanowych (lampek) w kabinie
int iButtonsMax,iButtons; //ile miejsca w tablicy i ile jest w u¿yciu
public:
TGauge* __fastcall Gauge(int n=-1); //pobranie adresu obiektu
TButton* __fastcall Button(int n=-1); //pobranie adresu obiektu
void __fastcall Update();
public:
__fastcall TCab();
__fastcall ~TCab();
void __fastcall Init(double Initx1, double Inity1, double Initz1, double Initx2, double Inity2,
double Initz2, bool InitEnabled, bool InitOccupied);
void __fastcall Load(TQueryParserComp *Parser);
vector3 CabPos1;
vector3 CabPos2;
bool bEnabled;
bool bOccupied;
double dimm_r, dimm_g, dimm_b; // McZapkie-120503: tlumienie swiatla
double intlit_r, intlit_g, intlit_b; // McZapkie-120503: oswietlenie kabiny
double intlitlow_r, intlitlow_g,
intlitlow_b; // McZapkie-120503: przyciemnione oswietlenie kabiny
private:
// bool bChangePossible;
TGauge *ggList; // Ra 2014-08: lista animacji macierzowych (ga³ek) w kabinie
int iGaugesMax, iGauges; // ile miejsca w tablicy i ile jest w u¿yciu
TButton *btList; // Ra 2014-08: lista animacji dwustanowych (lampek) w kabinie
int iButtonsMax, iButtons; // ile miejsca w tablicy i ile jest w u¿yciu
public:
TGauge *__fastcall Gauge(int n = -1); // pobranie adresu obiektu
TButton *__fastcall Button(int n = -1); // pobranie adresu obiektu
void __fastcall Update();
};
class TTrain
{
public:
public:
bool CabChange(int iDirection);
bool ActiveUniversal4;
bool ShowNextCurrent; //pokaz przd w podlaczonej lokomotywie (ET41)
bool ShowNextCurrent; // pokaz przd w podlaczonej lokomotywie (ET41)
bool InitializeCab(int NewCabNo, AnsiString asFileName);
__fastcall TTrain();
__fastcall ~TTrain();
// bool __fastcall Init(TTrack *Track);
//McZapkie-010302
bool __fastcall Init(TDynamicObject *NewDynamicObject,bool e3d=false);
// bool __fastcall Init(TTrack *Track);
// McZapkie-010302
bool __fastcall Init(TDynamicObject *NewDynamicObject, bool e3d = false);
void __fastcall OnKeyDown(int cKey);
void __fastcall OnKeyUp(int cKey);
// bool __fastcall SHP() { fShpTimer= 0; };
// bool __fastcall SHP() { fShpTimer= 0; };
inline vector3 __fastcall GetDirection() { return DynamicObject->VectorFront(); };
inline vector3 __fastcall GetUp() { return DynamicObject->VectorUp(); };
void __fastcall UpdateMechPosition(double dt);
bool __fastcall Update();
void __fastcall MechStop();
// virtual bool __fastcall RenderAlpha();
//McZapkie-310302: ladowanie parametrow z pliku
// virtual bool __fastcall RenderAlpha();
// McZapkie-310302: ladowanie parametrow z pliku
bool __fastcall LoadMMediaFile(AnsiString asFileName);
private: //¿eby go nic z zewn¹trz nie przestawia³o
TDynamicObject *DynamicObject; //przestawia zmiana pojazdu [F5]
private: //¿eby go nic z zewn¹trz nie przestawia³o
TMoverParameters *mvControlled; //cz³on, w którym sterujemy silnikiem
TMoverParameters *mvOccupied; //cz³on, w którym sterujemy hamulcem
TMoverParameters *mvSecond; //drugi cz³on (ET40, ET41, ET42, ukrotnienia)
TMoverParameters *mvThird; //trzeci cz³on (SN61)
public: //reszta mo¿e byæ publiczna
private: //¿eby go nic z zewn¹trz nie przestawia³o
TDynamicObject *DynamicObject; // przestawia zmiana pojazdu [F5]
private: //¿eby go nic z zewn¹trz nie przestawia³o
TMoverParameters *mvControlled; // cz³on, w którym sterujemy silnikiem
TMoverParameters *mvOccupied; // cz³on, w którym sterujemy hamulcem
TMoverParameters *mvSecond; // drugi cz³on (ET40, ET41, ET42, ukrotnienia)
TMoverParameters *mvThird; // trzeci cz³on (SN61)
public: // reszta mo¿e byæ publiczna
// AnsiString asMessage;
//AnsiString asMessage;
//McZapkie: definicje wskaŸników
//Ra 2014-08: czêsciowo przeniesione do tablicy w TCab
// McZapkie: definicje wskaŸników
// Ra 2014-08: czêsciowo przeniesione do tablicy w TCab
TGauge ggZbS;
TGauge ggClockSInd;
TGauge ggClockMInd;
TGauge ggClockHInd;
//TGauge ggHVoltage;
// TGauge ggHVoltage;
TGauge ggLVoltage;
//TGauge ggEnrot1m;
//TGauge ggEnrot2m;
//TGauge ggEnrot3m;
//TGauge ggEngageRatio;
// TGauge ggEnrot1m;
// TGauge ggEnrot2m;
// TGauge ggEnrot3m;
// TGauge ggEngageRatio;
TGauge ggMainGearStatus;
TGauge ggEngineVoltage;
TGauge ggI1B; //drugi cz³on w postaci jawnej
TGauge ggI1B; // drugi cz³on w postaci jawnej
TGauge ggI2B;
TGauge ggI3B;
TGauge ggItotalB;
//McZapkie: definicje regulatorow
// McZapkie: definicje regulatorow
TGauge ggMainCtrl;
TGauge ggMainCtrlAct;
TGauge ggScndCtrl;
@@ -125,20 +124,21 @@ public: //reszta mo
TGauge ggBrakeCtrl;
TGauge ggLocalBrake;
TGauge ggManualBrake;
TGauge ggBrakeProfileCtrl; //nastawiacz GPR - przelacznik obrotowy
TGauge ggBrakeProfileG; //nastawiacz GP - hebelek towarowy
TGauge ggBrakeProfileR; //nastawiacz PR - hamowanie dwustopniowe
TGauge ggBrakeProfileCtrl; // nastawiacz GPR - przelacznik obrotowy
TGauge ggBrakeProfileG; // nastawiacz GP - hebelek towarowy
TGauge ggBrakeProfileR; // nastawiacz PR - hamowanie dwustopniowe
TGauge ggMaxCurrentCtrl;
TGauge ggMainOffButton;
TGauge ggMainOnButton;
TGauge ggMainButton; //EZT
TGauge ggMainButton; // EZT
TGauge ggSecurityResetButton;
TGauge ggReleaserButton;
TGauge ggAntiSlipButton;
TGauge ggFuseButton;
TGauge ggConverterFuseButton; //hunter-261211: przycisk odblokowania nadmiarowego przetwornic i ogrzewania
TGauge ggConverterFuseButton; // hunter-261211: przycisk odblokowania nadmiarowego przetwornic i
// ogrzewania
TGauge ggStLinOffButton;
TGauge ggRadioButton;
TGauge ggUpperLightButton;
@@ -147,7 +147,7 @@ public: //reszta mo
TGauge ggLeftEndLightButton;
TGauge ggRightEndLightButton;
//hunter-230112: przelacznik swiatel tylnich
// hunter-230112: przelacznik swiatel tylnich
TGauge ggRearUpperLightButton;
TGauge ggRearLeftLightButton;
TGauge ggRearRightLightButton;
@@ -160,35 +160,35 @@ public: //reszta mo
TGauge ggConverterButton;
TGauge ggConverterOffButton;
//ABu 090305 - syrena i prad nastepnego czlonu
// ABu 090305 - syrena i prad nastepnego czlonu
TGauge ggHornButton;
TGauge ggNextCurrentButton;
//ABu 090305 - uniwersalne przyciski
// ABu 090305 - uniwersalne przyciski
TGauge ggUniversal1Button;
TGauge ggUniversal2Button;
TGauge ggUniversal3Button;
TGauge ggUniversal4Button;
TGauge ggCabLightButton; //hunter-091012: przelacznik oswietlania kabiny
TGauge ggCabLightDimButton; //hunter-091012: przelacznik przyciemnienia oswietlenia kabiny
TGauge ggCabLightButton; // hunter-091012: przelacznik oswietlania kabiny
TGauge ggCabLightDimButton; // hunter-091012: przelacznik przyciemnienia oswietlenia kabiny
//NBMX wrzesien 2003 - obsluga drzwi
// NBMX wrzesien 2003 - obsluga drzwi
TGauge ggDoorLeftButton;
TGauge ggDoorRightButton;
TGauge ggDepartureSignalButton;
//Winger 160204 - obsluga pantografow - ZROBIC
// Winger 160204 - obsluga pantografow - ZROBIC
TGauge ggPantFrontButton;
TGauge ggPantRearButton;
TGauge ggPantFrontButtonOff; //EZT
TGauge ggPantFrontButtonOff; // EZT
TGauge ggPantAllDownButton;
//Winger 020304 - wlacznik ogrzewania
// Winger 020304 - wlacznik ogrzewania
TGauge ggTrainHeatingButton;
TGauge ggSignallingButton;
TGauge ggDoorSignallingButton;
// TModel3d *mdKabina; McZapkie-030303: to do dynobj
//TGauge ggDistCounter; //Ra 2014-07: licznik kilometrów
//TGauge ggVelocityDgt; //i od razu prêdkoœciomierz
// TModel3d *mdKabina; McZapkie-030303: to do dynobj
// TGauge ggDistCounter; //Ra 2014-07: licznik kilometrów
// TGauge ggVelocityDgt; //i od razu prêdkoœciomierz
TButton btLampkaPoslizg;
TButton btLampkaStyczn;
@@ -200,32 +200,32 @@ public: //reszta mo
TButton btLampkaWylSzybki;
TButton btLampkaNadmWent;
TButton btLampkaNadmSpr;
//yB: drugie lampki dla EP05 i ET42
TButton btLampkaOporyB;
TButton btLampkaStycznB;
TButton btLampkaWylSzybkiB;
TButton btLampkaNadmPrzetwB;
TButton btLampkaPrzetwB;
//KURS90 lampki jazdy bezoporowej dla EU04
TButton btLampkaBezoporowaB;
TButton btLampkaBezoporowa;
TButton btLampkaUkrotnienie;
TButton btLampkaHamPosp;
TButton btLampkaRadio;
TButton btLampkaHamowanie1zes;
TButton btLampkaHamowanie2zes;
// TButton btLampkaUnknown;
// yB: drugie lampki dla EP05 i ET42
TButton btLampkaOporyB;
TButton btLampkaStycznB;
TButton btLampkaWylSzybkiB;
TButton btLampkaNadmPrzetwB;
TButton btLampkaPrzetwB;
// KURS90 lampki jazdy bezoporowej dla EU04
TButton btLampkaBezoporowaB;
TButton btLampkaBezoporowa;
TButton btLampkaUkrotnienie;
TButton btLampkaHamPosp;
TButton btLampkaRadio;
TButton btLampkaHamowanie1zes;
TButton btLampkaHamowanie2zes;
// TButton btLampkaUnknown;
TButton btLampkaOpory;
TButton btLampkaWysRozr;
TButton btLampkaUniversal3;
int LampkaUniversal3_typ; //ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw.
int LampkaUniversal3_typ; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw.
bool LampkaUniversal3_st;
TButton btLampkaWentZaluzje; //ET22
TButton btLampkaWentZaluzje; // ET22
TButton btLampkaOgrzewanieSkladu;
TButton btLampkaSHP;
TButton btLampkaCzuwaka; //McZapkie-141102
TButton btLampkaCzuwaka; // McZapkie-141102
TButton btLampkaRezerwa;
//youBy - jakies dodatkowe lampki
// youBy - jakies dodatkowe lampki
TButton btLampkaNapNastHam;
TButton btLampkaSprezarka;
TButton btLampkaSprezarkaB;
@@ -235,39 +235,39 @@ public: //reszta mo
TButton btLampkaBocznik4;
TButton btLampkaRadiotelefon;
TButton btLampkaHamienie;
TButton btLampkaJazda; //Ra: nie u¿ywane
//KURS90
TButton btLampkaBoczniki;
TButton btLampkaMaxSila;
TButton btLampkaPrzekrMaxSila;
// TButton bt;
//
TButton btLampkaJazda; // Ra: nie u¿ywane
// KURS90
TButton btLampkaBoczniki;
TButton btLampkaMaxSila;
TButton btLampkaPrzekrMaxSila;
// TButton bt;
//
TButton btLampkaDoorLeft;
TButton btLampkaDoorRight;
TButton btLampkaDepartureSignal;
TButton btLampkaBlokadaDrzwi;
TButton btLampkaHamulecReczny;
TButton btLampkaForward; //Ra: lampki w przód i w ty³ dla komputerowych kabin
TButton btLampkaForward; // Ra: lampki w przód i w ty³ dla komputerowych kabin
TButton btLampkaBackward;
TButton btCabLight; //hunter-171012: lampa oswietlajaca kabine
//Ra 2013-12: wirtualne "lampki" do odbijania na haslerze w PoKeys
TButton btHaslerBrakes; //ciœnienie w cylindrach
TButton btHaslerCurrent; //pr¹d na silnikach
TButton btCabLight; // hunter-171012: lampa oswietlajaca kabine
// Ra 2013-12: wirtualne "lampki" do odbijania na haslerze w PoKeys
TButton btHaslerBrakes; // ciœnienie w cylindrach
TButton btHaslerCurrent; // pr¹d na silnikach
vector3 pPosition;
vector3 pMechOffset; //driverNpos
vector3 pMechOffset; // driverNpos
vector3 vMechMovement;
vector3 pMechPosition;
vector3 pMechShake;
vector3 vMechVelocity;
//McZapkie: do poruszania sie po kabinie
// McZapkie: do poruszania sie po kabinie
double fMechCroach;
//McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
TCab Cabine[maxcab+1]; //przedzial maszynowy, kabina 1 (A), kabina 2 (B)
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
TCab Cabine[maxcab + 1]; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
int iCabn;
TSpring MechSpring;
double fMechSpringX; //McZapkie-250303: parametry bujania
double fMechSpringX; // McZapkie-250303: parametry bujania
double fMechSpringY;
double fMechSpringZ;
double fMechMaxSpring;
@@ -275,40 +275,39 @@ public: //reszta mo
double fMechPitch;
PSound dsbNastawnikJazdy;
PSound dsbNastawnikBocz; //hunter-081211
PSound dsbNastawnikBocz; // hunter-081211
PSound dsbRelay;
PSound dsbPneumaticRelay;
PSound dsbSwitch;
PSound dsbPneumaticSwitch;
PSound dsbReverserKey; //hunter-121211
PSound dsbReverserKey; // hunter-121211
PSound dsbCouplerAttach; //Ra: w kabinie????
PSound dsbCouplerDetach; //Ra: w kabinie???
PSound dsbCouplerAttach; // Ra: w kabinie????
PSound dsbCouplerDetach; // Ra: w kabinie???
PSound dsbDieselIgnition; //Ra: w kabinie???
PSound dsbDieselIgnition; // Ra: w kabinie???
PSound dsbDoorClose; //Ra: w kabinie???
PSound dsbDoorOpen; //Ra: w kabinie???
PSound dsbDoorClose; // Ra: w kabinie???
PSound dsbDoorOpen; // Ra: w kabinie???
//Winger 010304
// Winger 010304
PSound dsbPantUp;
PSound dsbPantDown;
PSound dsbWejscie_na_bezoporow;
PSound dsbWejscie_na_drugi_uklad; //hunter-081211: poprawka literowki
PSound dsbWejscie_na_drugi_uklad; // hunter-081211: poprawka literowki
// PSound dsbHiss1;
// PSound dsbHiss2;
// PSound dsbHiss1;
// PSound dsbHiss2;
//McZapkie-280302
// McZapkie-280302
TRealSound rsBrake;
TRealSound rsSlippery;
TRealSound rsHiss; //upuszczanie
TRealSound rsHissU; //napelnianie
TRealSound rsHissE; //nagle
TRealSound rsHissX; //fala
TRealSound rsHissT; //czasowy
TRealSound rsHiss; // upuszczanie
TRealSound rsHissU; // napelnianie
TRealSound rsHissE; // nagle
TRealSound rsHissX; // fala
TRealSound rsHissT; // czasowy
TRealSound rsSBHiss;
TRealSound rsRunningNoise;
TRealSound rsEngageSlippery;
@@ -316,61 +315,62 @@ public: //reszta mo
PSound dsbHasler;
PSound dsbBuzzer;
PSound dsbSlipAlarm; //Bombardier 011010: alarm przy poslizgu dla 181/182
//TFadeSound sConverter; //przetwornica
//TFadeSound sSmallCompressor; //przetwornica
PSound dsbSlipAlarm; // Bombardier 011010: alarm przy poslizgu dla 181/182
// TFadeSound sConverter; //przetwornica
// TFadeSound sSmallCompressor; //przetwornica
int iCabLightFlag; //McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne)
bool bCabLight; //hunter-091012: czy swiatlo jest zapalone?
bool bCabLightDim; //hunter-091012: czy przyciemnienie kabiny jest zapalone?
int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne)
bool bCabLight; // hunter-091012: czy swiatlo jest zapalone?
bool bCabLightDim; // hunter-091012: czy przyciemnienie kabiny jest zapalone?
vector3 pMechSittingPosition; //ABu 180404
vector3 __fastcall MirrorPosition(bool lewe);
private:
//PSound dsbBuzzer;
PSound dsbCouplerStretch;
PSound dsbEN57_CouplerStretch;
PSound dsbBufferClamp;
// TSubModel *smCzuwakShpOn;
// TSubModel *smCzuwakOn;
// TSubModel *smShpOn;
// TSubModel *smCzuwakShpOff;
// double fCzuwakTimer;
double fBlinkTimer;
float fHaslerTimer;
float fConverterTimer; //hunter-261211: dla przekaznika
float fMainRelayTimer; //hunter-141211: zalaczanie WSa z opoznieniem
float fCzuwakTestTimer; //hunter-091012: do testu czuwaka
vector3 pMechSittingPosition; // ABu 180404
vector3 __fastcall MirrorPosition(bool lewe);
int CAflag; //hunter-131211: dla osobnego zbijania CA i SHP
private:
// PSound dsbBuzzer;
PSound dsbCouplerStretch;
PSound dsbEN57_CouplerStretch;
PSound dsbBufferClamp;
// TSubModel *smCzuwakShpOn;
// TSubModel *smCzuwakOn;
// TSubModel *smShpOn;
// TSubModel *smCzuwakShpOff;
// double fCzuwakTimer;
double fBlinkTimer;
float fHaslerTimer;
float fConverterTimer; // hunter-261211: dla przekaznika
float fMainRelayTimer; // hunter-141211: zalaczanie WSa z opoznieniem
float fCzuwakTestTimer; // hunter-091012: do testu czuwaka
int CAflag; // hunter-131211: dla osobnego zbijania CA i SHP
double fPoslizgTimer;
// double fShpTimer;
// double fDblClickTimer;
//ABu: Przeniesione do public. - Wiem, ze to nieladnie...
//bool CabChange(int iDirection);
//bool InitializeCab(int NewCabNo, AnsiString asFileName);
// double fShpTimer;
// double fDblClickTimer;
// ABu: Przeniesione do public. - Wiem, ze to nieladnie...
// bool CabChange(int iDirection);
// bool InitializeCab(int NewCabNo, AnsiString asFileName);
TTrack *tor;
int keybrakecount;
//McZapkie-240302 - przyda sie do tachometru
// McZapkie-240302 - przyda sie do tachometru
float fTachoVelocity;
float fTachoVelocityJump; //ze skakaniem
float fTachoVelocityJump; // ze skakaniem
float fTachoTimer;
float fTachoCount;
float fHVoltage; //napiêcie dla dynamicznych ga³ek
float fHCurrent[4]; //pr¹dy: suma i amperomierze 1,2,3
float fEngine[4]; //obroty te¿ trzeba pobraæ
//McZapkie: do syczenia
float fPPress,fNPress;
float fSPPress,fSNPress;
int iSekunda; //Ra: sekunda aktualizacji prêdkoœci
int iRadioChannel; //numer aktualnego kana³u radiowego
public:
int __fastcall RadioChannel() {return iRadioChannel;};
inline TDynamicObject* __fastcall Dynamic() {return DynamicObject;};
inline TMoverParameters* __fastcall Controlled() {return mvControlled;};
void __fastcall DynamicSet(TDynamicObject *d);
void __fastcall Silence();
float fHVoltage; // napiêcie dla dynamicznych ga³ek
float fHCurrent[4]; // pr¹dy: suma i amperomierze 1,2,3
float fEngine[4]; // obroty te¿ trzeba pobraæ
// McZapkie: do syczenia
float fPPress, fNPress;
float fSPPress, fSNPress;
int iSekunda; // Ra: sekunda aktualizacji prêdkoœci
int iRadioChannel; // numer aktualnego kana³u radiowego
public:
int __fastcall RadioChannel() { return iRadioChannel; };
inline TDynamicObject *__fastcall Dynamic() { return DynamicObject; };
inline TMoverParameters *__fastcall Controlled() { return mvControlled; };
void __fastcall DynamicSet(TDynamicObject *d);
void __fastcall Silence();
};
//---------------------------------------------------------------------------
#endif

View File

@@ -22,272 +22,308 @@
__fastcall TTrackFollower::TTrackFollower()
{
pCurrentTrack=NULL;
pCurrentSegment=NULL;
fCurrentDistance=0;
pPosition=vAngles=vector3(0,0,0);
fDirection=1; //jest przodem do Point2
fOffsetH=0.0; //na starcie stoi na środku
pCurrentTrack = NULL;
pCurrentSegment = NULL;
fCurrentDistance = 0;
pPosition = vAngles = vector3(0, 0, 0);
fDirection = 1; // jest przodem do Point2
fOffsetH = 0.0; // na starcie stoi na środku
}
__fastcall TTrackFollower::~TTrackFollower()
__fastcall TTrackFollower::~TTrackFollower() {}
bool __fastcall TTrackFollower::Init(TTrack *pTrack, TDynamicObject *NewOwner, double fDir)
{
fDirection = fDir;
Owner = NewOwner;
SetCurrentTrack(pTrack, 0);
iEventFlag = 3; // na torze startowym również wykonać eventy 1/2
iEventallFlag = 3;
if ((pCurrentSegment)) // && (pCurrentSegment->GetLength()<fFirstDistance))
return false;
return true;
}
bool __fastcall TTrackFollower::Init(TTrack *pTrack,TDynamicObject *NewOwner,double fDir)
{
fDirection=fDir;
Owner=NewOwner;
SetCurrentTrack(pTrack,0);
iEventFlag=3; //na torze startowym również wykonać eventy 1/2
iEventallFlag=3;
if ((pCurrentSegment))// && (pCurrentSegment->GetLength()<fFirstDistance))
return false;
return true;
}
TTrack* __fastcall TTrackFollower::SetCurrentTrack(TTrack *pTrack,int end)
{//przejechanie na inny odcinkek toru, z ewentualnym rozpruciem
if (pTrack)
switch (pTrack->eType)
{case tt_Switch: //jeśli zwrotnica, to przekładamy ją, aby uzyskać dobry segment
{int i=(end?pCurrentTrack->iNextDirection:pCurrentTrack->iPrevDirection);
if (i>0) //jeżeli wjazd z ostrza
pTrack->SwitchForced(i>>1,Owner); //to przełożenie zwrotnicy - rozprucie!
}
break;
case tt_Cross: //skrzyżowanie trzeba tymczasowo przełączyć, aby wjechać na właściwy tor
{iSegment=Owner->RouteWish(pTrack); //nr segmentu został ustalony podczas skanowania
//Ra 2014-08: aby ustalić dalszą trasę, należy zapytać AI - trasa jest ustalana podczas skanowania
//Ra 15-01: zapytanie AI nie wybiera segmentu - kolejny skanujący może przestawić
//pTrack->CrossSegment(end?pCurrentTrack->iNextDirection:pCurrentTrack->iPrevDirection,i); //ustawienie właściwego wskaźnika
//powinno zwracać kierunek do zapamiętania, bo segmenty mogą mieć różny kierunek
//if fDirection=(iSegment>0)?1.0:-1.0; //kierunek na tym segmencie jest ustalany bezpośrednio
if (iSegment==0)
{//to jest błędna sytuacja - generuje pętle zawracające za skrzyżowaniem - ustalić, kiedy powstaje!
iSegment=1; //doraźna poprawka
TTrack *__fastcall TTrackFollower::SetCurrentTrack(TTrack *pTrack, int end)
{ // przejechanie na inny odcinkek toru, z ewentualnym rozpruciem
if (pTrack)
switch (pTrack->eType)
{
case tt_Switch: // jeśli zwrotnica, to przekładamy ją, aby uzyskać dobry segment
{
int i = (end ? pCurrentTrack->iNextDirection : pCurrentTrack->iPrevDirection);
if (i > 0) // jeżeli wjazd z ostrza
pTrack->SwitchForced(i >> 1, Owner); // to przełożenie zwrotnicy - rozprucie!
}
break;
case tt_Cross: // skrzyżowanie trzeba tymczasowo przełączyć, aby wjechać na właściwy tor
{
iSegment = Owner->RouteWish(pTrack); // nr segmentu został ustalony podczas skanowania
// Ra 2014-08: aby ustalić dalszą trasę, należy zapytać AI - trasa jest ustalana podczas
// skanowania
// Ra 15-01: zapytanie AI nie wybiera segmentu - kolejny skanujący może przestawić
// pTrack->CrossSegment(end?pCurrentTrack->iNextDirection:pCurrentTrack->iPrevDirection,i);
// //ustawienie właściwego wskaźnika
// powinno zwracać kierunek do zapamiętania, bo segmenty mogą mieć różny kierunek
// if fDirection=(iSegment>0)?1.0:-1.0; //kierunek na tym segmencie jest ustalany
// bezpośrednio
if (iSegment == 0)
{ // to jest błędna sytuacja - generuje pętle zawracające za skrzyżowaniem - ustalić,
// kiedy powstaje!
iSegment = 1; // doraźna poprawka
}
if ((end ? iSegment : -iSegment) < 0)
fDirection = -fDirection; // wtórna zmiana
pTrack->SwitchForced(abs(iSegment) - 1, NULL); // wybór zapamiętanego segmentu
}
break;
}
if (!pTrack)
{ // gdy nie ma toru w kierunku jazdy
pTrack = pCurrentTrack->NullCreate(
end); // tworzenie toru wykolejącego na przedłużeniu pCurrentTrack
if (!end) // jeśli dodana od strony zero, to zmiana kierunku
fDirection = -fDirection; // wtórna zmiana
// if (pTrack->iCategoryFlag&2)
//{//jeśli samochód, zepsuć na miejscu
// Owner->MoverParameters->V=0; //zatrzymać
// Owner->MoverParameters->Power=0; //ukraść silnik
// Owner->MoverParameters->AccS=0; //wchłonąć moc
// Global::iPause|=1; //zapauzowanie symulacji
//}
}
if ((end?iSegment:-iSegment)<0)
fDirection=-fDirection; //wtórna zmiana
pTrack->SwitchForced(abs(iSegment)-1,NULL); //wybór zapamiętanego segmentu
}
break;
}
if (!pTrack)
{//gdy nie ma toru w kierunku jazdy
pTrack=pCurrentTrack->NullCreate(end); //tworzenie toru wykolejącego na przedłużeniu pCurrentTrack
if (!end) //jeśli dodana od strony zero, to zmiana kierunku
fDirection=-fDirection; //wtórna zmiana
//if (pTrack->iCategoryFlag&2)
//{//jeśli samochód, zepsuć na miejscu
// Owner->MoverParameters->V=0; //zatrzymać
// Owner->MoverParameters->Power=0; //ukraść silnik
// Owner->MoverParameters->AccS=0; //wchłonąć moc
// Global::iPause|=1; //zapauzowanie symulacji
//}
}
else
{//najpierw +1, później -1, aby odcinek izolowany wspólny dla tych torów nie wykrył zera
pTrack->AxleCounter(+1,Owner); //zajęcie nowego toru
if (pCurrentTrack) pCurrentTrack->AxleCounter(-1,Owner); //opuszczenie tamtego toru
}
pCurrentTrack=pTrack;
pCurrentSegment=(pCurrentTrack?pCurrentTrack->CurrentSegment():NULL);
if (!pCurrentTrack)
Error(Owner->MoverParameters->Name+" at NULL track");
return pCurrentTrack;
else
{ // najpierw +1, później -1, aby odcinek izolowany wspólny dla tych torów nie wykrył zera
pTrack->AxleCounter(+1, Owner); // zajęcie nowego toru
if (pCurrentTrack)
pCurrentTrack->AxleCounter(-1, Owner); // opuszczenie tamtego toru
}
pCurrentTrack = pTrack;
pCurrentSegment = (pCurrentTrack ? pCurrentTrack->CurrentSegment() : NULL);
if (!pCurrentTrack)
Error(Owner->MoverParameters->Name + " at NULL track");
return pCurrentTrack;
};
bool __fastcall TTrackFollower::Move(double fDistance,bool bPrimary)
{//przesuwanie wózka po torach o odległość (fDistance), z wyzwoleniem eventów
//bPrimary=true - jest pierwszą osią w pojeździe, czyli generuje eventy i przepisuje pojazd
//Ra: zwraca false, jeśli pojazd ma być usunięty
fDistance*=fDirection; //dystans mnożnony przez kierunek
double s; //roboczy dystans
double dir; //zapamiętany kierunek do sprawdzenia, czy się zmienił
bool bCanSkip; //czy przemieścić pojazd na inny tor
while (true) //pętla wychodzi, gdy przesunięcie wyjdzie zerowe
{//pętla przesuwająca wózek przez kolejne tory, aż do trafienia w jakiś
if (!pCurrentTrack) return false; //nie ma toru, to nie ma przesuwania
if (pCurrentTrack->iEvents) //sumaryczna informacja o eventach
{//omijamy cały ten blok, gdy tor nie ma on żadnych eventów (większość nie ma)
if (fDistance<0)
{
if (iSetFlag(iEventFlag,-1)) //zawsze zeruje flagę sprawdzenia, jak mechanik dosiądzie, to się nie wykona
if (Owner->Mechanik) //tylko dla jednego członu
//if (TestFlag(iEventFlag,1)) //McZapkie-280503: wyzwalanie event tylko dla pojazdow z obsada
if (bPrimary && pCurrentTrack->evEvent1 && (!pCurrentTrack->evEvent1->iQueued))
Global::AddToQuery(pCurrentTrack->evEvent1,Owner); //dodanie do kolejki
//Owner->RaAxleEvent(pCurrentTrack->Event1); //Ra: dynamic zdecyduje, czy dodać do kolejki
//if (TestFlag(iEventallFlag,1))
if (iSetFlag(iEventallFlag,-1)) //McZapkie-280503: wyzwalanie eventall dla wszystkich pojazdow
if (bPrimary && pCurrentTrack->evEventall1 && (!pCurrentTrack->evEventall1->iQueued))
Global::AddToQuery(pCurrentTrack->evEventall1,Owner); //dodanie do kolejki
//Owner->RaAxleEvent(pCurrentTrack->Eventall1); //Ra: dynamic zdecyduje, czy dodać do kolejki
}
else if (fDistance>0)
{
if (iSetFlag(iEventFlag,-2)) //zawsze ustawia flagę sprawdzenia, jak mechanik dosiądzie, to się nie wykona
if (Owner->Mechanik) //tylko dla jednego członu
//if (TestFlag(iEventFlag,2)) //sprawdzanie jest od razu w pierwszym warunku
if (bPrimary && pCurrentTrack->evEvent2 && (!pCurrentTrack->evEvent2->iQueued))
Global::AddToQuery(pCurrentTrack->evEvent2,Owner);
//Owner->RaAxleEvent(pCurrentTrack->Event2); //Ra: dynamic zdecyduje, czy dodać do kolejki
//if (TestFlag(iEventallFlag,2))
if (iSetFlag(iEventallFlag,-2)) //sprawdza i zeruje na przyszłość, true jeśli zmieni z 2 na 0
if (bPrimary && pCurrentTrack->evEventall2 && (!pCurrentTrack->evEventall2->iQueued))
Global::AddToQuery(pCurrentTrack->evEventall2,Owner);
//Owner->RaAxleEvent(pCurrentTrack->Eventall2); //Ra: dynamic zdecyduje, czy dodać do kolejki
}
else //if (fDistance==0) //McZapkie-140602: wyzwalanie zdarzenia gdy pojazd stoi
{
if (Owner->Mechanik) //tylko dla jednego członu
if (pCurrentTrack->evEvent0)
if (!pCurrentTrack->evEvent0->iQueued)
Global::AddToQuery(pCurrentTrack->evEvent0,Owner);
//Owner->RaAxleEvent(pCurrentTrack->Event0); //Ra: dynamic zdecyduje, czy dodać do kolejki
if (pCurrentTrack->evEventall0)
if (!pCurrentTrack->evEventall0->iQueued)
Global::AddToQuery(pCurrentTrack->evEventall0,Owner);
//Owner->RaAxleEvent(pCurrentTrack->Eventall0); //Ra: dynamic zdecyduje, czy dodać do kolejki
}
}
if (!pCurrentSegment) //jeżeli nie ma powiązanego segmentu toru?
return false;
//if (fDistance==0.0) return true; //Ra: jak stoi, to chyba dalej nie ma co kombinować?
s=fCurrentDistance+fDistance; //doliczenie przesunięcia
//Ra: W Point2 toru może znajdować się "dziura", która zamieni energię kinetyczną
// ruchu wzdłużnego na energię potencjalną, zamieniającą się potem na energię
// sprężystości na amortyzatorach. Należałoby we wpisie toru umieścić współczynnik
// podziału energii kinetycznej.
// Współczynnik normalnie 1, z dziurą np. 0.99, a -1 będzie oznaczało 100% odbicia (kozioł).
// Albo w postaci kąta: normalnie 0°, a 180° oznacza 100% odbicia (cosinus powyższego).
/*
if (pCurrentTrack->eType==tt_Cross)
{//zjazdu ze skrzyżowania nie da się określić przez (iPrevDirection) i (iNextDirection)
//int segment=Owner->RouteWish(pCurrentTrack); //numer segmentu dla skrzyżowań
//pCurrentTrack->SwitchForced(abs(segment)-1,NULL); //tymczasowo ustawienie tego segmentu
//pCurrentSegment=pCurrentTrack->CurrentSegment(); //odświeżyć sobie wskaźnik segmentu (?)
}
*/
if (s<0)
{//jeśli przekroczenie toru od strony Point1
bCanSkip=bPrimary?pCurrentTrack->CheckDynamicObject(Owner):false;
if (bCanSkip) //tylko główna oś przenosi pojazd do innego toru
Owner->MyTrack->RemoveDynamicObject(Owner); //zdejmujemy pojazd z dotychczasowego toru
dir=fDirection;
if (pCurrentTrack->eType==tt_Cross)
{if (!SetCurrentTrack(pCurrentTrack->Neightbour(iSegment,fDirection),0))
return false; //wyjście z błędem
}
else if (!SetCurrentTrack(pCurrentTrack->Neightbour(-1,fDirection),0)) //ustawia fDirection
return false; //wyjście z błędem
if (dir==fDirection) //(pCurrentTrack->iPrevDirection)
{//gdy kierunek bez zmiany (Point1->Point2)
fCurrentDistance=pCurrentSegment->GetLength();
fDistance=s;
}
else
{//gdy zmiana kierunku toru (Point1->Point1)
fCurrentDistance=0;
fDistance=-s;
}
if (bCanSkip)
{//jak główna oś, to dodanie pojazdu do nowego toru
pCurrentTrack->AddDynamicObject(Owner);
iEventFlag=3; //McZapkie-020602: umozliwienie uruchamiania event1,2 po zmianie toru
iEventallFlag=3; //McZapkie-280503: jw, dla eventall1,2
if (!Owner->MyTrack) return false;
}
continue;
}
else if (s>pCurrentSegment->GetLength())
{//jeśli przekroczenie toru od strony Point2
bCanSkip=bPrimary?pCurrentTrack->CheckDynamicObject(Owner):false;
if (bCanSkip) //tylko główna oś przenosi pojazd do innego toru
Owner->MyTrack->RemoveDynamicObject(Owner); //zdejmujemy pojazd z dotychczasowego toru
fDistance=s-pCurrentSegment->GetLength();
dir=fDirection;
if (pCurrentTrack->eType==tt_Cross)
{if (!SetCurrentTrack(pCurrentTrack->Neightbour(iSegment,fDirection),1))
return false; //wyjście z błędem
}
else if (!SetCurrentTrack(pCurrentTrack->Neightbour(1,fDirection),1)) //ustawia fDirection
return false; //wyjście z błędem
if (dir!=fDirection) //(pCurrentTrack->iNextDirection)
{//gdy zmiana kierunku toru (Point2->Point2)
fDistance=-fDistance; //(s-pCurrentSegment->GetLength());
fCurrentDistance=pCurrentSegment->GetLength();
}
else //gdy kierunek bez zmiany (Point2->Point1)
fCurrentDistance=0;
if (bCanSkip)
{//jak główna oś, to dodanie pojazdu do nowego toru
pCurrentTrack->AddDynamicObject(Owner);
iEventFlag=3; //McZapkie-020602: umozliwienie uruchamiania event1,2 po zmianie toru
iEventallFlag=3;
if (!Owner->MyTrack) return false;
}
continue;
}
else
{//gdy zostaje na tym samym torze (przesuwanie już nie zmienia toru)
if (bPrimary)
{//tylko gdy początkowe ustawienie, dodajemy eventy stania do kolejki
if (Owner->MoverParameters->ActiveCab!=0)
//if (Owner->MoverParameters->CabNo!=0)
{
if (pCurrentTrack->evEvent1 && pCurrentTrack->evEvent1->fDelay<=-1.0f)
Global::AddToQuery(pCurrentTrack->evEvent1,Owner);
if (pCurrentTrack->evEvent2 && pCurrentTrack->evEvent2->fDelay<=-1.0f)
Global::AddToQuery(pCurrentTrack->evEvent2,Owner);
bool __fastcall TTrackFollower::Move(double fDistance, bool bPrimary)
{ // przesuwanie wózka po torach o odległość (fDistance), z wyzwoleniem eventów
// bPrimary=true - jest pierwszą osią w pojeździe, czyli generuje eventy i przepisuje pojazd
// Ra: zwraca false, jeśli pojazd ma być usunięty
fDistance *= fDirection; // dystans mnożnony przez kierunek
double s; // roboczy dystans
double dir; // zapamiętany kierunek do sprawdzenia, czy się zmienił
bool bCanSkip; // czy przemieścić pojazd na inny tor
while (true) // pętla wychodzi, gdy przesunięcie wyjdzie zerowe
{ // pętla przesuwająca wózek przez kolejne tory, aż do trafienia w jakiś
if (!pCurrentTrack)
return false; // nie ma toru, to nie ma przesuwania
if (pCurrentTrack->iEvents) // sumaryczna informacja o eventach
{ // omijamy cały ten blok, gdy tor nie ma on żadnych eventów (większość nie ma)
if (fDistance < 0)
{
if (iSetFlag(iEventFlag, -1)) // zawsze zeruje flagę sprawdzenia, jak mechanik
// dosiądzie, to się nie wykona
if (Owner->Mechanik) // tylko dla jednego członu
// if (TestFlag(iEventFlag,1)) //McZapkie-280503: wyzwalanie event tylko dla
// pojazdow z obsada
if (bPrimary && pCurrentTrack->evEvent1 &&
(!pCurrentTrack->evEvent1->iQueued))
Global::AddToQuery(pCurrentTrack->evEvent1, Owner); // dodanie do
// kolejki
// Owner->RaAxleEvent(pCurrentTrack->Event1); //Ra: dynamic zdecyduje, czy dodać do
// kolejki
// if (TestFlag(iEventallFlag,1))
if (iSetFlag(iEventallFlag,
-1)) // McZapkie-280503: wyzwalanie eventall dla wszystkich pojazdow
if (bPrimary && pCurrentTrack->evEventall1 &&
(!pCurrentTrack->evEventall1->iQueued))
Global::AddToQuery(pCurrentTrack->evEventall1, Owner); // dodanie do kolejki
// Owner->RaAxleEvent(pCurrentTrack->Eventall1); //Ra: dynamic zdecyduje, czy dodać
// do kolejki
}
else if (fDistance > 0)
{
if (iSetFlag(iEventFlag, -2)) // zawsze ustawia flagę sprawdzenia, jak mechanik
// dosiądzie, to się nie wykona
if (Owner->Mechanik) // tylko dla jednego członu
// if (TestFlag(iEventFlag,2)) //sprawdzanie jest od razu w pierwszym
// warunku
if (bPrimary && pCurrentTrack->evEvent2 &&
(!pCurrentTrack->evEvent2->iQueued))
Global::AddToQuery(pCurrentTrack->evEvent2, Owner);
// Owner->RaAxleEvent(pCurrentTrack->Event2); //Ra: dynamic zdecyduje, czy dodać do
// kolejki
// if (TestFlag(iEventallFlag,2))
if (iSetFlag(iEventallFlag,
-2)) // sprawdza i zeruje na przyszłość, true jeśli zmieni z 2 na 0
if (bPrimary && pCurrentTrack->evEventall2 &&
(!pCurrentTrack->evEventall2->iQueued))
Global::AddToQuery(pCurrentTrack->evEventall2, Owner);
// Owner->RaAxleEvent(pCurrentTrack->Eventall2); //Ra: dynamic zdecyduje, czy dodać
// do kolejki
}
else // if (fDistance==0) //McZapkie-140602: wyzwalanie zdarzenia gdy pojazd stoi
{
if (Owner->Mechanik) // tylko dla jednego członu
if (pCurrentTrack->evEvent0)
if (!pCurrentTrack->evEvent0->iQueued)
Global::AddToQuery(pCurrentTrack->evEvent0, Owner);
// Owner->RaAxleEvent(pCurrentTrack->Event0); //Ra: dynamic zdecyduje, czy dodać do
// kolejki
if (pCurrentTrack->evEventall0)
if (!pCurrentTrack->evEventall0->iQueued)
Global::AddToQuery(pCurrentTrack->evEventall0, Owner);
// Owner->RaAxleEvent(pCurrentTrack->Eventall0); //Ra: dynamic zdecyduje, czy dodać
// do kolejki
}
}
if (!pCurrentSegment) // jeżeli nie ma powiązanego segmentu toru?
return false;
// if (fDistance==0.0) return true; //Ra: jak stoi, to chyba dalej nie ma co kombinować?
s = fCurrentDistance + fDistance; // doliczenie przesunięcia
// Ra: W Point2 toru może znajdować się "dziura", która zamieni energię kinetyczną
// ruchu wzdłużnego na energię potencjalną, zamieniającą się potem na energię
// sprężystości na amortyzatorach. Należałoby we wpisie toru umieścić współczynnik
// podziału energii kinetycznej.
// Współczynnik normalnie 1, z dziurą np. 0.99, a -1 będzie oznaczało 100% odbicia (kozioł).
// Albo w postaci kąta: normalnie 0°, a 180° oznacza 100% odbicia (cosinus powyższego).
/*
if (pCurrentTrack->eType==tt_Cross)
{//zjazdu ze skrzyżowania nie da się określić przez (iPrevDirection) i (iNextDirection)
//int segment=Owner->RouteWish(pCurrentTrack); //numer segmentu dla skrzyżowań
//pCurrentTrack->SwitchForced(abs(segment)-1,NULL); //tymczasowo ustawienie tego segmentu
//pCurrentSegment=pCurrentTrack->CurrentSegment(); //odświeżyć sobie wskaźnik segmentu
(?)
}
*/
if (s < 0)
{ // jeśli przekroczenie toru od strony Point1
bCanSkip = bPrimary ? pCurrentTrack->CheckDynamicObject(Owner) : false;
if (bCanSkip) // tylko główna oś przenosi pojazd do innego toru
Owner->MyTrack->RemoveDynamicObject(
Owner); // zdejmujemy pojazd z dotychczasowego toru
dir = fDirection;
if (pCurrentTrack->eType == tt_Cross)
{
if (!SetCurrentTrack(pCurrentTrack->Neightbour(iSegment, fDirection), 0))
return false; // wyjście z błędem
}
else if (!SetCurrentTrack(pCurrentTrack->Neightbour(-1, fDirection),
0)) // ustawia fDirection
return false; // wyjście z błędem
if (dir == fDirection) //(pCurrentTrack->iPrevDirection)
{ // gdy kierunek bez zmiany (Point1->Point2)
fCurrentDistance = pCurrentSegment->GetLength();
fDistance = s;
}
else
{ // gdy zmiana kierunku toru (Point1->Point1)
fCurrentDistance = 0;
fDistance = -s;
}
if (bCanSkip)
{ // jak główna oś, to dodanie pojazdu do nowego toru
pCurrentTrack->AddDynamicObject(Owner);
iEventFlag =
3; // McZapkie-020602: umozliwienie uruchamiania event1,2 po zmianie toru
iEventallFlag = 3; // McZapkie-280503: jw, dla eventall1,2
if (!Owner->MyTrack)
return false;
}
continue;
}
else if (s > pCurrentSegment->GetLength())
{ // jeśli przekroczenie toru od strony Point2
bCanSkip = bPrimary ? pCurrentTrack->CheckDynamicObject(Owner) : false;
if (bCanSkip) // tylko główna oś przenosi pojazd do innego toru
Owner->MyTrack->RemoveDynamicObject(
Owner); // zdejmujemy pojazd z dotychczasowego toru
fDistance = s - pCurrentSegment->GetLength();
dir = fDirection;
if (pCurrentTrack->eType == tt_Cross)
{
if (!SetCurrentTrack(pCurrentTrack->Neightbour(iSegment, fDirection), 1))
return false; // wyjście z błędem
}
else if (!SetCurrentTrack(pCurrentTrack->Neightbour(1, fDirection),
1)) // ustawia fDirection
return false; // wyjście z błędem
if (dir != fDirection) //(pCurrentTrack->iNextDirection)
{ // gdy zmiana kierunku toru (Point2->Point2)
fDistance = -fDistance; //(s-pCurrentSegment->GetLength());
fCurrentDistance = pCurrentSegment->GetLength();
}
else // gdy kierunek bez zmiany (Point2->Point1)
fCurrentDistance = 0;
if (bCanSkip)
{ // jak główna oś, to dodanie pojazdu do nowego toru
pCurrentTrack->AddDynamicObject(Owner);
iEventFlag =
3; // McZapkie-020602: umozliwienie uruchamiania event1,2 po zmianie toru
iEventallFlag = 3;
if (!Owner->MyTrack)
return false;
}
continue;
}
else
{ // gdy zostaje na tym samym torze (przesuwanie już nie zmienia toru)
if (bPrimary)
{ // tylko gdy początkowe ustawienie, dodajemy eventy stania do kolejki
if (Owner->MoverParameters->ActiveCab != 0)
// if (Owner->MoverParameters->CabNo!=0)
{
if (pCurrentTrack->evEvent1 && pCurrentTrack->evEvent1->fDelay <= -1.0f)
Global::AddToQuery(pCurrentTrack->evEvent1, Owner);
if (pCurrentTrack->evEvent2 && pCurrentTrack->evEvent2->fDelay <= -1.0f)
Global::AddToQuery(pCurrentTrack->evEvent2, Owner);
}
if (pCurrentTrack->evEventall1 && pCurrentTrack->evEventall1->fDelay <= -1.0f)
Global::AddToQuery(pCurrentTrack->evEventall1, Owner);
if (pCurrentTrack->evEventall2 && pCurrentTrack->evEventall2->fDelay <= -1.0f)
Global::AddToQuery(pCurrentTrack->evEventall2, Owner);
}
fCurrentDistance = s;
// fDistance=0;
return ComputatePosition(); // przeliczenie XYZ, true o ile nie wyjechał na NULL
}
}
if (pCurrentTrack->evEventall1 && pCurrentTrack->evEventall1->fDelay<=-1.0f)
Global::AddToQuery(pCurrentTrack->evEventall1,Owner);
if (pCurrentTrack->evEventall2 && pCurrentTrack->evEventall2->fDelay<=-1.0f)
Global::AddToQuery(pCurrentTrack->evEventall2,Owner);
}
fCurrentDistance=s;
//fDistance=0;
return ComputatePosition(); //przeliczenie XYZ, true o ile nie wyjechał na NULL
}
}
};
bool __fastcall TTrackFollower::ComputatePosition()
{//ustalenie współrzędnych XYZ
if (pCurrentSegment) //o ile jest tor
{
pCurrentSegment->RaPositionGet(fCurrentDistance,pPosition,vAngles);
if (fDirection<0) //kąty zależą jeszcze od zwrotu na torze
{//kąty są w przedziale <-M_PI;M_PI>
vAngles.x=-vAngles.x; //przechyłka jest w przecinwą stronę
vAngles.y=-vAngles.y; //pochylenie jest w przecinwą stronę
vAngles.z+=(vAngles.z>=M_PI)?-M_PI:M_PI; //ale kierunek w planie jest obrócony o 180°
}
if (fOffsetH!=0.0)
{//jeśli przesunięcie względem osi toru, to je doliczyć
}
return true;
}
return false;
{ // ustalenie współrzędnych XYZ
if (pCurrentSegment) // o ile jest tor
{
pCurrentSegment->RaPositionGet(fCurrentDistance, pPosition, vAngles);
if (fDirection < 0) // kąty zależą jeszcze od zwrotu na torze
{ // kąty są w przedziale <-M_PI;M_PI>
vAngles.x = -vAngles.x; // przechyłka jest w przecinwą stronę
vAngles.y = -vAngles.y; // pochylenie jest w przecinwą stronę
vAngles.z +=
(vAngles.z >= M_PI) ? -M_PI : M_PI; // ale kierunek w planie jest obrócony o 180°
}
if (fOffsetH != 0.0)
{ // jeśli przesunięcie względem osi toru, to je doliczyć
}
return true;
}
return false;
}
#if RENDER_CONE
#include "opengl/glew.h"
#include "opengl/glut.h"
void __fastcall TTrackFollower::Render(float fNr)
{//funkcja rysująca stożek w miejscu osi
glPushMatrix(); //matryca kamery
glTranslatef(pPosition.x,pPosition.y+6,pPosition.z); //6m ponad
glRotated(RadToDeg(-vAngles.z),0,1,0); //obrót względem osi OY
//glRotated(RadToDeg(vAngles.z),0,1,0); //obrót względem osi OY
glDisable(GL_LIGHTING);
glColor3f(1.0,1.0-fNr,1.0-fNr); //biały dla 0, czerwony dla 1
//glutWireCone(promień podstawy,wysokość,kątność podstawy,ilość segmentów na wysokość)
glutWireCone(0.5,2,4,1); //rysowanie stożka (ostrosłupa o podstawie wieloboka)
glEnable(GL_LIGHTING);
glPopMatrix();
{ // funkcja rysująca stożek w miejscu osi
glPushMatrix(); // matryca kamery
glTranslatef(pPosition.x, pPosition.y + 6, pPosition.z); // 6m ponad
glRotated(RadToDeg(-vAngles.z), 0, 1, 0); // obrót względem osi OY
// glRotated(RadToDeg(vAngles.z),0,1,0); //obrót względem osi OY
glDisable(GL_LIGHTING);
glColor3f(1.0, 1.0 - fNr, 1.0 - fNr); // biały dla 0, czerwony dla 1
// glutWireCone(promień podstawy,wysokość,kątność podstawy,ilość segmentów na wysokość)
glutWireCone(0.5, 2, 4, 1); // rysowanie stożka (ostrosłupa o podstawie wieloboka)
glEnable(GL_LIGHTING);
glPopMatrix();
}
#endif
//---------------------------------------------------------------------------

View File

@@ -8,35 +8,39 @@
class TDynamicObject;
class TTrackFollower
{//oś poruszająca się po torze
private:
TTrack *pCurrentTrack; //na którym torze się znajduje
TSegment *pCurrentSegment; //zwrotnice mogą mieć dwa segmenty
double fCurrentDistance; //przesunięcie względem Point1 w stronę Point2
double fDirection; //ustawienie względem toru: -1.0 albo 1.0, mnożone przez dystans
bool __fastcall ComputatePosition(); //przeliczenie pozycji na torze
TDynamicObject *Owner; //pojazd posiadający
int iEventFlag; //McZapkie-020602: informacja o tym czy wyzwalac zdarzenie: 0,1,2,3
int iEventallFlag;
int iSegment; //który segment toru jest używany (żeby nie przeskakiwało po przestawieniu zwrotnicy pod taborem)
public:
double fOffsetH; //Ra: odległość środka osi od osi toru (dla samochodów) - użyć do wężykowania
vector3 pPosition; //współrzędne XYZ w układzie scenerii
vector3 vAngles; //x:przechyłka, y:pochylenie, z:kierunek w planie (w radianach)
__fastcall TTrackFollower();
__fastcall ~TTrackFollower();
TTrack* __fastcall SetCurrentTrack(TTrack *pTrack,int end);
bool __fastcall Move(double fDistance,bool bPrimary);
inline TTrack* __fastcall GetTrack() {return pCurrentTrack;};
inline double __fastcall GetRoll() {return vAngles.x;}; //przechyłka policzona przy ustalaniu pozycji
//{return pCurrentSegment->GetRoll(fCurrentDistance)*fDirection;}; //zamiast liczyć można pobrać
inline double __fastcall GetDirection() {return fDirection;}; //zwrot na torze
inline double __fastcall GetTranslation() {return fCurrentDistance;}; //ABu-030403
//inline double __fastcall GetLength(vector3 p1, vector3 cp1, vector3 cp2, vector3 p2)
//{ return pCurrentSegment->ComputeLength(p1,cp1,cp2,p2); };
//inline double __fastcall GetRadius(double L, double d); //McZapkie-150503
bool __fastcall Init(TTrack *pTrack,TDynamicObject *NewOwner,double fDir);
void __fastcall Render(float fNr);
{ // oś poruszająca się po torze
private:
TTrack *pCurrentTrack; // na którym torze się znajduje
TSegment *pCurrentSegment; // zwrotnice mogą mieć dwa segmenty
double fCurrentDistance; // przesunięcie względem Point1 w stronę Point2
double fDirection; // ustawienie względem toru: -1.0 albo 1.0, mnożone przez dystans
bool __fastcall ComputatePosition(); // przeliczenie pozycji na torze
TDynamicObject *Owner; // pojazd posiadający
int iEventFlag; // McZapkie-020602: informacja o tym czy wyzwalac zdarzenie: 0,1,2,3
int iEventallFlag;
int iSegment; // który segment toru jest używany (żeby nie przeskakiwało po przestawieniu
// zwrotnicy pod taborem)
public:
double fOffsetH; // Ra: odległość środka osi od osi toru (dla samochodów) - użyć do wężykowania
vector3 pPosition; // współrzędne XYZ w układzie scenerii
vector3 vAngles; // x:przechyłka, y:pochylenie, z:kierunek w planie (w radianach)
__fastcall TTrackFollower();
__fastcall ~TTrackFollower();
TTrack *__fastcall SetCurrentTrack(TTrack *pTrack, int end);
bool __fastcall Move(double fDistance, bool bPrimary);
inline TTrack *__fastcall GetTrack() { return pCurrentTrack; };
inline double __fastcall GetRoll()
{
return vAngles.x;
}; // przechyłka policzona przy ustalaniu pozycji
//{return pCurrentSegment->GetRoll(fCurrentDistance)*fDirection;}; //zamiast liczyć można pobrać
inline double __fastcall GetDirection() { return fDirection; }; // zwrot na torze
inline double __fastcall GetTranslation() { return fCurrentDistance; }; // ABu-030403
// inline double __fastcall GetLength(vector3 p1, vector3 cp1, vector3 cp2, vector3 p2)
//{ return pCurrentSegment->ComputeLength(p1,cp1,cp2,p2); };
// inline double __fastcall GetRadius(double L, double d); //McZapkie-150503
bool __fastcall Init(TTrack *pTrack, TDynamicObject *NewOwner, double fDir);
void __fastcall Render(float fNr);
};
//---------------------------------------------------------------------------
#endif

124
VBO.cpp
View File

@@ -11,85 +11,89 @@
#pragma package(smart_init)
__fastcall CMesh::CMesh()
{//utworzenie pustego obiektu
m_pVNT=NULL;
m_nVertexCount=-1;
m_nVBOVertices=0; //nie zarezerwowane
{ // utworzenie pustego obiektu
m_pVNT = NULL;
m_nVertexCount = -1;
m_nVBOVertices = 0; // nie zarezerwowane
};
__fastcall CMesh::~CMesh()
{//usuwanie obiektu
Clear(); //zwolnienie zasobów
{ // usuwanie obiektu
Clear(); // zwolnienie zasobów
};
void __fastcall CMesh::MakeArray(int n)
{//tworzenie tablic
m_nVertexCount=n;
m_pVNT=new CVertNormTex[m_nVertexCount]; // przydzielenie pamięci dla tablicy
{ // tworzenie tablic
m_nVertexCount = n;
m_pVNT = new CVertNormTex[m_nVertexCount]; // przydzielenie pamięci dla tablicy
};
void __fastcall CMesh::BuildVBOs(bool del)
{//tworzenie VBO i kasowanie już niepotrzebnych tablic
//pobierz numer VBO oraz ustaw go jako aktywny
glGenBuffersARB(1,&m_nVBOVertices); //pobierz numer
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_nVBOVertices); //ustaw bufor jako aktualny
glBufferDataARB(GL_ARRAY_BUFFER_ARB,m_nVertexCount*sizeof(CVertNormTex),m_pVNT,GL_STATIC_DRAW_ARB);
//WriteLog("Assigned VBO number "+AnsiString(m_nVBOVertices)+", vertices: "+AnsiString(m_nVertexCount));
if (del) SafeDeleteArray(m_pVNT); //wierzchołki już się nie przydadzą
{ // tworzenie VBO i kasowanie już niepotrzebnych tablic
// pobierz numer VBO oraz ustaw go jako aktywny
glGenBuffersARB(1, &m_nVBOVertices); // pobierz numer
glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBOVertices); // ustaw bufor jako aktualny
glBufferDataARB(GL_ARRAY_BUFFER_ARB, m_nVertexCount * sizeof(CVertNormTex), m_pVNT,
GL_STATIC_DRAW_ARB);
// WriteLog("Assigned VBO number "+AnsiString(m_nVBOVertices)+", vertices:
// "+AnsiString(m_nVertexCount));
if (del)
SafeDeleteArray(m_pVNT); // wierzchołki już się nie przydadzą
};
void __fastcall CMesh::Clear()
{//niewirtualne zwolnienie zasobów przez sprzątacz albo destruktor
//inna nazwa, żeby nie mieszało się z funkcją wirtualną sprzątacza
if (m_nVBOVertices) //jeśli było coś rezerwowane
{
glDeleteBuffersARB(1,&m_nVBOVertices); // Free The Memory
//WriteLog("Released VBO number "+AnsiString(m_nVBOVertices));
}
m_nVBOVertices=0;
m_nVertexCount=-1; //do ponownego zliczenia
SafeDeleteArray(m_pVNT); //usuwanie tablic, gdy były użyte do Vertex Array
{ // niewirtualne zwolnienie zasobów przez sprzątacz albo destruktor
// inna nazwa, żeby nie mieszało się z funkcją wirtualną sprzątacza
if (m_nVBOVertices) // jeśli było coś rezerwowane
{
glDeleteBuffersARB(1, &m_nVBOVertices); // Free The Memory
// WriteLog("Released VBO number "+AnsiString(m_nVBOVertices));
}
m_nVBOVertices = 0;
m_nVertexCount = -1; // do ponownego zliczenia
SafeDeleteArray(m_pVNT); // usuwanie tablic, gdy były użyte do Vertex Array
};
bool __fastcall CMesh::StartVBO()
{//początek rysowania elementów z VBO
if (m_nVertexCount<=0) return false; //nie ma nic do rysowania w ten sposób
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (m_nVBOVertices)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_nVBOVertices);
glVertexPointer(3,GL_FLOAT,sizeof(CVertNormTex),((char*)NULL)); //pozycje
glNormalPointer(GL_FLOAT,sizeof(CVertNormTex),((char*)NULL)+12); //normalne
glTexCoordPointer(2,GL_FLOAT,sizeof(CVertNormTex),((char*)NULL)+24); //wierzchołki
}
return true; //można rysować z VBO
{ // początek rysowania elementów z VBO
if (m_nVertexCount <= 0)
return false; // nie ma nic do rysowania w ten sposób
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (m_nVBOVertices)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBOVertices);
glVertexPointer(3, GL_FLOAT, sizeof(CVertNormTex), ((char *)NULL)); // pozycje
glNormalPointer(GL_FLOAT, sizeof(CVertNormTex), ((char *)NULL) + 12); // normalne
glTexCoordPointer(2, GL_FLOAT, sizeof(CVertNormTex), ((char *)NULL) + 24); // wierzchołki
}
return true; // można rysować z VBO
};
bool __fastcall CMesh::StartColorVBO()
{//początek rysowania punktów świecących z VBO
if (m_nVertexCount<=0) return false; //nie ma nic do rysowania w ten sposób
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
if (m_nVBOVertices)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB,m_nVBOVertices);
glVertexPointer(3,GL_FLOAT,sizeof(CVertNormTex),((char*)NULL)); //pozycje
//glColorPointer(3,GL_UNSIGNED_BYTE,sizeof(CVertNormTex),((char*)NULL)+12); //kolory
glColorPointer(3,GL_FLOAT,sizeof(CVertNormTex),((char*)NULL)+12); //kolory
}
return true; //można rysować z VBO
{ // początek rysowania punktów świecących z VBO
if (m_nVertexCount <= 0)
return false; // nie ma nic do rysowania w ten sposób
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
if (m_nVBOVertices)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_nVBOVertices);
glVertexPointer(3, GL_FLOAT, sizeof(CVertNormTex), ((char *)NULL)); // pozycje
// glColorPointer(3,GL_UNSIGNED_BYTE,sizeof(CVertNormTex),((char*)NULL)+12); //kolory
glColorPointer(3, GL_FLOAT, sizeof(CVertNormTex), ((char *)NULL) + 12); // kolory
}
return true; // można rysować z VBO
};
void __fastcall CMesh::EndVBO()
{//koniec użycia VBO
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
//glBindBuffer(GL_ARRAY_BUFFER,0); //takie coś psuje, mimo iż polecali użyć
glBindBufferARB(GL_ARRAY_BUFFER_ARB,0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0); //Ra: to na przyszłość
{ // koniec użycia VBO
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
// glBindBuffer(GL_ARRAY_BUFFER,0); //takie coś psuje, mimo iż polecali użyć
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); // Ra: to na przyszłość
};

45
VBO.h
View File

@@ -5,32 +5,31 @@
//---------------------------------------------------------------------------
class CVertNormTex
{
public:
float x; //X wierzchołka
float y; //Y wierzchołka
float z; //Z wierzchołka
float nx; //X wektora normalnego
float ny; //Y wektora normalnego
float nz; //Z wektora normalnego
float u; //U mapowania
float v; //V mapowania
public:
float x; // X wierzchołka
float y; // Y wierzchołka
float z; // Z wierzchołka
float nx; // X wektora normalnego
float ny; // Y wektora normalnego
float nz; // Z wektora normalnego
float u; // U mapowania
float v; // V mapowania
};
class CMesh
{//wsparcie dla VBO
public:
int m_nVertexCount; //liczba wierzchołków
CVertNormTex *m_pVNT;
unsigned int m_nVBOVertices; //numer VBO z wierzchołkami
__fastcall CMesh();
__fastcall ~CMesh();
void __fastcall MakeArray(int n); //tworzenie tablicy z elementami VNT
void __fastcall BuildVBOs(bool del=true); //zamiana tablic na VBO
void __fastcall Clear(); //zwolnienie zasobów
bool __fastcall StartVBO();
void __fastcall EndVBO();
bool __fastcall StartColorVBO();
{ // wsparcie dla VBO
public:
int m_nVertexCount; // liczba wierzchołków
CVertNormTex *m_pVNT;
unsigned int m_nVBOVertices; // numer VBO z wierzchołkami
__fastcall CMesh();
__fastcall ~CMesh();
void __fastcall MakeArray(int n); // tworzenie tablicy z elementami VNT
void __fastcall BuildVBOs(bool del = true); // zamiana tablic na VBO
void __fastcall Clear(); // zwolnienie zasobów
bool __fastcall StartVBO();
void __fastcall EndVBO();
bool __fastcall StartColorVBO();
};
#endif

4690
World.cpp

File diff suppressed because it is too large Load Diff

88
World.h
View File

@@ -3,7 +3,6 @@
#ifndef WorldH
#define WorldH
#include "Usefull.h"
#include "Classes.h"
#include "Texture.h"
@@ -16,49 +15,50 @@
class TWorld
{
void __fastcall InOutKey();
void __fastcall FollowView(bool wycisz=true);
void __fastcall DistantView();
public:
bool __fastcall Init(HWND NhWnd, HDC hDC);
HWND hWnd;
GLvoid __fastcall glPrint(const char *fmt);
void __fastcall OnKeyDown(int cKey);
void __fastcall OnKeyUp(int cKey);
//void __fastcall UpdateWindow();
void __fastcall OnMouseMove(double x, double y);
void __fastcall OnCommandGet(DaneRozkaz *pRozkaz);
bool __fastcall Update();
void __fastcall TrainDelete(TDynamicObject *d=NULL);
__fastcall TWorld();
__fastcall ~TWorld();
//double Aspect;
private:
AnsiString OutText1; //teksty na ekranie
AnsiString OutText2;
AnsiString OutText3;
AnsiString OutText4;
void ShowHints();
bool __fastcall Render();
TCamera Camera;
TGround Ground;
TTrain *Train;
TDynamicObject *pDynamicNearest;
bool Paused;
GLuint base; //numer DL dla znaków w napisach
GLuint light; //numer tekstury dla smugi
TSky Clouds;
TEvent *KeyEvents[10]; //eventy wyzwalane z klawiaury
TMoverParameters *mvControlled; //wskaŸnik na cz³on silnikowy, do wyœwietlania jego parametrów
int iCheckFPS; //kiedy znów sprawdziæ FPS, ¿eby wy³¹czaæ optymalizacji od razu do zera
double fTime50Hz; //bufor czasu dla komunikacji z PoKeys
double fTimeBuffer; //bufor czasu aktualizacji dla sta³ego kroku fizyki
double fMaxDt; //[s] krok czasowy fizyki (0.01 dla normalnych warunków)
int iPause; //wykrywanie zmian w zapauzowaniu
public:
void __fastcall ModifyTGA(const AnsiString &dir="");
void __fastcall CreateE3D(const AnsiString &dir="",bool dyn=false);
void __fastcall CabChange(TDynamicObject *old,TDynamicObject *now);
void __fastcall InOutKey();
void __fastcall FollowView(bool wycisz = true);
void __fastcall DistantView();
public:
bool __fastcall Init(HWND NhWnd, HDC hDC);
HWND hWnd;
GLvoid __fastcall glPrint(const char *fmt);
void __fastcall OnKeyDown(int cKey);
void __fastcall OnKeyUp(int cKey);
// void __fastcall UpdateWindow();
void __fastcall OnMouseMove(double x, double y);
void __fastcall OnCommandGet(DaneRozkaz *pRozkaz);
bool __fastcall Update();
void __fastcall TrainDelete(TDynamicObject *d = NULL);
__fastcall TWorld();
__fastcall ~TWorld();
// double Aspect;
private:
AnsiString OutText1; // teksty na ekranie
AnsiString OutText2;
AnsiString OutText3;
AnsiString OutText4;
void ShowHints();
bool __fastcall Render();
TCamera Camera;
TGround Ground;
TTrain *Train;
TDynamicObject *pDynamicNearest;
bool Paused;
GLuint base; // numer DL dla znaków w napisach
GLuint light; // numer tekstury dla smugi
TSky Clouds;
TEvent *KeyEvents[10]; // eventy wyzwalane z klawiaury
TMoverParameters *mvControlled; // wskaŸnik na cz³on silnikowy, do wyœwietlania jego parametrów
int iCheckFPS; // kiedy znów sprawdziæ FPS, ¿eby wy³¹czaæ optymalizacji od razu do zera
double fTime50Hz; // bufor czasu dla komunikacji z PoKeys
double fTimeBuffer; // bufor czasu aktualizacji dla sta³ego kroku fizyki
double fMaxDt; //[s] krok czasowy fizyki (0.01 dla normalnych warunków)
int iPause; // wykrywanie zmian w zapauzowaniu
public:
void __fastcall ModifyTGA(const AnsiString &dir = "");
void __fastcall CreateE3D(const AnsiString &dir = "", bool dyn = false);
void __fastcall CabChange(TDynamicObject *old, TDynamicObject *now);
};
//---------------------------------------------------------------------------
#endif

View File

@@ -2,116 +2,140 @@
#include "fastmath.h"
#include <cassert>
namespace Math3D {
namespace Math3D
{
void __fastcall vector3::RotateX(double angle)
{
double ty= y;
y= (cos(angle)*y-z*sin(angle));
z= (z*cos(angle)+sin(angle)*ty);
double ty = y;
y = (cos(angle) * y - z * sin(angle));
z = (z * cos(angle) + sin(angle) * ty);
};
void __fastcall vector3::RotateY(double angle)
{
double tx= x;
x= (cos(angle)*x+z*sin(angle));
z= (z*cos(angle)-sin(angle)*tx);
double tx = x;
x = (cos(angle) * x + z * sin(angle));
z = (z * cos(angle) - sin(angle) * tx);
};
void __fastcall vector3::RotateZ(double angle)
{
double ty= y;
y= (cos(angle)*y+x*sin(angle));
x= (x*cos(angle)-sin(angle)*ty);
double ty = y;
y = (cos(angle) * y + x * sin(angle));
x = (x * cos(angle) - sin(angle) * ty);
};
void inline __fastcall vector3::SafeNormalize()
{
double l= Length();
if (l==0)
double l = Length();
if (l == 0)
{
x=y=z=0;
x = y = z = 0;
}
else
{
x/= l;
y/= l;
z/= l;
x /= l;
y /= l;
z /= l;
}
}
// From code in Graphics Gems; p. 766
inline scalar_t det2x2 (scalar_t a, scalar_t b, scalar_t c, scalar_t d) {
return a*d - b*c;
inline scalar_t det2x2(scalar_t a, scalar_t b, scalar_t c, scalar_t d) { return a * d - b * c; }
inline scalar_t det3x3(scalar_t a1, scalar_t a2, scalar_t a3, scalar_t b1, scalar_t b2, scalar_t b3,
scalar_t c1, scalar_t c2, scalar_t c3)
{
return a1 * det2x2(b2, b3, c2, c3) - b1 * det2x2(a2, a3, c2, c3) + c1 * det2x2(a2, a3, b2, b3);
}
inline scalar_t det3x3 ( scalar_t a1, scalar_t a2, scalar_t a3,
scalar_t b1, scalar_t b2, scalar_t b3,
scalar_t c1, scalar_t c2, scalar_t c3) {
return a1 * det2x2(b2, b3, c2, c3)
- b1 * det2x2(a2, a3, c2, c3)
+ c1 * det2x2(a2, a3, b2, b3);
scalar_t Determinant(const matrix4x4 &m)
{
scalar_t a1 = m[0][0];
scalar_t a2 = m[1][0];
scalar_t a3 = m[2][0];
scalar_t a4 = m[3][0];
scalar_t b1 = m[0][1];
scalar_t b2 = m[1][1];
scalar_t b3 = m[2][1];
scalar_t b4 = m[3][1];
scalar_t c1 = m[0][2];
scalar_t c2 = m[1][2];
scalar_t c3 = m[2][2];
scalar_t c4 = m[3][2];
scalar_t d1 = m[0][3];
scalar_t d2 = m[1][3];
scalar_t d3 = m[2][3];
scalar_t 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);
}
scalar_t Determinant (const matrix4x4& m) {
scalar_t a1 = m[0][0]; scalar_t a2 = m[1][0]; scalar_t a3 = m[2][0]; scalar_t a4 = m[3][0];
scalar_t b1 = m[0][1]; scalar_t b2 = m[1][1]; scalar_t b3 = m[2][1]; scalar_t b4 = m[3][1];
scalar_t c1 = m[0][2]; scalar_t c2 = m[1][2]; scalar_t c3 = m[2][2]; scalar_t c4 = m[3][2];
scalar_t d1 = m[0][3]; scalar_t d2 = m[1][3]; scalar_t d3 = m[2][3]; scalar_t d4 = m[3][3];
matrix4x4 Adjoint(const matrix4x4 &m)
{
scalar_t a1 = m[0][0];
scalar_t a2 = m[0][1];
scalar_t a3 = m[0][2];
scalar_t a4 = m[0][3];
scalar_t b1 = m[1][0];
scalar_t b2 = m[1][1];
scalar_t b3 = m[1][2];
scalar_t b4 = m[1][3];
scalar_t c1 = m[2][0];
scalar_t c2 = m[2][1];
scalar_t c3 = m[2][2];
scalar_t c4 = m[2][3];
scalar_t d1 = m[3][0];
scalar_t d2 = m[3][1];
scalar_t d3 = m[3][2];
scalar_t 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);
// Adjoint(x,y) = -1^(x+y) * a(y,x)
// Where a(i,j) is the 3x3 determinant of m with row i and col j removed
matrix4x4 retVal;
retVal(0)[0] = det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
retVal(0)[1] = -det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
retVal(0)[2] = det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
retVal(0)[3] = -det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
retVal(1)[0] = -det3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
retVal(1)[1] = det3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
retVal(1)[2] = -det3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
retVal(1)[3] = det3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
retVal(2)[0] = det3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
retVal(2)[1] = -det3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
retVal(2)[2] = det3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
retVal(2)[3] = -det3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
retVal(3)[0] = -det3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
retVal(3)[1] = det3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
retVal(3)[2] = -det3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
retVal(3)[3] = det3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
return retVal;
}
matrix4x4 Adjoint (const matrix4x4& m) {
scalar_t a1 = m[0][0]; scalar_t a2 = m[0][1]; scalar_t a3 = m[0][2]; scalar_t a4 = m[0][3];
scalar_t b1 = m[1][0]; scalar_t b2 = m[1][1]; scalar_t b3 = m[1][2]; scalar_t b4 = m[1][3];
scalar_t c1 = m[2][0]; scalar_t c2 = m[2][1]; scalar_t c3 = m[2][2]; scalar_t c4 = m[2][3];
scalar_t d1 = m[3][0]; scalar_t d2 = m[3][1]; scalar_t d3 = m[3][2]; scalar_t d4 = m[3][3];
matrix4x4 Inverse(const matrix4x4 &m)
{
matrix4x4 retVal = Adjoint(m);
scalar_t det = Determinant(m);
assert(det);
// Adjoint(x,y) = -1^(x+y) * a(y,x)
// Where a(i,j) is the 3x3 determinant of m with row i and col j removed
matrix4x4 retVal;
retVal(0)[0] = det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
retVal(0)[1] = -det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
retVal(0)[2] = det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
retVal(0)[3] = -det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
retVal(i)[j] /= det;
}
}
retVal(1)[0] = -det3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
retVal(1)[1] = det3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
retVal(1)[2] = -det3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
retVal(1)[3] = det3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
retVal(2)[0] = det3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
retVal(2)[1] = -det3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
retVal(2)[2] = det3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
retVal(2)[3] = -det3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
retVal(3)[0] = -det3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
retVal(3)[1] = det3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
retVal(3)[2] = -det3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
retVal(3)[3] = det3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
return retVal;
}
matrix4x4 Inverse (const matrix4x4& m) {
matrix4x4 retVal = Adjoint(m);
scalar_t det = Determinant(m);
assert(det);
for (int i=0;i<4;++i) {
for (int j=0;j<4;++j) {
retVal(i)[j] /= det;
}
}
return retVal;
return retVal;
}
}
//**************************************
// Testing from here on.
//**************************************
@@ -123,240 +147,255 @@ using namespace std;
static int failures = 0;
void ReportFailure (const char* className, const char* testName, bool passed) {
cout << className;
if (passed)
cout << " passed test ";
else {
cout << " FAILED test ";
++failures;
}
cout << testName << "." << endl;
void ReportFailure(const char *className, const char *testName, bool passed)
{
cout << className;
if (passed)
cout << " passed test ";
else
{
cout << " FAILED test ";
++failures;
}
cout << testName << "." << endl;
}
const char* vector3Name = "vector3";
const char* matrix4x4Name = "matrix4x4";
const char *vector3Name = "vector3";
const char *matrix4x4Name = "matrix4x4";
void Testvector3Constructors(void) {
// Default ctor... just make sure it compiles
vector3 defaultCtorTest;
void Testvector3Constructors(void)
{
// Default ctor... just make sure it compiles
vector3 defaultCtorTest;
// Initializer ctor test (3 param)
vector3 initCtorTest(1, 2, 3);
ReportFailure (vector3Name, "initialized ctor (3 parameter version)", (initCtorTest[0] == 1 && initCtorTest[1] == 2 && initCtorTest[2] == 3 && initCtorTest[3] == 1));
// Initializer ctor test (3 param)
vector3 initCtorTest(1, 2, 3);
ReportFailure(vector3Name, "initialized ctor (3 parameter version)",
(initCtorTest[0] == 1 && initCtorTest[1] == 2 && initCtorTest[2] == 3 &&
initCtorTest[3] == 1));
// Initializer ctor test (4 param)
vector3 initCtorTest2 (1,2,3,4);
ReportFailure (vector3Name, "initialized ctor (4 parameter version)", (initCtorTest2[0] == 1 && initCtorTest2[1] == 2 && initCtorTest2[2] == 3 && initCtorTest2[3] == 4));
// Initializer ctor test (4 param)
vector3 initCtorTest2(1, 2, 3, 4);
ReportFailure(vector3Name, "initialized ctor (4 parameter version)",
(initCtorTest2[0] == 1 && initCtorTest2[1] == 2 && initCtorTest2[2] == 3 &&
initCtorTest2[3] == 4));
scalar_t initArray[] = { 1, 2, 3, 4};
vector3 initCtorArrayTest3 (initArray);
ReportFailure (vector3Name, "array initialized ctor (3 parameter version)", (initCtorArrayTest3[0] == 1 && initCtorArrayTest3[1] == 2 && initCtorArrayTest3[2] == 3 && initCtorArrayTest3[3] == 1));
scalar_t initArray[] = {1, 2, 3, 4};
vector3 initCtorArrayTest3(initArray);
ReportFailure(vector3Name, "array initialized ctor (3 parameter version)",
(initCtorArrayTest3[0] == 1 && initCtorArrayTest3[1] == 2 &&
initCtorArrayTest3[2] == 3 && initCtorArrayTest3[3] == 1));
vector3 initCtorArrayTest4 (initArray, 4);
ReportFailure (vector3Name, "array initialized ctor (4 parameter version)", (initCtorArrayTest4[0] == 1 && initCtorArrayTest4[1] == 2 && initCtorArrayTest4[2] == 3 && initCtorArrayTest4[3] == 4));
vector3 initCtorArrayTest4(initArray, 4);
ReportFailure(vector3Name, "array initialized ctor (4 parameter version)",
(initCtorArrayTest4[0] == 1 && initCtorArrayTest4[1] == 2 &&
initCtorArrayTest4[2] == 3 && initCtorArrayTest4[3] == 4));
// Copy ctor test
vector3 copyCtorTest(initCtorTest2);
ReportFailure (vector3Name, "copy ctor", (copyCtorTest[0] == 1 && copyCtorTest[1] == 2 && copyCtorTest[2] == 3 && copyCtorTest[3] == 4));
// Copy ctor test
vector3 copyCtorTest(initCtorTest2);
ReportFailure(vector3Name, "copy ctor", (copyCtorTest[0] == 1 && copyCtorTest[1] == 2 &&
copyCtorTest[2] == 3 && copyCtorTest[3] == 4));
}
void Testvector3Comparison(void) {
vector3 alpha(1,1,1);
vector3 beta(alpha);
vector3 gamma(2,3,4);
void Testvector3Comparison(void)
{
vector3 alpha(1, 1, 1);
vector3 beta(alpha);
vector3 gamma(2, 3, 4);
ReportFailure (vector3Name, "equivalence operator test 1", (alpha==beta));
ReportFailure (vector3Name, "equivalence operator test 2", (!(alpha == gamma)));
ReportFailure (vector3Name, "comparison operator test 1", !(alpha < beta));
ReportFailure (vector3Name, "comparison operator test 2", (alpha < gamma));
ReportFailure (vector3Name, "comparison operator test 3", !(gamma < beta));
ReportFailure(vector3Name, "equivalence operator test 1", (alpha == beta));
ReportFailure(vector3Name, "equivalence operator test 2", (!(alpha == gamma)));
ReportFailure(vector3Name, "comparison operator test 1", !(alpha < beta));
ReportFailure(vector3Name, "comparison operator test 2", (alpha < gamma));
ReportFailure(vector3Name, "comparison operator test 3", !(gamma < beta));
}
void Testvector3Assignment (void) {
vector3 alpha(1,1,1,1);
vector3 beta(10,10,10,10);
alpha = beta;
ReportFailure (vector3Name, "assignment operator", (alpha == beta));
void Testvector3Assignment(void)
{
vector3 alpha(1, 1, 1, 1);
vector3 beta(10, 10, 10, 10);
alpha = beta;
ReportFailure(vector3Name, "assignment operator", (alpha == beta));
}
void Testvector3UnaryOps (void) {
vector3 alpha(10,10,10,10);
vector3 beta(-10,-10,-10,-10);
alpha = -alpha;
ReportFailure(vector3Name, "negation operator", (alpha==beta));
void Testvector3UnaryOps(void)
{
vector3 alpha(10, 10, 10, 10);
vector3 beta(-10, -10, -10, -10);
alpha = -alpha;
ReportFailure(vector3Name, "negation operator", (alpha == beta));
ReportFailure(vector3Name, "length squared 3 element version", LengthSquared3(alpha) == 300);
ReportFailure(vector3Name, "length 3 element version", Length3(alpha) == SQRT_FUNCTION(300));
ReportFailure(vector3Name, "length squared 4 element version", LengthSquared4(alpha) == 400);
ReportFailure(vector3Name, "length 4 element version", Length4(alpha) == SQRT_FUNCTION(400));
ReportFailure(vector3Name, "length squared 3 element version", LengthSquared3(alpha) == 300);
ReportFailure(vector3Name, "length 3 element version", Length3(alpha) == SQRT_FUNCTION(300));
ReportFailure(vector3Name, "length squared 4 element version", LengthSquared4(alpha) == 400);
ReportFailure(vector3Name, "length 4 element version", Length4(alpha) == SQRT_FUNCTION(400));
// Manually normalize beta
// Done without /= on vector3, as we want to be independant of failure of /=
// Earlier failures should be resolved before later ones (just like C++)
beta = alpha;
for (int i=0;i<3;++i) beta(i) /= SQRT_FUNCTION(300);
beta(3) = 1;
ReportFailure(vector3Name, "normalize 3 element version", Normalize3(alpha) == beta);
// Manually normalize beta
// Done without /= on vector3, as we want to be independant of failure of /=
// Earlier failures should be resolved before later ones (just like C++)
beta = alpha;
for (int i = 0; i < 3; ++i)
beta(i) /= SQRT_FUNCTION(300);
beta(3) = 1;
ReportFailure(vector3Name, "normalize 3 element version", Normalize3(alpha) == beta);
beta = alpha;
for (int i=0;i<4;++i) beta(i) /= SQRT_FUNCTION(400);
ReportFailure(vector3Name, "normalize 4 element version", Normalize4(alpha) == beta);
beta = alpha;
for (int i = 0; i < 4; ++i)
beta(i) /= SQRT_FUNCTION(400);
ReportFailure(vector3Name, "normalize 4 element version", Normalize4(alpha) == beta);
}
void Testvector3BinaryOps (void) {
// Vector * Matrix is tested in Testmatrix4x4BinaryOps
vector3 testVec(1,1,1,1);
vector3 deltaVec(1,2,3,4);
vector3 crossVec(1, -2, 1, 1); // testVec x deltaVec
void Testvector3BinaryOps(void)
{
// Vector * Matrix is tested in Testmatrix4x4BinaryOps
vector3 testVec(1, 1, 1, 1);
vector3 deltaVec(1, 2, 3, 4);
vector3 crossVec(1, -2, 1, 1); // testVec x deltaVec
vector3 factorVec(10,10,10,10);
vector3 sumVec(2,3,4,5);
vector3 difVec(0,-1,-2,-3);
vector3 testVec2;
vector3 factorVec(10, 10, 10, 10);
vector3 sumVec(2, 3, 4, 5);
vector3 difVec(0, -1, -2, -3);
vector3 testVec2;
ReportFailure(vector3Name, "scalar multiply 1", (testVec * 10) == factorVec);
ReportFailure(vector3Name, "scalar multiply 2", (10 * testVec) == factorVec);
testVec2 = testVec;
ReportFailure(vector3Name, "scalar multiply and store", (testVec2 *= 10) == factorVec);
ReportFailure(vector3Name, "scalar multiply 1", (testVec * 10) == factorVec);
ReportFailure(vector3Name, "scalar multiply 2", (10 * testVec) == factorVec);
testVec2 = testVec;
ReportFailure(vector3Name, "scalar multiply and store", (testVec2 *= 10) == factorVec);
ReportFailure(vector3Name, "scalar divide", (factorVec / 10) == testVec);
testVec2 = factorVec;
ReportFailure(vector3Name, "scalar divide and store", (testVec2 /= 10) == testVec);
ReportFailure(vector3Name, "scalar divide", (factorVec / 10) == testVec);
testVec2 = factorVec;
ReportFailure(vector3Name, "scalar divide and store", (testVec2 /= 10) == testVec);
ReportFailure(vector3Name, "vector addition", (testVec + deltaVec) == sumVec);
testVec2 = testVec;
ReportFailure(vector3Name, "vector addition and store", (testVec2 += deltaVec) == sumVec);
ReportFailure(vector3Name, "vector addition", (testVec + deltaVec) == sumVec);
testVec2 = testVec;
ReportFailure(vector3Name, "vector addition and store", (testVec2 += deltaVec) == sumVec);
ReportFailure(vector3Name, "vector subtraction", (testVec - deltaVec) == difVec);
testVec2 = testVec;
ReportFailure(vector3Name, "vector subtraction and store", (testVec2 -= deltaVec) == difVec);
ReportFailure(vector3Name, "vector subtraction", (testVec - deltaVec) == difVec);
testVec2 = testVec;
ReportFailure(vector3Name, "vector subtraction and store", (testVec2 -= deltaVec) == difVec);
ReportFailure(vector3Name, "3 element dot product", 6 == DotProduct3(testVec, deltaVec));
ReportFailure(vector3Name, "4 element dot product", 10 == DotProduct4(testVec, deltaVec));
ReportFailure(vector3Name, "3 element dot product", 6 == DotProduct3(testVec, deltaVec));
ReportFailure(vector3Name, "4 element dot product", 10 == DotProduct4(testVec, deltaVec));
ReportFailure(vector3Name, "cross product", crossVec == CrossProduct(testVec, deltaVec));
ReportFailure(vector3Name, "cross product", crossVec == CrossProduct(testVec, deltaVec));
}
void Testvector3 (void) {
// Accessors cannot be tested effectively...
// They are really trivial, and so don't really need testing,
// but more importantly, how do you test the ctors without assuming
// the accessors work? Conversely, how do you test the acccessors
// without assuming the ctors work? Chicken and egg problem, and I
// decided on testing the ctors, not the accessors.
Testvector3Constructors();
Testvector3Comparison();
Testvector3Assignment();
Testvector3UnaryOps();
Testvector3BinaryOps();
void Testvector3(void)
{
// Accessors cannot be tested effectively...
// They are really trivial, and so don't really need testing,
// but more importantly, how do you test the ctors without assuming
// the accessors work? Conversely, how do you test the acccessors
// without assuming the ctors work? Chicken and egg problem, and I
// decided on testing the ctors, not the accessors.
Testvector3Constructors();
Testvector3Comparison();
Testvector3Assignment();
Testvector3UnaryOps();
Testvector3BinaryOps();
}
void Testmatrix4x4Constructors (void) {
// Check if default ctor compiles
matrix4x4 defaultTest;
void Testmatrix4x4Constructors(void)
{
// Check if default ctor compiles
matrix4x4 defaultTest;
scalar_t initArray[] = { 0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15 };
matrix4x4 arrayTest;
arrayTest.C_Matrix(initArray);
bool passedTest = true;
for (int x=0;x<4;++x) for (int y=0;y<4;++y)
if (arrayTest[x][y] != initArray[(y<<2) + x]) passedTest = false;
ReportFailure(matrix4x4Name, "array constructor", passedTest);
scalar_t initArray[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
matrix4x4 arrayTest;
arrayTest.C_Matrix(initArray);
bool passedTest = true;
for (int x = 0; x < 4; ++x)
for (int y = 0; y < 4; ++y)
if (arrayTest[x][y] != initArray[(y << 2) + x])
passedTest = false;
ReportFailure(matrix4x4Name, "array constructor", passedTest);
matrix4x4 copyTest(arrayTest);
passedTest = true;
for (int x=0;x<4;++x) for (int y=0;y<4;++y)
if (arrayTest[x][y] != copyTest[x][y]) passedTest = false;
ReportFailure(matrix4x4Name, "copy constructor", passedTest);
matrix4x4 copyTest(arrayTest);
passedTest = true;
for (int x = 0; x < 4; ++x)
for (int y = 0; y < 4; ++y)
if (arrayTest[x][y] != copyTest[x][y])
passedTest = false;
ReportFailure(matrix4x4Name, "copy constructor", passedTest);
}
void Testmatrix4x4Comparison (void) {
scalar_t initArray[] = { 0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15 };
scalar_t initArray2[] = { 1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1,
1, 1, 1, 1 };
matrix4x4 alpha, beta, gamma;
alpha.C_Matrix(initArray);
beta.C_Matrix(initArray);
gamma.C_Matrix(initArray2);
void Testmatrix4x4Comparison(void)
{
scalar_t initArray[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
scalar_t initArray2[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
matrix4x4 alpha, beta, gamma;
alpha.C_Matrix(initArray);
beta.C_Matrix(initArray);
gamma.C_Matrix(initArray2);
ReportFailure(matrix4x4Name, "equality test 1", alpha == beta);
ReportFailure(matrix4x4Name, "equality test 2", !(alpha == gamma));
ReportFailure(matrix4x4Name, "comparison test 1", alpha < gamma);
ReportFailure(matrix4x4Name, "comparison test 2", !(gamma < alpha));
ReportFailure(matrix4x4Name, "comparison test 3", !(alpha < beta));
ReportFailure(matrix4x4Name, "equality test 1", alpha == beta);
ReportFailure(matrix4x4Name, "equality test 2", !(alpha == gamma));
ReportFailure(matrix4x4Name, "comparison test 1", alpha < gamma);
ReportFailure(matrix4x4Name, "comparison test 2", !(gamma < alpha));
ReportFailure(matrix4x4Name, "comparison test 3", !(alpha < beta));
}
void Testmatrix4x4BinaryOps (void) {
scalar_t initVector[] = { 0, 1, 2, 3 };
scalar_t initMatrix[] = { 0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15 };
scalar_t resultVector[] = { 0 * 0 + 1 * 1 + 2 * 2 + 3 * 3,
0 * 4 + 1 * 5 + 2 * 6 + 3 * 7,
0 * 8 + 1 * 9 + 2 * 10 + 3 * 11,
0 * 12 + 1 * 13 + 2 * 14 + 3 * 15 };
void Testmatrix4x4BinaryOps(void)
{
scalar_t initVector[] = {0, 1, 2, 3};
scalar_t initMatrix[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
scalar_t resultVector[] = {0 * 0 + 1 * 1 + 2 * 2 + 3 * 3, 0 * 4 + 1 * 5 + 2 * 6 + 3 * 7,
0 * 8 + 1 * 9 + 2 * 10 + 3 * 11, 0 * 12 + 1 * 13 + 2 * 14 + 3 * 15};
vector3 vector1 (initVector, 4);
matrix4x4 matrix1;
matrix1.C_Matrix(initMatrix);
vector3 vectorTest (resultVector, 4);
ReportFailure (matrix4x4Name, "matrix * vector", vectorTest == matrix1 * vector1);
vector3 vector1(initVector, 4);
matrix4x4 matrix1;
matrix1.C_Matrix(initMatrix);
vector3 vectorTest(resultVector, 4);
ReportFailure(matrix4x4Name, "matrix * vector", vectorTest == matrix1 * vector1);
scalar_t initMatrix2[] = { 15, 14, 13, 12,
11, 10, 9, 8,
7, 6, 5, 4,
3, 2, 1, 0 };
scalar_t initMatrix2[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
matrix4x4 matrix2;
matrix2.C_Matrix(initMatrix2);
matrix4x4 resultMatrix;
for (int x=0;x<4;++x) for (int y=0;y<4;++y) {
resultMatrix(x)[y] = 0;
for (int i=0;i<4;++i) resultMatrix(x)[y] += matrix1[i][y] * matrix2[x][i];
}
ReportFailure (matrix4x4Name, "matrix * matrix", resultMatrix == matrix1 * matrix2);
matrix4x4 matrix2;
matrix2.C_Matrix(initMatrix2);
matrix4x4 resultMatrix;
for (int x = 0; x < 4; ++x)
for (int y = 0; y < 4; ++y)
{
resultMatrix(x)[y] = 0;
for (int i = 0; i < 4; ++i)
resultMatrix(x)[y] += matrix1[i][y] * matrix2[x][i];
}
ReportFailure(matrix4x4Name, "matrix * matrix", resultMatrix == matrix1 * matrix2);
}
void Testmatrix4x4 (void) {
Testmatrix4x4Constructors();
Testmatrix4x4Comparison();
Testmatrix4x4BinaryOps();
void Testmatrix4x4(void)
{
Testmatrix4x4Constructors();
Testmatrix4x4Comparison();
Testmatrix4x4BinaryOps();
}
int main (int, char*[]) {
int vectorFailures = 0;
int matrixFailures = 0;
Testvector3();
vectorFailures = failures;
failures = 0;
int main(int, char *[])
{
int vectorFailures = 0;
int matrixFailures = 0;
Testvector3();
vectorFailures = failures;
failures = 0;
Testmatrix4x4();
matrixFailures = failures;
Testmatrix4x4();
matrixFailures = failures;
cout << endl << "****************************************" << endl;
cout << "* *" << endl;
if (vectorFailures + matrixFailures == 0)
cout << "* No failures detected in Math3D *" << endl;
else {
cout << "* FAILURES DETECTED IN MATH3D! *" << endl;
cout << "* Total vector3 failures: " << vectorFailures << " *" << endl;
cout << "* Total matrix4x4 failures: " << matrixFailures << " *" << endl;
cout << "* Total Failures in Math3D: " << vectorFailures + matrixFailures << " *" << endl;
cout << endl << "****************************************" << endl;
cout << "* *" << endl;
if (vectorFailures + matrixFailures == 0)
cout << "* No failures detected in Math3D *" << endl;
else
{
cout << "* FAILURES DETECTED IN MATH3D! *" << endl;
cout << "* Total vector3 failures: " << vectorFailures << " *" << endl;
cout << "* Total matrix4x4 failures: " << matrixFailures << " *" << endl;
cout << "* Total Failures in Math3D: " << vectorFailures + matrixFailures << " *"
<< endl;
}
cout << "* *" << endl;
cout << "****************************************" << endl;
}
cout << "* *" << endl;
cout << "****************************************" << endl;
return 0;
return 0;
}
#endif

841
dumb3d.h
View File

@@ -4,7 +4,8 @@
//#include <cmath>
#include <fastmath.h>
namespace Math3D {
namespace Math3D
{
// Define this to have Math3D.cp generate a main which tests these classes
//#define TEST_MATH3D
@@ -17,16 +18,20 @@ namespace Math3D {
typedef double scalar_t;
// inline pass-throughs to various basic math functions
// written in this style to allow for easy substitution with more efficient versions
inline scalar_t SINE_FUNCTION (scalar_t x) { return sin(x); }
inline scalar_t COSINE_FUNCTION (scalar_t x) { return cos(x); }
inline scalar_t SQRT_FUNCTION (scalar_t x) { return sqrt(x); }
inline scalar_t SINE_FUNCTION(scalar_t x) { return sin(x); }
inline scalar_t COSINE_FUNCTION(scalar_t x) { return cos(x); }
inline scalar_t SQRT_FUNCTION(scalar_t x) { return sqrt(x); }
// 2 element vector
class vector2 {
public:
vector2 (void) {}
__fastcall vector2 (scalar_t a, scalar_t b)
{ x=a; y=b; }
class vector2
{
public:
vector2(void) {}
__fastcall vector2(scalar_t a, scalar_t b)
{
x = a;
y = b;
}
double x;
union
{
@@ -35,15 +40,20 @@ public:
};
};
// 3 element vector
class vector3 {
public:
vector3 (void) {}
__fastcall vector3 (scalar_t a, scalar_t b, scalar_t c)
{ x=a; y=b; z=c; }
class vector3
{
public:
vector3(void) {}
__fastcall vector3(scalar_t a, scalar_t b, scalar_t c)
{
x = a;
y = b;
z = c;
}
// The int parameter is the number of elements to copy from initArray (3 or 4)
// explicit vector3(scalar_t* initArray, int arraySize = 3)
// { for (int i = 0;i<arraySize;++i) e[i] = initArray[i]; }
// The int parameter is the number of elements to copy from initArray (3 or 4)
// explicit vector3(scalar_t* initArray, int arraySize = 3)
// { for (int i = 0;i<arraySize;++i) e[i] = initArray[i]; }
void __fastcall RotateX(double angle);
void __fastcall RotateY(double angle);
@@ -52,396 +62,478 @@ public:
void inline __fastcall Normalize();
void inline __fastcall SafeNormalize();
double inline __fastcall Length();
void inline __fastcall Zero() {x=y=z=0.0;};
void inline __fastcall Zero() { x = y = z = 0.0; };
// [] is to read, () is to write (const correctness)
// const scalar_t& operator[] (int i) const { return e[i]; }
// scalar_t& operator() (int i) { return e[i]; }
// [] is to read, () is to write (const correctness)
// const scalar_t& operator[] (int i) const { return e[i]; }
// scalar_t& operator() (int i) { return e[i]; }
// Provides access to the underlying array; useful for passing this class off to C APIs
const scalar_t* readArray(void) { return &x; }
scalar_t* getArray(void) { return &x; }
// Provides access to the underlying array; useful for passing this class off to C APIs
const scalar_t *readArray(void) { return &x; }
scalar_t *getArray(void) { return &x; }
// union
// {
// struct
// {
double x,y,z;
// };
// scalar_t e[3];
// };
bool inline __fastcall Equal(vector3 *v)
{//sprawdzenie odleg³oœci punktów
if (fabs(x-v->x)>0.02) return false; //szeœcian zamiast kuli
if (fabs(z-v->z)>0.02) return false;
if (fabs(y-v->y)>0.02) return false;
return true;
};
// union
// {
// struct
// {
double x, y, z;
// };
// scalar_t e[3];
// };
bool inline __fastcall Equal(vector3 *v)
{ // sprawdzenie odleg³oœci punktów
if (fabs(x - v->x) > 0.02)
return false; // szeœcian zamiast kuli
if (fabs(z - v->z) > 0.02)
return false;
if (fabs(y - v->y) > 0.02)
return false;
return true;
};
private:
private:
};
// 4 element matrix
class matrix4x4 {
public:
matrix4x4 (void) {}
class matrix4x4
{
public:
matrix4x4(void) {}
// When defining matrices in C arrays, it is easiest to define them with
// the column increasing fastest. However, some APIs (OpenGL in particular) do this
// backwards, hence the "constructor" from C matrices, or from OpenGL matrices.
// Note that matrices are stored internally in OpenGL format.
void C_Matrix (scalar_t* initArray)
{ int i = 0; for (int y=0;y<4;++y) for (int x=0;x<4;++x) (*this)(x)[y] = initArray[i++]; }
void OpenGL_Matrix (scalar_t* initArray)
{ int i = 0; for (int x = 0; x < 4; ++x) for (int y=0;y<4;++y) (*this)(x)[y] = initArray[i++]; }
// When defining matrices in C arrays, it is easiest to define them with
// the column increasing fastest. However, some APIs (OpenGL in particular) do this
// backwards, hence the "constructor" from C matrices, or from OpenGL matrices.
// Note that matrices are stored internally in OpenGL format.
void C_Matrix(scalar_t *initArray)
{
int i = 0;
for (int y = 0; y < 4; ++y)
for (int x = 0; x < 4; ++x)
(*this)(x)[y] = initArray[i++];
}
void OpenGL_Matrix(scalar_t *initArray)
{
int i = 0;
for (int x = 0; x < 4; ++x)
for (int y = 0; y < 4; ++y)
(*this)(x)[y] = initArray[i++];
}
// [] is to read, () is to write (const correctness)
// m[x][y] or m(x)[y] is the correct form
const scalar_t* operator[] (int i) const { return &e[i<<2]; }
scalar_t* operator() (int i) { return &e[i<<2]; }
// [] is to read, () is to write (const correctness)
// m[x][y] or m(x)[y] is the correct form
const scalar_t *operator[](int i) const { return &e[i << 2]; }
scalar_t *operator()(int i) { return &e[i << 2]; }
// Low-level access to the array.
const scalar_t* readArray (void) { return e; }
scalar_t* getArray(void) { return e; }
// Low-level access to the array.
const scalar_t *readArray(void) { return e; }
scalar_t *getArray(void) { return e; }
// Construct various matrices; REPLACES CURRENT CONTENTS OF THE MATRIX!
// Written this way to work in-place and hence be somewhat more efficient
void Identity (void) { for (int i=0;i<16;++i) e[i] = 0; e[0] = 1; e[5] = 1; e[10] = 1; e[15] = 1; }
inline matrix4x4& Rotation (scalar_t angle, vector3 axis);
inline matrix4x4& Translation(const vector3& translation);
inline matrix4x4& Scale (scalar_t x, scalar_t y, scalar_t z);
inline matrix4x4& BasisChange (const vector3& v, const vector3& n);
inline matrix4x4& BasisChange (const vector3& u, const vector3& v, const vector3& n);
inline matrix4x4& ProjectionMatrix (bool perspective, scalar_t l, scalar_t r, scalar_t t, scalar_t b, scalar_t n, scalar_t f);
void InitialRotate()
{//taka specjalna rotacja, nie ma co ci¹gaæ trygonometrii
double 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 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;
}
// Construct various matrices; REPLACES CURRENT CONTENTS OF THE MATRIX!
// Written this way to work in-place and hence be somewhat more efficient
void Identity(void)
{
for (int i = 0; i < 16; ++i)
e[i] = 0;
e[0] = 1;
e[5] = 1;
e[10] = 1;
e[15] = 1;
}
inline matrix4x4 &Rotation(scalar_t angle, vector3 axis);
inline matrix4x4 &Translation(const vector3 &translation);
inline matrix4x4 &Scale(scalar_t x, scalar_t y, scalar_t z);
inline matrix4x4 &BasisChange(const vector3 &v, const vector3 &n);
inline matrix4x4 &BasisChange(const vector3 &u, const vector3 &v, const vector3 &n);
inline matrix4x4 &ProjectionMatrix(bool perspective, scalar_t l, scalar_t r, scalar_t t,
scalar_t b, scalar_t n, scalar_t f);
void InitialRotate()
{ // taka specjalna rotacja, nie ma co ci¹gaæ trygonometrii
double 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 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;
}
private:
scalar_t e[16];
private:
scalar_t e[16];
};
// Scalar operations
// Returns false if there are 0 solutions
inline bool SolveQuadratic (scalar_t a, scalar_t b, scalar_t c, scalar_t* x1, scalar_t* x2);
inline bool SolveQuadratic(scalar_t a, scalar_t b, scalar_t c, scalar_t *x1, scalar_t *x2);
// Vector operations
inline bool operator== (const vector3&, const vector3&);
inline bool operator< (const vector3&, const vector3&);
inline bool operator==(const vector3 &, const vector3 &);
inline bool operator<(const vector3 &, const vector3 &);
inline vector3 operator- (const vector3&);
inline vector3 operator* (const vector3&, scalar_t);
inline vector3 operator* (scalar_t, const vector3&);
inline vector3& operator*= (vector3&, scalar_t);
inline vector3 operator/ (const vector3&, scalar_t);
inline vector3& operator/= (vector3&, scalar_t);
inline vector3 operator-(const vector3 &);
inline vector3 operator*(const vector3 &, scalar_t);
inline vector3 operator*(scalar_t, const vector3 &);
inline vector3 &operator*=(vector3 &, scalar_t);
inline vector3 operator/(const vector3 &, scalar_t);
inline vector3 &operator/=(vector3 &, scalar_t);
inline vector3 operator+ (const vector3&, const vector3&);
inline vector3& operator+= (vector3&, const vector3&);
inline vector3 operator- (const vector3&, const vector3&);
inline vector3& operator-= (vector3&, const vector3&);
inline vector3 operator+(const vector3 &, const vector3 &);
inline vector3 &operator+=(vector3 &, const vector3 &);
inline vector3 operator-(const vector3 &, const vector3 &);
inline vector3 &operator-=(vector3 &, const vector3 &);
// X3 is the 3 element version of a function, X4 is four element
inline scalar_t LengthSquared3 (const vector3&);
inline scalar_t LengthSquared4 (const vector3&);
inline scalar_t Length3 (const vector3&);
inline scalar_t Length4 (const vector3&);
inline vector3 Normalize (const vector3&);
inline vector3 Normalize4 (const vector3&);
inline scalar_t DotProduct (const vector3&, const vector3&);
inline scalar_t DotProduct4 (const vector3&, const vector3&);
inline scalar_t LengthSquared3(const vector3 &);
inline scalar_t LengthSquared4(const vector3 &);
inline scalar_t Length3(const vector3 &);
inline scalar_t Length4(const vector3 &);
inline vector3 Normalize(const vector3 &);
inline vector3 Normalize4(const vector3 &);
inline scalar_t DotProduct(const vector3 &, const vector3 &);
inline scalar_t DotProduct4(const vector3 &, const vector3 &);
// Cross product is only defined for 3 elements
inline vector3 CrossProduct (const vector3&, const vector3&);
inline vector3 CrossProduct(const vector3 &, const vector3 &);
inline vector3 operator* (const matrix4x4&, const vector3&);
inline vector3 operator*(const matrix4x4 &, const vector3 &);
// Matrix operations
inline bool operator== (const matrix4x4&, const matrix4x4&);
inline bool operator< (const matrix4x4&, const matrix4x4&);
inline bool operator==(const matrix4x4 &, const matrix4x4 &);
inline bool operator<(const matrix4x4 &, const matrix4x4 &);
inline matrix4x4 operator* (const matrix4x4&, const matrix4x4&);
inline matrix4x4 operator*(const matrix4x4 &, const matrix4x4 &);
inline matrix4x4 Transpose (const matrix4x4&);
scalar_t Determinant (const matrix4x4&);
matrix4x4 Adjoint (const matrix4x4&);
matrix4x4 Inverse (const matrix4x4&);
inline matrix4x4 Transpose(const matrix4x4 &);
scalar_t Determinant(const matrix4x4 &);
matrix4x4 Adjoint(const matrix4x4 &);
matrix4x4 Inverse(const matrix4x4 &);
// Inline implementations follow
inline bool SolveQuadratic (scalar_t a, scalar_t b, scalar_t c, scalar_t* x1, scalar_t* x2) {
// If a == 0, solve a linear equation
if (a == 0) {
if (b == 0) return false;
*x1 = c / b;
*x2 = *x1;
return true;
} else {
scalar_t det = b * b - 4 * a * c;
if (det < 0) return false;
det = SQRT_FUNCTION(det) / (2 * a);
scalar_t prefix = -b / (2*a);
*x1 = prefix + det;
*x2 = prefix - det;
return true;
}
}
inline bool operator== (const vector3& v1, const vector3& v2)
{ return (v1.x==v2.x&&v1.y==v2.y&&v1.z==v2.z); }
inline bool operator< (const vector3& v1, const vector3& v2) {
// for (int i=0;i<4;++i)
// if (v1[i] < v2[i]) return true;
// else if (v1[i] > v2[i]) return false;
return false;
}
inline vector3 operator- (const vector3& v)
{ return vector3(-v.x, -v.y, -v.z); }
inline vector3 operator* (const vector3& v, scalar_t k)
{ return vector3(k*v.x, k*v.y, k*v.z); }
inline vector3 operator* (scalar_t k, const vector3& v)
{ return v * k; }
inline vector3& operator*= (vector3& v, scalar_t k)
{ v.x*= k; v.y*= k; v.z*= k; return v; };
inline vector3 operator/ (const vector3& v, scalar_t k)
{ return vector3(v.x/k, v.y/k, v.z/k); }
inline vector3& operator/= (vector3& v, scalar_t k)
{ v.x/= k; v.y/= k; v.z/= k; return v; }
inline scalar_t LengthSquared3 (const vector3& v)
{ return DotProduct(v,v); }
inline scalar_t LengthSquared4 (const vector3& v)
{ return DotProduct4(v,v); }
inline scalar_t Length3 (const vector3& v)
{ return SQRT_FUNCTION(LengthSquared3(v)); }
inline scalar_t Length4 (const vector3& v)
{ return SQRT_FUNCTION(LengthSquared4(v)); }
inline vector3 Normalize (const vector3& v)
{ vector3 retVal = v / Length3(v); return retVal; }
inline vector3 SafeNormalize(const vector3& v)
inline bool SolveQuadratic(scalar_t a, scalar_t b, scalar_t c, scalar_t *x1, scalar_t *x2)
{
double l= Length3(v);
vector3 retVal;
if (l==0)
retVal.x=retVal.y=retVal.z=0;
else
retVal=v/l;
return retVal;
}
inline vector3 Normalize4 (const vector3& v)
{ return v / Length4(v); }
inline vector3 operator+ (const vector3& v1, const vector3& v2)
{ return vector3(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z); }
inline vector3& operator+= (vector3& v1, const vector3& v2)
{ v1.x+= v2.x; v1.y+= v2.y; v1.z+= v2.z; return v1;}
inline vector3 operator- (const vector3& v1, const vector3& v2)
{ return vector3(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z); }
inline vector3& operator-= (vector3& v1, const vector3& v2)
{ v1.x-= v2.x; v1.y-= v2.y; v1.z-= v2.z; return v1;}
inline scalar_t DotProduct (const vector3& v1, const vector3& v2)
{ return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; }
inline scalar_t DotProduct4 (const vector3& v1, const vector3& v2)
{ return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z; }
inline vector3 CrossProduct (const vector3& v1, const vector3& v2) {
return vector3( v1.y * v2.z - v1.z * v2.y
,v2.x * v1.z - v2.z * v1.x
,v1.x * v2.y - v1.y * v2.x);
// If a == 0, solve a linear equation
if (a == 0)
{
if (b == 0)
return false;
*x1 = c / b;
*x2 = *x1;
return true;
}
else
{
scalar_t det = b * b - 4 * a * c;
if (det < 0)
return false;
det = SQRT_FUNCTION(det) / (2 * a);
scalar_t prefix = -b / (2 * a);
*x1 = prefix + det;
*x2 = prefix - det;
return true;
}
}
inline vector3 operator* (const matrix4x4& m, const vector3& v) {
return vector3( 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 bool operator==(const vector3 &v1, const vector3 &v2)
{
return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z);
}
inline bool operator<(const vector3 &v1, const vector3 &v2)
{
// for (int i=0;i<4;++i)
// if (v1[i] < v2[i]) return true;
// else if (v1[i] > v2[i]) return false;
return false;
}
inline vector3 operator-(const vector3 &v) { return vector3(-v.x, -v.y, -v.z); }
inline vector3 operator*(const vector3 &v, scalar_t k)
{
return vector3(k * v.x, k * v.y, k * v.z);
}
inline vector3 operator*(scalar_t k, const vector3 &v) { return v * k; }
inline vector3 &operator*=(vector3 &v, scalar_t k)
{
v.x *= k;
v.y *= k;
v.z *= k;
return v;
};
inline vector3 operator/(const vector3 &v, scalar_t k)
{
return vector3(v.x / k, v.y / k, v.z / k);
}
inline vector3 &operator/=(vector3 &v, scalar_t k)
{
v.x /= k;
v.y /= k;
v.z /= k;
return v;
}
inline scalar_t LengthSquared3(const vector3 &v) { return DotProduct(v, v); }
inline scalar_t LengthSquared4(const vector3 &v) { return DotProduct4(v, v); }
inline scalar_t Length3(const vector3 &v) { return SQRT_FUNCTION(LengthSquared3(v)); }
inline scalar_t Length4(const vector3 &v) { return SQRT_FUNCTION(LengthSquared4(v)); }
inline vector3 Normalize(const vector3 &v)
{
vector3 retVal = v / Length3(v);
return retVal;
}
inline vector3 SafeNormalize(const vector3 &v)
{
double l = Length3(v);
vector3 retVal;
if (l == 0)
retVal.x = retVal.y = retVal.z = 0;
else
retVal = v / l;
return retVal;
}
inline vector3 Normalize4(const vector3 &v) { return v / Length4(v); }
inline vector3 operator+(const vector3 &v1, const vector3 &v2)
{
return vector3(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}
inline vector3 &operator+=(vector3 &v1, const vector3 &v2)
{
v1.x += v2.x;
v1.y += v2.y;
v1.z += v2.z;
return v1;
}
inline vector3 operator-(const vector3 &v1, const vector3 &v2)
{
return vector3(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}
inline vector3 &operator-=(vector3 &v1, const vector3 &v2)
{
v1.x -= v2.x;
v1.y -= v2.y;
v1.z -= v2.z;
return v1;
}
inline scalar_t DotProduct(const vector3 &v1, const vector3 &v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
inline scalar_t DotProduct4(const vector3 &v1, const vector3 &v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
inline vector3 CrossProduct(const vector3 &v1, const vector3 &v2)
{
return vector3(v1.y * v2.z - v1.z * v2.y, v2.x * v1.z - v2.z * v1.x, v1.x * v2.y - v1.y * v2.x);
}
inline vector3 operator*(const matrix4x4 &m, const vector3 &v)
{
return vector3(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]);
}
void inline __fastcall vector3::Normalize()
{
double il= 1/Length();
x*= il;
y*= il;
z*= il;
double il = 1 / Length();
x *= il;
y *= il;
z *= il;
}
double inline __fastcall vector3::Length()
double inline __fastcall vector3::Length() { return SQRT_FUNCTION(x * x + y * y + z * z); }
inline bool operator==(const matrix4x4 &m1, const matrix4x4 &m2)
{
return SQRT_FUNCTION(x*x+y*y+z*z);
for (int x = 0; x < 4; ++x)
for (int y = 0; y < 4; ++y)
if (m1[x][y] != m2[x][y])
return false;
return true;
}
inline bool operator== (const matrix4x4& m1, const matrix4x4& m2) {
for (int x=0;x<4;++x) for (int y=0;y<4;++y)
if (m1[x][y] != m2[x][y]) return false;
return true;
}
inline bool operator< (const matrix4x4& m1, const matrix4x4& m2) {
for (int x=0;x<4;++x) for (int y=0;y<4;++y)
if (m1[x][y] < m2[x][y]) return true;
else if (m1[x][y] > m2[x][y]) return false;
return false;
}
inline matrix4x4 operator* (const matrix4x4& m1, const matrix4x4& m2) {
matrix4x4 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;
}
inline matrix4x4 Transpose (const matrix4x4& m) {
matrix4x4 retVal;
for (int x=0;x<4;++x) for (int y=0;y<4;++y)
retVal(x)[y] = m[y][x];
return retVal;
}
inline matrix4x4& matrix4x4::Rotation (scalar_t angle, vector3 axis) {
scalar_t c = COSINE_FUNCTION(angle);
scalar_t s = SINE_FUNCTION(angle);
// One minus c (short name for legibility of formulai)
scalar_t omc = (1 - c);
if (LengthSquared3(axis) != 1) axis = Normalize(axis);
scalar_t x = axis.x;
scalar_t y = axis.y;
scalar_t z = axis.z;
scalar_t xs = x * s;
scalar_t ys = y * s;
scalar_t zs = z * s;
scalar_t xyomc = x * y * omc;
scalar_t xzomc = x * z * omc;
scalar_t 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 matrix4x4& matrix4x4::Translation(const vector3& translation) {
Identity();
e[12] = translation.x;
e[13] = translation.y;
e[14] = translation.z;
return *this;
}
inline matrix4x4& matrix4x4::Scale (scalar_t x, scalar_t y, scalar_t z) {
Identity();
e[0] = x;
e[5] = y;
e[10] = z;
return *this;
}
inline matrix4x4& matrix4x4::BasisChange (const vector3& u, const vector3& v, const vector3& n) {
e[0] = u.x;
e[1] = v.x;
e[2] = n.x;
e[3] = 0;
e[4] = u.y;
e[5] = v.y;
e[6] = n.y;
e[7] = 0;
e[8] = u.z;
e[9] = v.z;
e[10] = n.z;
e[11] = 0;
e[12] = 0;
e[13] = 0;
e[14] = 0;
e[15] = 1;
return *this;
}
inline matrix4x4& matrix4x4::BasisChange (const vector3& v, const vector3& n) {
vector3 u = CrossProduct(v,n);
return BasisChange (u, v, n);
}
inline matrix4x4& matrix4x4::ProjectionMatrix (bool perspective, scalar_t left_plane, scalar_t right_plane,
scalar_t top_plane, scalar_t bottom_plane,
scalar_t near_plane, scalar_t far_plane)
inline bool operator<(const matrix4x4 &m1, const matrix4x4 &m2)
{
scalar_t A = (right_plane + left_plane) / (right_plane - left_plane);
scalar_t B = (top_plane + bottom_plane) / (top_plane - bottom_plane);
scalar_t C = (far_plane + near_plane) / (far_plane - near_plane);
Identity();
if (perspective) {
e[0] = 2 * near_plane / (right_plane - left_plane);
e[5] = 2 * near_plane / (top_plane - bottom_plane);
e[8] = A;
e[9] = B;
e[10] = C;
e[11] = -1;
e[14] = 2 * far_plane * near_plane / (far_plane - near_plane);
} else {
e[0] = 2 / (right_plane - left_plane);
e[5] = 2 / (top_plane - bottom_plane);
e[10] = -2 / (far_plane - near_plane);
e[12] = A;
e[13] = B;
e[14] = C;
}
return *this;
for (int x = 0; x < 4; ++x)
for (int y = 0; y < 4; ++y)
if (m1[x][y] < m2[x][y])
return true;
else if (m1[x][y] > m2[x][y])
return false;
return false;
}
double inline __fastcall SquareMagnitude(const vector3& v)
inline matrix4x4 operator*(const matrix4x4 &m1, const matrix4x4 &m2)
{
return v.x*v.x+v.y*v.y+v.z*v.z;
matrix4x4 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;
}
inline matrix4x4 Transpose(const matrix4x4 &m)
{
matrix4x4 retVal;
for (int x = 0; x < 4; ++x)
for (int y = 0; y < 4; ++y)
retVal(x)[y] = m[y][x];
return retVal;
}
inline matrix4x4 &matrix4x4::Rotation(scalar_t angle, vector3 axis)
{
scalar_t c = COSINE_FUNCTION(angle);
scalar_t s = SINE_FUNCTION(angle);
// One minus c (short name for legibility of formulai)
scalar_t omc = (1 - c);
if (LengthSquared3(axis) != 1)
axis = Normalize(axis);
scalar_t x = axis.x;
scalar_t y = axis.y;
scalar_t z = axis.z;
scalar_t xs = x * s;
scalar_t ys = y * s;
scalar_t zs = z * s;
scalar_t xyomc = x * y * omc;
scalar_t xzomc = x * z * omc;
scalar_t 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 matrix4x4 &matrix4x4::Translation(const vector3 &translation)
{
Identity();
e[12] = translation.x;
e[13] = translation.y;
e[14] = translation.z;
return *this;
}
inline matrix4x4 &matrix4x4::Scale(scalar_t x, scalar_t y, scalar_t z)
{
Identity();
e[0] = x;
e[5] = y;
e[10] = z;
return *this;
}
inline matrix4x4 &matrix4x4::BasisChange(const vector3 &u, const vector3 &v, const vector3 &n)
{
e[0] = u.x;
e[1] = v.x;
e[2] = n.x;
e[3] = 0;
e[4] = u.y;
e[5] = v.y;
e[6] = n.y;
e[7] = 0;
e[8] = u.z;
e[9] = v.z;
e[10] = n.z;
e[11] = 0;
e[12] = 0;
e[13] = 0;
e[14] = 0;
e[15] = 1;
return *this;
}
inline matrix4x4 &matrix4x4::BasisChange(const vector3 &v, const vector3 &n)
{
vector3 u = CrossProduct(v, n);
return BasisChange(u, v, n);
}
inline matrix4x4 &matrix4x4::ProjectionMatrix(bool perspective, scalar_t left_plane,
scalar_t right_plane, scalar_t top_plane,
scalar_t bottom_plane, scalar_t near_plane,
scalar_t far_plane)
{
scalar_t A = (right_plane + left_plane) / (right_plane - left_plane);
scalar_t B = (top_plane + bottom_plane) / (top_plane - bottom_plane);
scalar_t C = (far_plane + near_plane) / (far_plane - near_plane);
Identity();
if (perspective)
{
e[0] = 2 * near_plane / (right_plane - left_plane);
e[5] = 2 * near_plane / (top_plane - bottom_plane);
e[8] = A;
e[9] = B;
e[10] = C;
e[11] = -1;
e[14] = 2 * far_plane * near_plane / (far_plane - near_plane);
}
else
{
e[0] = 2 / (right_plane - left_plane);
e[5] = 2 / (top_plane - bottom_plane);
e[10] = -2 / (far_plane - near_plane);
e[12] = A;
e[13] = B;
e[14] = C;
}
return *this;
}
double inline __fastcall SquareMagnitude(const vector3 &v)
{
return v.x * v.x + v.y * v.y + v.z * v.z;
}
} // close namespace
@@ -454,22 +546,25 @@ double inline __fastcall SquareMagnitude(const vector3& v)
#ifdef OSTREAM_MATH3D
#include <ostream>
// Streaming support
std::ostream& operator<< (std::ostream& os, const Math3D::vector3& v) {
os << '[';
for (int i=0; i<4; ++i)
os << ' ' << v[i];
return os << ']';
std::ostream &operator<<(std::ostream &os, const Math3D::vector3 &v)
{
os << '[';
for (int i = 0; i < 4; ++i)
os << ' ' << v[i];
return os << ']';
}
std::ostream& operator<< (std::ostream& os, const Math3D::matrix4x4& m) {
for (int y=0; y<4; ++y) {
os << '[';
for (int x=0;x<4;++x)
os << ' ' << m[x][y];
os << " ]" << std::endl;
}
return os;
std::ostream &operator<<(std::ostream &os, const Math3D::matrix4x4 &m)
{
for (int y = 0; y < 4; ++y)
{
os << '[';
for (int x = 0; x < 4; ++x)
os << ' ' << m[x][y];
os << " ]" << std::endl;
}
return os;
}
#endif // OSTREAM_MATH3D
#endif // OSTREAM_MATH3D
#endif

View File

@@ -4,113 +4,97 @@
#include "Geometry.h"
inline double __fastcall sqr(double a) { return ( a*a ); };
inline double __fastcall sqr(double a) { return (a * a); };
__fastcall TLine::TLine()
{
};
__fastcall TLine::TLine(){};
__fastcall TLine::TLine(vector3 NPoint, vector3 NVector)
{
Vector= NVector; Point= NPoint;
Vector = NVector;
Point = NPoint;
};
__fastcall TLine::~TLine()
{
};
__fastcall TLine::~TLine(){};
TPlane __fastcall TLine::GetPlane()
{
return(TPlane(Point,Vector));
};
TPlane __fastcall TLine::GetPlane() { return (TPlane(Point, Vector)); };
double __fastcall TLine::GetDistance(vector3 Point1)
{
return ( (sqr((Point1.x-Point.x)*Vector.x-(Point1.y-Point.y)*Vector.y)-
sqr((Point1.y-Point.y)*Vector.y-(Point1.z-Point.z)*Vector.z)-
sqr((Point1.z-Point.z)*Vector.z-(Point1.x-Point.x)*Vector.x))/
(sqr(Vector.x)+sqr(Vector.y)+sqr(Vector.z)) );
return ((sqr((Point1.x - Point.x) * Vector.x - (Point1.y - Point.y) * Vector.y) -
sqr((Point1.y - Point.y) * Vector.y - (Point1.z - Point.z) * Vector.z) -
sqr((Point1.z - Point.z) * Vector.z - (Point1.x - Point.x) * Vector.x)) /
(sqr(Vector.x) + sqr(Vector.y) + sqr(Vector.z)));
;
};
//---------------------------------------------------------------------------
__fastcall TPlane::TPlane()
{
Vector= vector3(0,0,0);
d= 0;
Vector = vector3(0, 0, 0);
d = 0;
};
__fastcall TPlane::TPlane(vector3 NVector, double nd)
{
Vector= NVector; d= nd;
Vector = NVector;
d = nd;
}
__fastcall TPlane::TPlane(vector3 Point, vector3 NVector)
{
Vector= NVector; d= -NVector.x*Point.x-NVector.y*Point.y-NVector.z*Point.z;
Vector = NVector;
d = -NVector.x * Point.x - NVector.y * Point.y - NVector.z * Point.z;
};
__fastcall TPlane::TPlane(vector3 Point1, vector3 Vector1, vector3 Vector2)
__fastcall TPlane::TPlane(vector3 Point1, vector3 Vector1, vector3 Vector2)
{
Vector= CrossProduct(Vector1,Vector2); d= -Vector.x*Point1.x-Vector.y*Point1.y-Vector.z*Point1.z;
Vector = CrossProduct(Vector1, Vector2);
d = -Vector.x * Point1.x - Vector.y * Point1.y - Vector.z * Point1.z;
};
__fastcall TPlane::~TPlane()
{
};
__fastcall TPlane::~TPlane(){};
void __fastcall TPlane::Normalize()
{
double mgn= Vector.Length();
Vector= Vector/mgn; d/= mgn;
double mgn = Vector.Length();
Vector = Vector / mgn;
d /= mgn;
};
double __fastcall TPlane::GetSide(vector3 Point)
{
return (Vector.x*Point.x+Vector.y*Point.y+Vector.z*Point.z+d);
return (Vector.x * Point.x + Vector.y * Point.y + Vector.z * Point.z + d);
};
//void __fastcall TPlane::Transform(D3DMATRIX &Transformations)
// void __fastcall TPlane::Transform(D3DMATRIX &Transformations)
//{
// vector3 src= Vector;
// D3DMath_VectorMatrixMultiply(Vector,src,Transformations);
//};
bool __fastcall TPlane::Defined()
{
return !(Vector==vector3(0,0,0));
};
bool __fastcall TPlane::Defined() { return !(Vector == vector3(0, 0, 0)); };
//---------------------------------------------------------------------------
inline double __fastcall Sum(vector3 &Vector)
{
return( Vector.x+Vector.y+Vector.z );
};
inline double __fastcall Sum(vector3 &Vector) { return (Vector.x + Vector.y + Vector.z); };
bool __fastcall CrossPoint(vector3 &RetPoint, TLine &Line, TPlane &Plane)
{
double ro= DotProduct(Plane.Vector,Line.Vector);
if (ro==0)
return( false );
ro= (DotProduct(Plane.Vector,Line.Point)+Plane.d)/ro;
RetPoint= Line.Point-(Line.Vector*ro);
return( true );
double ro = DotProduct(Plane.Vector, Line.Vector);
if (ro == 0)
return (false);
ro = (DotProduct(Plane.Vector, Line.Point) + Plane.d) / ro;
RetPoint = Line.Point - (Line.Vector * ro);
return (true);
};
inline double __fastcall GetLength(vector3& Vector)
{
return ( Vector.Length() );
};
inline double __fastcall GetLength(vector3 &Vector) { return (Vector.Length()); };
inline vector3 __fastcall SetLength(vector3& Vector, double Length)
inline vector3 __fastcall SetLength(vector3 &Vector, double Length)
{
Vector.Normalize();
return ( Vector*Length );
return (Vector * Length);
};
//---------------------------------------------------------------------------
//#pragma package(smart_init)

View File

@@ -11,7 +11,7 @@ class TPlane;
class TLine
{
public:
public:
vector3 Vector, Point;
__fastcall TLine();
__fastcall TLine(vector3 NPoint, vector3 NVector);
@@ -24,17 +24,17 @@ public:
class TPlane
{
public:
public:
vector3 Vector;
double d;
__fastcall TPlane();
__fastcall TPlane(vector3 NVector, double nd);
__fastcall TPlane(vector3 NPoint, vector3 NVector);
__fastcall TPlane(vector3 Point1, vector3 Vector1, vector3 Vector2);
__fastcall TPlane(vector3 Point1, vector3 Vector1, vector3 Vector2);
__fastcall ~TPlane();
void __fastcall Normalize();
double __fastcall GetSide(vector3 Point);
// void __fastcall Transform(D3DMATRIX &Transformations);
// void __fastcall Transform(D3DMATRIX &Transformations);
bool __fastcall Defined();
};

View File

@@ -10,185 +10,192 @@
*/
/////////////////////////////////////////////////////////////////////////////////////////////////////
// cParser -- generic class for parsing text data.
// constructors
cParser::cParser(std::string Stream,buffertype Type,std::string Path,bool tr)
cParser::cParser(std::string Stream, buffertype Type, std::string Path, bool tr)
{
LoadTraction=tr;
// build comments map
mComments.insert(commentmap::value_type("/*","*/"));
mComments.insert(commentmap::value_type("//","\n"));
//mComments.insert(commentmap::value_type("--","\n")); //Ra: to chyba nie u¿ywane
// store to calculate sub-sequent includes from relative path
mPath=Path;
// reset pointers and attach proper type of buffer
switch (Type)
{
case buffer_FILE:
Path.append(Stream);
mStream=new std::ifstream(Path.c_str());
break;
case buffer_TEXT:
mStream=new std::istringstream(Stream);
break;
default:
mStream=NULL;
}
mIncludeParser=NULL;
// calculate stream size
if (mStream)
{
mSize=mStream->rdbuf()->pubseekoff(0,std::ios_base::end);
mStream->rdbuf()->pubseekoff(0,std::ios_base::beg);
}
else
mSize=0;
LoadTraction = tr;
// build comments map
mComments.insert(commentmap::value_type("/*", "*/"));
mComments.insert(commentmap::value_type("//", "\n"));
// mComments.insert(commentmap::value_type("--","\n")); //Ra: to chyba nie u¿ywane
// store to calculate sub-sequent includes from relative path
mPath = Path;
// reset pointers and attach proper type of buffer
switch (Type)
{
case buffer_FILE:
Path.append(Stream);
mStream = new std::ifstream(Path.c_str());
break;
case buffer_TEXT:
mStream = new std::istringstream(Stream);
break;
default:
mStream = NULL;
}
mIncludeParser = NULL;
// calculate stream size
if (mStream)
{
mSize = mStream->rdbuf()->pubseekoff(0, std::ios_base::end);
mStream->rdbuf()->pubseekoff(0, std::ios_base::beg);
}
else
mSize = 0;
}
// destructor
cParser::~cParser()
{
if (mIncludeParser) delete mIncludeParser;
if (mStream) delete mStream;
mComments.clear();
if (mIncludeParser)
delete mIncludeParser;
if (mStream)
delete mStream;
mComments.clear();
}
// methods
bool cParser::getTokens(int Count,bool ToLower,const char* Break)
bool cParser::getTokens(int Count, bool ToLower, const char *Break)
{
/*
if (LoadTraction==true)
trtest="niemaproblema"; //wczytywaæ
else
trtest="x"; //nie wczytywaæ
*/
int i;
this->str("");
this->clear();
for (i=0;i<Count;++i)
{
std::string string=readToken(ToLower,Break);
// collect parameters
if (i==0)
this->str(string);
else
{
std::string temp=this->str();
temp.append("\n");
temp.append(string);
this->str(temp);
}
}
if (i<Count)
return false;
else
return true;
/*
if (LoadTraction==true)
trtest="niemaproblema"; //wczytywaæ
else
trtest="x"; //nie wczytywaæ
*/
int i;
this->str("");
this->clear();
for (i = 0; i < Count; ++i)
{
std::string string = readToken(ToLower, Break);
// collect parameters
if (i == 0)
this->str(string);
else
{
std::string temp = this->str();
temp.append("\n");
temp.append(string);
this->str(temp);
}
}
if (i < Count)
return false;
else
return true;
}
std::string cParser::readToken(bool ToLower,const char* Break)
std::string cParser::readToken(bool ToLower, const char *Break)
{
std::string token="";
size_t pos; //pocz¹tek podmienianego ci¹gu
// see if there's include parsing going on. clean up when it's done.
if (mIncludeParser)
{
token=(*mIncludeParser).readToken(ToLower,Break);
if (!token.empty())
{pos=token.find("(p");
// check if the token is a parameter which should be replaced with stored true value
if (pos!=std::string::npos) //!=npos to znalezione
{
std::string parameter=token.substr(pos+2,token.find(")",pos)-pos+2); //numer parametru
token.erase(pos,token.find(")",pos)-pos+1); //najpierw usuniêcie "(pN)"
size_t nr=atoi(parameter.c_str())-1;
if (nr<parameters.size())
{token.insert(pos,parameters.at(nr)); //wklejenie wartoœci parametru
if (ToLower)
for (;pos<token.length();++pos)
token[pos]=tolower(token[pos]);
std::string token = "";
size_t pos; // pocz¹tek podmienianego ci¹gu
// see if there's include parsing going on. clean up when it's done.
if (mIncludeParser)
{
token = (*mIncludeParser).readToken(ToLower, Break);
if (!token.empty())
{
pos = token.find("(p");
// check if the token is a parameter which should be replaced with stored true value
if (pos != std::string::npos) //!=npos to znalezione
{
std::string parameter =
token.substr(pos + 2, token.find(")", pos) - pos + 2); // numer parametru
token.erase(pos, token.find(")", pos) - pos + 1); // najpierw usuniêcie "(pN)"
size_t nr = atoi(parameter.c_str()) - 1;
if (nr < parameters.size())
{
token.insert(pos, parameters.at(nr)); // wklejenie wartoœci parametru
if (ToLower)
for (; pos < token.length(); ++pos)
token[pos] = tolower(token[pos]);
}
else
token.insert(pos, "none"); // zabezpieczenie przed brakiem parametru
}
return token;
}
else
{
delete mIncludeParser;
mIncludeParser = NULL;
parameters.clear();
}
}
else
token.insert(pos,"none"); //zabezpieczenie przed brakiem parametru
}
return token;
}
else
{delete mIncludeParser;
mIncludeParser=NULL;
parameters.clear();
}
}
// get the token yourself if there's no child to delegate it to.
char c;
do
{while (mStream->peek()!=EOF&& strchr( Break, c = mStream->get() ) == NULL)
{
if (ToLower) c=tolower(c);
token+=c;
if (trimComments(token)) // don't glue together words separated with comment
break;
}
} while (token=="" && mStream->peek()!=EOF); // double check to deal with trailing spaces
// launch child parser if include directive found.
// NOTE: parameter collecting uses default set of token separators.
if (token.compare("include")==0)
{//obs³uga include
std::string includefile=readToken(ToLower); //nazwa pliku
if (LoadTraction?true:((includefile.find("tr/")==std::string::npos)&&(includefile.find("tra/")==std::string::npos)))
{
//std::string trtest2="niemaproblema"; //nazwa odporna na znalezienie "tr/"
//if (trtest=="x") //jeœli nie wczytywaæ drutów
//trtest2=includefile; //kopiowanie œcie¿ki do pliku
std::string parameter=readToken(false); //w parametrach nie zmniejszamy
while (parameter.compare("end")!=0)
{
parameters.push_back(parameter);
parameter=readToken(ToLower);
}
//if (trtest2.find("tr/")!=0)
mIncludeParser=new cParser(includefile,buffer_FILE,mPath,LoadTraction);
if (mIncludeParser->mSize<=0)
ErrorLog("Missed include: "+AnsiString(includefile.c_str()));
}
else
while (token.compare("end")!=0)
token=readToken(ToLower);
token=readToken(ToLower,Break);
}
return token;
// get the token yourself if there's no child to delegate it to.
char c;
do
{
while (mStream->peek() != EOF && strchr(Break, c = mStream->get()) == NULL)
{
if (ToLower)
c = tolower(c);
token += c;
if (trimComments(token)) // don't glue together words separated with comment
break;
}
} while (token == "" && mStream->peek() != EOF); // double check to deal with trailing spaces
// launch child parser if include directive found.
// NOTE: parameter collecting uses default set of token separators.
if (token.compare("include") == 0)
{ // obs³uga include
std::string includefile = readToken(ToLower); // nazwa pliku
if (LoadTraction ? true : ((includefile.find("tr/") == std::string::npos) &&
(includefile.find("tra/") == std::string::npos)))
{
// std::string trtest2="niemaproblema"; //nazwa odporna na znalezienie "tr/"
// if (trtest=="x") //jeœli nie wczytywaæ drutów
// trtest2=includefile; //kopiowanie œcie¿ki do pliku
std::string parameter = readToken(false); // w parametrach nie zmniejszamy
while (parameter.compare("end") != 0)
{
parameters.push_back(parameter);
parameter = readToken(ToLower);
}
// if (trtest2.find("tr/")!=0)
mIncludeParser = new cParser(includefile, buffer_FILE, mPath, LoadTraction);
if (mIncludeParser->mSize <= 0)
ErrorLog("Missed include: " + AnsiString(includefile.c_str()));
}
else
while (token.compare("end") != 0)
token = readToken(ToLower);
token = readToken(ToLower, Break);
}
return token;
}
bool cParser::trimComments(std::string &String)
{
for (commentmap::iterator cmIt=mComments.begin();cmIt!=mComments.end();++cmIt)
{
if (String.find((*cmIt).first)!=std::string::npos)
{
readComment((*cmIt).second);
String.resize(String.find((*cmIt).first));
return true;
}
}
return false;
for (commentmap::iterator cmIt = mComments.begin(); cmIt != mComments.end(); ++cmIt)
{
if (String.find((*cmIt).first) != std::string::npos)
{
readComment((*cmIt).second);
String.resize(String.find((*cmIt).first));
return true;
}
}
return false;
}
std::string cParser::readComment(const std::string Break)
{//pobieranie znaków a¿ do znalezienia znacznika koñca
std::string token="";
while (mStream->peek()!=EOF)
{//o ile nie koniec pliku
token+=mStream->get(); //pobranie znaku
if (token.find(Break)!=std::string::npos) //szukanie znacznika koñca
break;
}
return token;
{ // pobieranie znaków a¿ do znalezienia znacznika koñca
std::string token = "";
while (mStream->peek() != EOF)
{ // o ile nie koniec pliku
token += mStream->get(); // pobranie znaku
if (token.find(Break) != std::string::npos) // szukanie znacznika koñca
break;
}
return token;
}
int cParser::getProgress() const
{
return mStream->rdbuf()->pubseekoff( 0, std::ios_base::cur ) * 100 / mSize;
return mStream->rdbuf()->pubseekoff(0, std::ios_base::cur) * 100 / mSize;
}

View File

@@ -2,7 +2,7 @@
#if !defined(rainKERNELTEXTPARSER_H_INCLUDED)
#define rainKERNELTEXTPARSER_H_INCLUDED
#pragma warning ( disable : 4786 ) // 'containers too long for debug' warning
#pragma warning(disable : 4786) // 'containers too long for debug' warning
#include <string>
#include <sstream>
@@ -16,40 +16,52 @@
class cParser : public std::stringstream
{
public:
//parameters:
enum buffertype {buffer_FILE,buffer_TEXT};
//constructors:
cParser(std::string Stream,buffertype Type=buffer_TEXT,std::string Path="",bool tr=true);
//destructor:
virtual ~cParser();
//methods:
template <typename OutputT>
inline void getToken(OutputT& output) {getTokens(); *this >> output;};
inline void ignoreToken() {readToken();};
inline void ignoreTokens(int count) {for (int i=0;i<count;i++) readToken();};
inline bool expectToken(std::string value) {return readToken()==value;};
bool eof() {return mStream->eof();};
bool ok() {return !mStream->fail();};
bool getTokens(int Count=1,bool ToLower=true,const char* Break="\n\t ;");
int getProgress() const; // percentage of file processed.
//load traction?
bool LoadTraction;
protected:
// methods:
std::string readToken(bool ToLower=true,const char* Break="\n\t ;");
std::string readComment(const std::string Break="\n\t ;");
std::string trtest;
bool trimComments(std::string& String);
// members:
std::istream *mStream; // relevant kind of buffer is attached on creation.
std::string mPath; // path to open stream, for relative path lookups.
int mSize; // size of open stream, for progress report.
typedef std::map<std::string,std::string> commentmap;
commentmap mComments;
cParser *mIncludeParser; // child class to handle include directives.
std::vector<std::string> parameters; // parameter list for included file.
public:
// parameters:
enum buffertype
{
buffer_FILE,
buffer_TEXT
};
// constructors:
cParser(std::string Stream, buffertype Type = buffer_TEXT, std::string Path = "",
bool tr = true);
// destructor:
virtual ~cParser();
// methods:
template <typename OutputT> inline void getToken(OutputT &output)
{
getTokens();
*this >> output;
};
inline void ignoreToken() { readToken(); };
inline void ignoreTokens(int count)
{
for (int i = 0; i < count; i++)
readToken();
};
inline bool expectToken(std::string value) { return readToken() == value; };
bool eof() { return mStream->eof(); };
bool ok() { return !mStream->fail(); };
bool getTokens(int Count = 1, bool ToLower = true, const char *Break = "\n\t ;");
int getProgress() const; // percentage of file processed.
// load traction?
bool LoadTraction;
protected:
// methods:
std::string readToken(bool ToLower = true, const char *Break = "\n\t ;");
std::string readComment(const std::string Break = "\n\t ;");
std::string trtest;
bool trimComments(std::string &String);
// members:
std::istream *mStream; // relevant kind of buffer is attached on creation.
std::string mPath; // path to open stream, for relative path lookups.
int mSize; // size of open stream, for progress report.
typedef std::map<std::string, std::string> commentmap;
commentmap mComments;
cParser *mIncludeParser; // child class to handle include directives.
std::vector<std::string> parameters; // parameter list for included file.
};
#endif // ..!defined(rainKERNELTEXTPARSER_H_INCLUDED)

79
sky.cpp
View File

@@ -1,65 +1,58 @@
//---------------------------------------------------------------------------
#include "system.hpp"
#include "classes.hpp"
#include "system.hpp"
#include "classes.hpp"
#pragma hdrstop
#include "sky.h"
#include "Globals.h"
//---------------------------------------------------------------------------
GLfloat lightPos[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
GLfloat lightPos[4] = {0.0f, 0.0f, 0.0f, 1.0f};
__fastcall TSky::~TSky()
{
};
__fastcall TSky::TSky()
{
};
__fastcall TSky::~TSky(){};
__fastcall TSky::TSky(){};
void __fastcall TSky::Init()
{
WriteLog(Global::asSky.c_str());
WriteLog("init");
AnsiString asModel;
asModel=Global::asSky;
if ((asModel!="1") && (asModel!="0"))
// {
mdCloud=TModelsManager::GetModel(asModel.c_str());
// }
WriteLog(Global::asSky.c_str());
WriteLog("init");
AnsiString asModel;
asModel = Global::asSky;
if ((asModel != "1") && (asModel != "0"))
// {
mdCloud = TModelsManager::GetModel(asModel.c_str());
// }
};
void __fastcall TSky::Render()
{
if (mdCloud)
{//jeœli jest model nieba
glPushMatrix();
//glDisable(GL_DEPTH_TEST);
glTranslatef(Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
if (Global::bUseVBO)
{//renderowanie z VBO
mdCloud->RaRender(100,0);
mdCloud->RaRenderAlpha(100,0);
}
else
{//renderowanie z Display List
mdCloud->Render(100,0);
mdCloud->RenderAlpha(100,0);
}
//glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
//glEnable(GL_LIGHTING);
glPopMatrix();
glLightfv(GL_LIGHT0,GL_POSITION,Global::lightPos);
}
if (mdCloud)
{ // jeœli jest model nieba
glPushMatrix();
// glDisable(GL_DEPTH_TEST);
glTranslatef(Global::pCameraPosition.x, Global::pCameraPosition.y,
Global::pCameraPosition.z);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
if (Global::bUseVBO)
{ // renderowanie z VBO
mdCloud->RaRender(100, 0);
mdCloud->RaRenderAlpha(100, 0);
}
else
{ // renderowanie z Display List
mdCloud->Render(100, 0);
mdCloud->RenderAlpha(100, 0);
}
// glEnable(GL_DEPTH_TEST);
glClear(GL_DEPTH_BUFFER_BIT);
// glEnable(GL_LIGHTING);
glPopMatrix();
glLightfv(GL_LIGHT0, GL_POSITION, Global::lightPos);
}
};
//---------------------------------------------------------------------------
#pragma package(smart_init)

15
sky.h
View File

@@ -7,13 +7,14 @@
class TSky
{
private:
TModel3d *mdCloud;
public:
__fastcall TSky();
__fastcall ~TSky();
void __fastcall Init();
void __fastcall Render();
private:
TModel3d *mdCloud;
public:
__fastcall TSky();
__fastcall ~TSky();
void __fastcall Init();
void __fastcall Render();
};
//---------------------------------------------------------------------------

View File

@@ -9,21 +9,35 @@
//#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))
//Ra: to jest mocno nieoptymalne: 10+3*4=22 mno¿enia, 6 odejmowañ, 3*3=9 dodawañ
//Ra: po przeliczeniu wspó³czynników mamy: 3*3=9 mno¿eñ i 3*3=9 dodawañ
// Ra: to jest mocno nieoptymalne: 10+3*4=22 mno¿enia, 6 odejmowañ, 3*3=9 dodawañ
// Ra: po przeliczeniu wspó³czynników mamy: 3*3=9 mno¿eñ i 3*3=9 dodawañ
//#define Interpolate(t,p1,cp1,cp2,p2) (B4(t)*p1+B3(t)*cp1+B2(t)*cp2+B1(t)*p2)
//Ra: "delete NULL" nic nie zrobi, wiêc "if (a!=NULL)" jest zbêdne
// Ra: "delete NULL" nic nie zrobi, wiêc "if (a!=NULL)" jest zbêdne
//#define SafeFree(a) if (a!=NULL) free(a)
#define SafeDelete(a) { delete (a); a=NULL; }
#define SafeDeleteArray(a) { delete[] (a); a=NULL; }
#define SafeDelete(a) \
{ \
delete (a); \
a = NULL; \
}
#define SafeDeleteArray(a) \
{ \
delete[](a); \
a = NULL; \
}
#define sign(x) ((x)<0?-1:((x)>0?1:0))
#define sign(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0))
#define DegToRad(a) ((M_PI/180.0)*(a)) //(a) w nawiasie, bo mo¿e byæ dodawaniem
#define RadToDeg(r) ((180.0/M_PI)*(r))
#define DegToRad(a) ((M_PI / 180.0) * (a)) //(a) w nawiasie, bo mo¿e byæ dodawaniem
#define RadToDeg(r) ((180.0 / M_PI) * (r))
#define Fix(a,b,c) {if (a<b) a=b; if (a>c) a=c;}
#define Fix(a, b, c) \
{ \
if (a < b) \
a = b; \
if (a > c) \
a = c; \
}
#define asModelsPath AnsiString("models\\")
#define asSceneryPath AnsiString("scenery\\")
@@ -33,12 +47,8 @@
#define szTexturePath "textures\\"
//#define szDefaultTextureExt ".dds"
//#define DevelopTime //FIXME
//#define EditorMode
//---------------------------------------------------------------------------
#endif

View File

@@ -9,80 +9,86 @@
#include <windows.h>
#include "WavRead.h"
//-----------------------------------------------------------------------------
// Defines, constants, and global variables
//-----------------------------------------------------------------------------
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#define SAFE_DELETE(p) \
{ \
if (p) \
{ \
delete (p); \
(p) = NULL; \
} \
}
#define SAFE_RELEASE(p) \
{ \
if (p) \
{ \
(p)->Release(); \
(p) = NULL; \
} \
}
//-----------------------------------------------------------------------------
// Name: ReadMMIO()
// Desc: Support function for reading from a multimedia I/O stream
//-----------------------------------------------------------------------------
HRESULT ReadMMIO( HMMIO hmmioIn, MMCKINFO* pckInRIFF, WAVEFORMATEX** ppwfxInfo )
HRESULT ReadMMIO(HMMIO hmmioIn, MMCKINFO *pckInRIFF, WAVEFORMATEX **ppwfxInfo)
{
MMCKINFO ckIn; // chunk info. for general use.
PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in.
MMCKINFO ckIn; // chunk info. for general use.
PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in.
*ppwfxInfo = NULL;
if( ( 0 != mmioDescend( hmmioIn, pckInRIFF, NULL, 0 ) ) )
if ((0 != mmioDescend(hmmioIn, pckInRIFF, NULL, 0)))
return E_FAIL;
if( (pckInRIFF->ckid != FOURCC_RIFF) ||
(pckInRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E') ) )
if ((pckInRIFF->ckid != FOURCC_RIFF) || (pckInRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E')))
return E_FAIL;
// Search the input file for for the 'fmt ' chunk.
ckIn.ckid = mmioFOURCC('f', 'm', 't', ' ');
if( 0 != mmioDescend(hmmioIn, &ckIn, pckInRIFF, MMIO_FINDCHUNK) )
if (0 != mmioDescend(hmmioIn, &ckIn, pckInRIFF, MMIO_FINDCHUNK))
return E_FAIL;
// Expect the 'fmt' chunk to be at least as large as <PCMWAVEFORMAT>;
// if there are extra parameters at the end, we'll ignore them
if( ckIn.cksize < (LONG) sizeof(PCMWAVEFORMAT) )
return E_FAIL;
if (ckIn.cksize < (LONG)sizeof(PCMWAVEFORMAT))
return E_FAIL;
// Read the 'fmt ' chunk into <pcmWaveFormat>.
if( mmioRead( hmmioIn, (HPSTR) &pcmWaveFormat,
sizeof(pcmWaveFormat)) != sizeof(pcmWaveFormat) )
if (mmioRead(hmmioIn, (HPSTR)&pcmWaveFormat, sizeof(pcmWaveFormat)) != sizeof(pcmWaveFormat))
return E_FAIL;
// Allocate the waveformatex, but if its not pcm format, read the next
// word, and thats how many extra bytes to allocate.
if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM )
if (pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM)
{
if( NULL == ( *ppwfxInfo = new WAVEFORMATEX ) )
if (NULL == (*ppwfxInfo = new WAVEFORMATEX))
return E_FAIL;
// Copy the bytes from the pcm structure to the waveformatex structure
memcpy( *ppwfxInfo, &pcmWaveFormat, sizeof(pcmWaveFormat) );
memcpy(*ppwfxInfo, &pcmWaveFormat, sizeof(pcmWaveFormat));
(*ppwfxInfo)->cbSize = 0;
}
else
{
// Read in length of extra bytes.
WORD cbExtraBytes = 0L;
if( mmioRead( hmmioIn, (CHAR*)&cbExtraBytes, sizeof(WORD)) != sizeof(WORD) )
if (mmioRead(hmmioIn, (CHAR *)&cbExtraBytes, sizeof(WORD)) != sizeof(WORD))
return E_FAIL;
*ppwfxInfo = (WAVEFORMATEX*)new CHAR[ sizeof(WAVEFORMATEX) + cbExtraBytes ];
if( NULL == *ppwfxInfo )
*ppwfxInfo = (WAVEFORMATEX *)new CHAR[sizeof(WAVEFORMATEX) + cbExtraBytes];
if (NULL == *ppwfxInfo)
return E_FAIL;
// Copy the bytes from the pcm structure to the waveformatex structure
memcpy( *ppwfxInfo, &pcmWaveFormat, sizeof(pcmWaveFormat) );
memcpy(*ppwfxInfo, &pcmWaveFormat, sizeof(pcmWaveFormat));
(*ppwfxInfo)->cbSize = cbExtraBytes;
// Now, read those extra bytes into the structure, if cbExtraAlloc != 0.
if( mmioRead( hmmioIn, (CHAR*)(((BYTE*)&((*ppwfxInfo)->cbSize))+sizeof(WORD)),
cbExtraBytes ) != cbExtraBytes )
if (mmioRead(hmmioIn, (CHAR *)(((BYTE *)&((*ppwfxInfo)->cbSize)) + sizeof(WORD)),
cbExtraBytes) != cbExtraBytes)
{
delete *ppwfxInfo;
*ppwfxInfo = NULL;
@@ -91,7 +97,7 @@ HRESULT ReadMMIO( HMMIO hmmioIn, MMCKINFO* pckInRIFF, WAVEFORMATEX** ppwfxInfo )
}
// Ascend the input file out of the 'fmt ' chunk.
if( 0 != mmioAscend( hmmioIn, &ckIn, 0 ) )
if (0 != mmioAscend(hmmioIn, &ckIn, 0))
{
delete *ppwfxInfo;
*ppwfxInfo = NULL;
@@ -101,27 +107,24 @@ HRESULT ReadMMIO( HMMIO hmmioIn, MMCKINFO* pckInRIFF, WAVEFORMATEX** ppwfxInfo )
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: WaveOpenFile()
// Desc: This function will open a wave input file and prepare it for reading,
// so the data can be easily read with WaveReadFile. Returns 0 if
// successful, the error code if not.
//-----------------------------------------------------------------------------
HRESULT WaveOpenFile( CHAR* strFileName, HMMIO* phmmioIn, WAVEFORMATEX** ppwfxInfo,
MMCKINFO* pckInRIFF )
HRESULT WaveOpenFile(CHAR *strFileName, HMMIO *phmmioIn, WAVEFORMATEX **ppwfxInfo,
MMCKINFO *pckInRIFF)
{
HRESULT hr;
HMMIO hmmioIn = NULL;
HMMIO hmmioIn = NULL;
if( NULL == ( hmmioIn = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF|MMIO_READ ) ) )
if (NULL == (hmmioIn = mmioOpen(strFileName, NULL, MMIO_ALLOCBUF | MMIO_READ)))
return E_FAIL;
if( FAILED( hr = ReadMMIO( hmmioIn, pckInRIFF, ppwfxInfo ) ) )
if (FAILED(hr = ReadMMIO(hmmioIn, pckInRIFF, ppwfxInfo)))
{
mmioClose( hmmioIn, 0 );
mmioClose(hmmioIn, 0);
return hr;
}
@@ -130,9 +133,6 @@ HRESULT WaveOpenFile( CHAR* strFileName, HMMIO* phmmioIn, WAVEFORMATEX** ppwfxIn
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: WaveStartDataRead()
// Desc: Routine has to be called before WaveReadFile as it searches for the
@@ -141,25 +141,20 @@ HRESULT WaveOpenFile( CHAR* strFileName, HMMIO* phmmioIn, WAVEFORMATEX** ppwfxIn
// moved to a separate routine so there was more control on the chunks
// that are before the data chunk, such as 'fact', etc...
//-----------------------------------------------------------------------------
HRESULT WaveStartDataRead( HMMIO* phmmioIn, MMCKINFO* pckIn,
MMCKINFO* pckInRIFF )
HRESULT WaveStartDataRead(HMMIO *phmmioIn, MMCKINFO *pckIn, MMCKINFO *pckInRIFF)
{
// Seek to the data
if( -1 == mmioSeek( *phmmioIn, pckInRIFF->dwDataOffset + sizeof(FOURCC),
SEEK_SET ) )
if (-1 == mmioSeek(*phmmioIn, pckInRIFF->dwDataOffset + sizeof(FOURCC), SEEK_SET))
return E_FAIL;
// Search the input file for for the 'data' chunk.
pckIn->ckid = mmioFOURCC('d', 'a', 't', 'a');
if( 0 != mmioDescend( *phmmioIn, pckIn, pckInRIFF, MMIO_FINDCHUNK ) )
if (0 != mmioDescend(*phmmioIn, pckIn, pckInRIFF, MMIO_FINDCHUNK))
return E_FAIL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: WaveReadFile()
// Desc: Reads wave data from the wave file. Make sure we're descended into
@@ -169,60 +164,50 @@ HRESULT WaveStartDataRead( HMMIO* phmmioIn, MMCKINFO* pckIn,
// pbDest - Destination buffer to put bytes.
// cbActualRead - # of bytes actually read.
//-----------------------------------------------------------------------------
HRESULT WaveReadFile( HMMIO hmmioIn, UINT cbRead, BYTE* pbDest,
MMCKINFO* pckIn, UINT* cbActualRead )
HRESULT WaveReadFile(HMMIO hmmioIn, UINT cbRead, BYTE *pbDest, MMCKINFO *pckIn, UINT *cbActualRead)
{
MMIOINFO mmioinfoIn; // current status of <hmmioIn>
MMIOINFO mmioinfoIn; // current status of <hmmioIn>
*cbActualRead = 0;
if( 0 != mmioGetInfo( hmmioIn, &mmioinfoIn, 0 ) )
if (0 != mmioGetInfo(hmmioIn, &mmioinfoIn, 0))
return E_FAIL;
UINT cbDataIn = cbRead;
if( cbDataIn > pckIn->cksize )
if (cbDataIn > pckIn->cksize)
cbDataIn = pckIn->cksize;
pckIn->cksize -= cbDataIn;
for( DWORD cT = 0; cT < cbDataIn; cT++ )
for (DWORD cT = 0; cT < cbDataIn; cT++)
{
// Copy the bytes from the io to the buffer.
if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
if (mmioinfoIn.pchNext == mmioinfoIn.pchEndRead)
{
if( 0 != mmioAdvance( hmmioIn, &mmioinfoIn, MMIO_READ ) )
if (0 != mmioAdvance(hmmioIn, &mmioinfoIn, MMIO_READ))
return E_FAIL;
if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
if (mmioinfoIn.pchNext == mmioinfoIn.pchEndRead)
return E_FAIL;
}
// Actual copy.
*((BYTE*)pbDest+cT) = *((BYTE*)mmioinfoIn.pchNext);
*((BYTE *)pbDest + cT) = *((BYTE *)mmioinfoIn.pchNext);
mmioinfoIn.pchNext++;
}
if( 0 != mmioSetInfo( hmmioIn, &mmioinfoIn, 0 ) )
if (0 != mmioSetInfo(hmmioIn, &mmioinfoIn, 0))
return E_FAIL;
*cbActualRead = cbDataIn;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CWaveSoundRead()
// Desc: Constructs the class
//-----------------------------------------------------------------------------
CWaveSoundRead::CWaveSoundRead()
{
m_pwfx = NULL;
}
CWaveSoundRead::CWaveSoundRead() { m_pwfx = NULL; }
//-----------------------------------------------------------------------------
// Name: ~CWaveSoundRead()
@@ -231,69 +216,51 @@ CWaveSoundRead::CWaveSoundRead()
CWaveSoundRead::~CWaveSoundRead()
{
Close();
SAFE_DELETE( m_pwfx );
SAFE_DELETE(m_pwfx);
}
//-----------------------------------------------------------------------------
// Name: Open()
// Desc: Opens a wave file for reading
//-----------------------------------------------------------------------------
HRESULT CWaveSoundRead::Open( CHAR* strFilename )
HRESULT CWaveSoundRead::Open(CHAR *strFilename)
{
SAFE_DELETE( m_pwfx );
SAFE_DELETE(m_pwfx);
HRESULT hr;
HRESULT hr;
if( FAILED( hr = WaveOpenFile( strFilename, &m_hmmioIn, &m_pwfx, &m_ckInRiff ) ) )
if (FAILED(hr = WaveOpenFile(strFilename, &m_hmmioIn, &m_pwfx, &m_ckInRiff)))
return hr;
if( FAILED( hr = Reset() ) )
if (FAILED(hr = Reset()))
return hr;
return hr;
}
//-----------------------------------------------------------------------------
// Name: Reset()
// Desc: Resets the internal m_ckIn pointer so reading starts from the
// beginning of the file again
//-----------------------------------------------------------------------------
HRESULT CWaveSoundRead::Reset()
{
return WaveStartDataRead( &m_hmmioIn, &m_ckIn, &m_ckInRiff );
}
HRESULT CWaveSoundRead::Reset() { return WaveStartDataRead(&m_hmmioIn, &m_ckIn, &m_ckInRiff); }
//-----------------------------------------------------------------------------
// Name: Read()
// Desc: Reads a wave file into a pointer and returns how much read
// using m_ckIn to determine where to start reading from
//-----------------------------------------------------------------------------
HRESULT CWaveSoundRead::Read( UINT nSizeToRead, BYTE* pbData, UINT* pnSizeRead )
HRESULT CWaveSoundRead::Read(UINT nSizeToRead, BYTE *pbData, UINT *pnSizeRead)
{
return WaveReadFile( m_hmmioIn, nSizeToRead, pbData, &m_ckIn, pnSizeRead );
return WaveReadFile(m_hmmioIn, nSizeToRead, pbData, &m_ckIn, pnSizeRead);
}
//-----------------------------------------------------------------------------
// Name: Close()
// Desc: Closes an open wave file
//-----------------------------------------------------------------------------
HRESULT CWaveSoundRead::Close()
{
mmioClose( m_hmmioIn, 0 );
mmioClose(m_hmmioIn, 0);
return S_OK;
}

View File

@@ -9,17 +9,13 @@
#ifndef WAVE_READ_H
#define WAVE_READ_H
#include <mmreg.h>
#include <mmsystem.h>
HRESULT WaveOpenFile( CHAR* strFileName, HMMIO* phmmioIn, WAVEFORMATEX** ppwfxInfo,
MMCKINFO* pckInRIFF );
HRESULT WaveStartDataRead( HMMIO* phmmioIn, MMCKINFO* pckIn,
MMCKINFO* pckInRIFF );
HRESULT WaveReadFile( HMMIO hmmioIn, UINT cbRead, BYTE* pbDest,
MMCKINFO* pckIn, UINT* cbActualRead );
HRESULT WaveOpenFile(CHAR *strFileName, HMMIO *phmmioIn, WAVEFORMATEX **ppwfxInfo,
MMCKINFO *pckInRIFF);
HRESULT WaveStartDataRead(HMMIO *phmmioIn, MMCKINFO *pckIn, MMCKINFO *pckInRIFF);
HRESULT WaveReadFile(HMMIO hmmioIn, UINT cbRead, BYTE *pbDest, MMCKINFO *pckIn, UINT *cbActualRead);
//-----------------------------------------------------------------------------
// Name: class CWaveSoundRead
@@ -27,25 +23,20 @@ HRESULT WaveReadFile( HMMIO hmmioIn, UINT cbRead, BYTE* pbDest,
//-----------------------------------------------------------------------------
class CWaveSoundRead
{
public:
WAVEFORMATEX* m_pwfx; // Pointer to WAVEFORMATEX structure
HMMIO m_hmmioIn; // MM I/O handle for the WAVE
MMCKINFO m_ckIn; // Multimedia RIFF chunk
MMCKINFO m_ckInRiff; // Use in opening a WAVE file
public:
WAVEFORMATEX *m_pwfx; // Pointer to WAVEFORMATEX structure
HMMIO m_hmmioIn; // MM I/O handle for the WAVE
MMCKINFO m_ckIn; // Multimedia RIFF chunk
MMCKINFO m_ckInRiff; // Use in opening a WAVE file
public:
public:
CWaveSoundRead();
~CWaveSoundRead();
HRESULT Open( CHAR* strFilename );
HRESULT Open(CHAR *strFilename);
HRESULT Reset();
HRESULT Read( UINT nSizeToRead, BYTE* pbData, UINT* pnSizeRead );
HRESULT Read(UINT nSizeToRead, BYTE *pbData, UINT *pnSizeRead);
HRESULT Close();
};
#endif WAVE_READ_H