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

assorted bug fixes

This commit is contained in:
tmj-fstate
2017-01-23 11:06:34 +01:00
parent 538d130617
commit 77d462ffe4
13 changed files with 68 additions and 72 deletions

View File

@@ -1881,7 +1881,7 @@ bool TController::CheckVehicles(TOrders user)
{ // je<6A>li pojazd posiada pantograf, to przydzielamy mu mask<73>, kt<6B>r<EFBFBD> b<>dzie informowa<77> o { // je<6A>li pojazd posiada pantograf, to przydzielamy mu mask<73>, kt<6B>r<EFBFBD> b<>dzie informowa<77> o
// je<6A>dzie bezpr<70>dowej // je<6A>dzie bezpr<70>dowej
p->iOverheadMask = pantmask; p->iOverheadMask = pantmask;
pantmask << 1; // przesuni<6E>cie bit<69>w, max. 32 pojazdy z pantografami w sk<73>adzie pantmask = pantmask << 1; // przesuni<6E>cie bit<69>w, max. 32 pojazdy z pantografami w sk<73>adzie
} }
d = p->DirectionSet(d ? 1 : -1); // zwraca po<70>o<EFBFBD>enie nast<73>pnego (1=zgodny,0=odwr<77>cony - d = p->DirectionSet(d ? 1 : -1); // zwraca po<70>o<EFBFBD>enie nast<73>pnego (1=zgodny,0=odwr<77>cony -
// wzgl<67>dem czo<7A>a sk<73>adu) // wzgl<67>dem czo<7A>a sk<73>adu)
@@ -2310,7 +2310,7 @@ bool TController::PrepareEngine()
if (OK) if (OK)
{ {
if (eStopReason == stopSleep) // je<6A>li dotychczas spa<70> if (eStopReason == stopSleep) // je<6A>li dotychczas spa<70>
eStopReason == stopNone; // teraz nie ma powodu do stania eStopReason = stopNone; // teraz nie ma powodu do stania
iEngineActive = 1; iEngineActive = 1;
return true; return true;
} }

View File

@@ -2847,7 +2847,7 @@ bool TDynamicObject::Update(double dt, double dt1)
i = 0; i = 0;
przek = przek / (np - nPrzekrF); przek = przek / (np - nPrzekrF);
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p; for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
(kier > 0 ? p = p->NextC(4) : p = p->PrevC(4))) (true == kier ? p = p->NextC(4) : p = p->PrevC(4)))
{ {
if (!PrzekrF[i]) if (!PrzekrF[i])
{ {
@@ -2858,7 +2858,7 @@ bool TDynamicObject::Update(double dt, double dt1)
} }
i = 0; i = 0;
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p; for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
(kier > 0 ? p = p->NextC(4) : p = p->PrevC(4))) (true == kier ? p = p->NextC(4) : p = p->PrevC(4)))
{ {
float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] - float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
p->MoverParameters->BrakeCylSpring) * p->MoverParameters->BrakeCylSpring) *
@@ -4252,10 +4252,10 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
iMultiTex = 0; // czy jest wiele tekstur wymiennych? iMultiTex = 0; // czy jest wiele tekstur wymiennych?
parser.getTokens(); parser.getTokens();
parser >> asModel; parser >> asModel;
if (asModel.find('#') == asModel.length()) // Ra 2015-01: nie podoba mi się to if( asModel[asModel.size() - 1] == '#' ) // Ra 2015-01: nie podoba mi się to
{ // model wymaga wielu tekstur wymiennych { // model wymaga wielu tekstur wymiennych
iMultiTex = 1; iMultiTex = 1;
asModel = asModel.substr(0, asModel.length() - 1); asModel.erase( asModel.length() - 1 );
} }
if ((i = asModel.find(',')) != std::string::npos) if ((i = asModel.find(',')) != std::string::npos)
{ // Ra 2015-01: może szukać przecinka w { // Ra 2015-01: może szukać przecinka w
@@ -4273,6 +4273,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
// modele w dynamics/basedir // modele w dynamics/basedir
Global::asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/... Global::asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
mdModel = TModelsManager::GetModel(asModel, true); mdModel = TModelsManager::GetModel(asModel, true);
assert( mdModel != nullptr ); // TODO: handle this more gracefully than all going to shit
if (ReplacableSkin != "none") if (ReplacableSkin != "none")
{ // tekstura wymienna jest raczej jedynie w "dynamic\" { // tekstura wymienna jest raczej jedynie w "dynamic\"
ReplacableSkin = ReplacableSkin =

View File

@@ -572,7 +572,7 @@ int WINAPI WinMain(HINSTANCE hInstance, // instance
LPSTR lpCmdLine, // command line parameters LPSTR lpCmdLine, // command line parameters
int nCmdShow) // window show state int nCmdShow) // window show state
{ {
#ifdef _MSC_VER & _DEBUG #if defined(_MSC_VER) && defined (_DEBUG)
// memory leaks // memory leaks
_CrtSetDbgFlag( _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) | _CRTDBG_LEAK_CHECK_DF ); _CrtSetDbgFlag( _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ) | _CRTDBG_LEAK_CHECK_DF );
// floating point operation errors // floating point operation errors

View File

@@ -42,7 +42,6 @@ http://mozilla.org/MPL/2.0/.
#define _PROBLEND 1 #define _PROBLEND 1
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#pragma package(smart_init)
bool bCondition; // McZapkie: do testowania warunku na event multiple bool bCondition; // McZapkie: do testowania warunku na event multiple
string LogComment; string LogComment;
@@ -684,17 +683,6 @@ void TGroundNode::RenderAlphaDL()
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//------------------ Podstawowy pojemnik terenu - sektor ----------------------- //------------------ Podstawowy pojemnik terenu - sektor -----------------------
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
TSubRect::TSubRect()
{
nRootNode = NULL; // lista wszystkich obiektów jest pusta
nRenderHidden = nRenderRect = nRenderRectAlpha = nRender = nRenderMixed = nRenderAlpha =
nRenderWires = NULL;
tTrackAnim = NULL; // nic nie animujemy
tTracks = NULL; // nie ma jeszcze torów
nRootMesh = nMeshed = NULL; // te listy te¿ s¹ puste
iNodeCount = 0; // licznik obiektów
iTracks = 0; // licznik torów
}
TSubRect::~TSubRect() TSubRect::~TSubRect()
{ {
if (Global::bManageNodes) // Ra: tu siê coœ sypie if (Global::bManageNodes) // Ra: tu siê coœ sypie
@@ -2278,8 +2266,9 @@ void TGround::FirstInit()
for (j = 1; j < Current->iCount; ++j) for (j = 1; j < Current->iCount; ++j)
{ // od 1 do koñca s¹ zestawy trójk¹tów { // od 1 do koñca s¹ zestawy trójk¹tów
std::string xxxzzz = Current->nNode[j].smTerrain->pName; // pobranie nazwy std::string xxxzzz = Current->nNode[j].smTerrain->pName; // pobranie nazwy
gr = GetRect(1000 * (stol_def(xxxzzz.substr(0, 3),0) - 500), gr = GetRect(
1000 * (stol_def(xxxzzz.substr(3, 3),0) - 500)); ( std::stoi( xxxzzz.substr( 0, 3 )) - 500 ) * 1000,
( std::stoi( xxxzzz.substr( 3, 3 )) - 500 ) * 1000 );
if (Global::bUseVBO) if (Global::bUseVBO)
gr->nTerrain = Current->nNode + j; // zapamiêtanie gr->nTerrain = Current->nNode + j; // zapamiêtanie
else else

View File

@@ -182,28 +182,28 @@ class TGroundNode : public Resource
class TSubRect : public Resource, public CMesh class TSubRect : public Resource, public CMesh
{ // sektor składowy kwadratu kilometrowego { // sektor składowy kwadratu kilometrowego
public: public:
int iTracks; // ilość torów w (tTracks) int iTracks = 0; // ilość torów w (tTracks)
TTrack **tTracks; // tory do renderowania pojazdów TTrack **tTracks = nullptr; // tory do renderowania pojazdów
protected: protected:
TTrack *tTrackAnim; // obiekty do przeliczenia animacji TTrack *tTrackAnim = nullptr; // obiekty do przeliczenia animacji
TGroundNode *nRootMesh; // obiekty renderujące wg tekstury (wtórne, lista po nNext2) TGroundNode *nRootMesh = nullptr; // obiekty renderujące wg tekstury (wtórne, lista po nNext2)
TGroundNode *nMeshed; // lista obiektów dla których istnieją obiekty renderujące grupowo TGroundNode *nMeshed = nullptr; // lista obiektów dla których istnieją obiekty renderujące grupowo
public: public:
TGroundNode * TGroundNode *
nRootNode; // wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2) nRootNode = nullptr; // wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2)
TGroundNode * TGroundNode *
nRenderHidden; // lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3) nRenderHidden = nullptr; // lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3)
TGroundNode *nRenderRect; // z poziomu sektora - nieprzezroczyste (nNext3) TGroundNode *nRenderRect = nullptr; // z poziomu sektora - nieprzezroczyste (nNext3)
TGroundNode *nRenderRectAlpha; // z poziomu sektora - przezroczyste (nNext3) TGroundNode *nRenderRectAlpha = nullptr; // z poziomu sektora - przezroczyste (nNext3)
TGroundNode *nRenderWires; // z poziomu sektora - druty i inne linie (nNext3) TGroundNode *nRenderWires = nullptr; // z poziomu sektora - druty i inne linie (nNext3)
TGroundNode *nRender; // indywidualnie - nieprzezroczyste (nNext3) TGroundNode *nRender = nullptr; // indywidualnie - nieprzezroczyste (nNext3)
TGroundNode *nRenderMixed; // indywidualnie - nieprzezroczyste i przezroczyste (nNext3) TGroundNode *nRenderMixed = nullptr; // indywidualnie - nieprzezroczyste i przezroczyste (nNext3)
TGroundNode *nRenderAlpha; // indywidualnie - przezroczyste (nNext3) TGroundNode *nRenderAlpha = nullptr; // indywidualnie - przezroczyste (nNext3)
int iNodeCount; // licznik obiektów, do pomijania pustych sektorów int iNodeCount = 0; // licznik obiektów, do pomijania pustych sektorów
public: public:
void LoadNodes(); // utworzenie VBO sektora void LoadNodes(); // utworzenie VBO sektora
public: public:
TSubRect(); // TSubRect() = default;
virtual ~TSubRect(); virtual ~TSubRect();
virtual void Release(); // zwalnianie VBO sektora virtual void Release(); // zwalnianie VBO sektora
void NodeAdd(TGroundNode *Node); // dodanie obiektu do sektora na etapie rozdzielania na sektory void NodeAdd(TGroundNode *Node); // dodanie obiektu do sektora na etapie rozdzielania na sektory

View File

@@ -352,6 +352,10 @@ TMoverParameters::TMoverParameters(double VelInitial, std::string TypeNameInit,
Couplers[b].DmaxC = 0.1; Couplers[b].DmaxC = 0.1;
Couplers[b].FmaxC = 1000.0; Couplers[b].FmaxC = 1000.0;
} }
for( b = 0; b < 2; ++b ) {
HVCouplers[ b ][ 0 ] = 0.0;
HVCouplers[ b ][ 1 ] = 0.0;
}
Power = 0.0; Power = 0.0;
MaxLoad = 0; MaxLoad = 0;
LoadAccepted = ""; LoadAccepted = "";
@@ -549,7 +553,7 @@ TMoverParameters::TMoverParameters(double VelInitial, std::string TypeNameInit,
ResistorsFlag = false; ResistorsFlag = false;
RventRot = 0.0; RventRot = 0.0;
RVentType = 0; RVentType = 0;
RVentnmax = 0.0; RVentnmax = 1.0;
RVentCutOff = 0.0; RVentCutOff = 0.0;
enrot = 0.0; enrot = 0.0;
@@ -7791,7 +7795,14 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
WriteLog("XBT EStED"); WriteLog("XBT EStED");
Hamulec = std::make_shared<TEStED>(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA); Hamulec = std::make_shared<TEStED>(MaxBrakePress[3], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA);
Hamulec->SetRM(RapidMult); Hamulec->SetRM(RapidMult);
break; if( MBPM < 2 ) {
//jesli przystawka wazaca
Hamulec->SetLP( 0, MaxBrakePress[ 3 ], 0 );
}
else {
Hamulec->SetLP( Mass, MBPM, MaxBrakePress[ 1 ] );
}
break;
} }
case EP2: case EP2:
{ {

View File

@@ -96,9 +96,9 @@ double PFVa(double PH, double PL, double S, double LIM,
FM = FM * (LIM - PL) / DP; // jesli jestesmy przy nastawieniu, to zawor sie przymyka FM = FM * (LIM - PL) / DP; // jesli jestesmy przy nastawieniu, to zawor sie przymyka
if ((sg > 0.5)) // jesli ponizej stosunku krytycznego if ((sg > 0.5)) // jesli ponizej stosunku krytycznego
if ((PH - PL) < DPL) // niewielka roznica cisnien if ((PH - PL) < DPL) // niewielka roznica cisnien
return (PH - PL) / DPL * FM * 2 * sqrt((sg) * (1 - sg)); return (PH - PL) / DPL * FM * 2 * sqrt((sg) * (1 - sg)); // BUG: (1-sg) can be < 0, leading to sqrt(-x)
else else
return FM * 2 * sqrt((sg) * (1 - sg)); return FM * 2 * sqrt( (sg) * ( 1 - sg ) ); // BUG: (1-sg) can be < 0, leading to sqrt(-x)
else // powyzej stosunku krytycznego else // powyzej stosunku krytycznego
return FM; return FM;
} }
@@ -1835,7 +1835,7 @@ void TKE::CheckReleaser(double dt)
CVP = CntrlRes->P(); CVP = CntrlRes->P();
// odluzniacz // odluzniacz
if ((BrakeStatus && b_rls) == b_rls) if ( true == ((BrakeStatus & b_rls) == b_rls))
if ((CVP - VVP < 0)) if ((CVP - VVP < 0))
BrakeStatus &= 247; BrakeStatus &= 247;
else else
@@ -2591,32 +2591,23 @@ double TM394::GetPos(int i)
double TH14K1::GetPF(double i_bcp, double PP, double HP, double dt, double ep) double TH14K1::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
{ {
static int const LBDelay = 100; // szybkosc + zasilanie sterujacego int const LBDelay = 100; // szybkosc + zasilanie sterujacego
// static double const BPT_K[/*?*/ /*-1..4*/ (4) - (-1) + 1][2] = // static double const BPT_K[/*?*/ /*-1..4*/ (4) - (-1) + 1][2] =
//{ (10, 0), (4, 1), (0, 1), (4, 0), (4, -1), (15, -1) }; //{ (10, 0), (4, 1), (0, 1), (4, 0), (4, -1), (15, -1) };
static double const NomPress = 5.0; double const NomPress = 5.0;
double LimPP; int BCP = std::lround(i_bcp);
double dpPipe; if( i_bcp < -1 ) { BCP = 1; }
double dpMainValve;
double ActFlowSpeed;
int BCP;
BCP = lround(i_bcp); double LimPP = BPT_K[BCP + 1][1];
if (i_bcp < -1) if( LimPP < 0.0 ) { LimPP = 0.5 * PP; }
BCP = 1; else if( LimPP > 0.0 ) { LimPP = PP; }
LimPP = BPT_K[BCP + 1][1]; else { LimPP = CP; }
if (LimPP < 0) double ActFlowSpeed = BPT_K[BCP + 1][0];
LimPP = 0.5 * PP;
else if (LimPP > 0)
LimPP = PP;
else
LimPP = CP;
ActFlowSpeed = BPT_K[BCP + 1][0];
CP = CP + 6 * Min0R(abs(LimPP - CP), 0.05) * PR(CP, LimPP) * dt; // zbiornik sterujacy CP = CP + 6 * std::min( std::abs(LimPP - CP), 0.05 ) * PR(CP, LimPP) * dt; // zbiornik sterujacy
dpMainValve = 0; double dpMainValve = 0.0;
if (BCP == -1) if (BCP == -1)
dpMainValve = PF(HP, PP, ActFlowSpeed / LBDelay) * dt; dpMainValve = PF(HP, PP, ActFlowSpeed / LBDelay) * dt;

View File

@@ -279,7 +279,7 @@ std::string Tab2Sp(std::string const &s) /*Tab to Space sign*/
{ {
std::string s2 = ""; std::string s2 = "";
char tmp = (char)9; char tmp = (char)9;
for (int b = 0; b < s.length(); ++b) for (std::size_t b = 0; b < s.length(); ++b)
//{ //{
// if (s[b] == tmp[0]) // if (s[b] == tmp[0])
// s[b] = tmp[1]; // s[b] = tmp[1];
@@ -415,6 +415,9 @@ std::string to_hex_str( int const Value, int const Width )
int stol_def(const std::string &str, const int &DefaultValue) int stol_def(const std::string &str, const int &DefaultValue)
{ {
// NOTE: there's good chance this function is bugged, it produced wrong result on at least one occasion
// TODO: rewrite into something more reliable
// this function was developed iteratively on Codereview.stackexchange // this function was developed iteratively on Codereview.stackexchange
// with the assistance of @Corbin // with the assistance of @Corbin
std::size_t len = str.size(); std::size_t len = str.size();

View File

@@ -1844,7 +1844,11 @@ bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic) {
Init(); // generowanie siatek i zapis E3D Init(); // generowanie siatek i zapis E3D
} }
} }
return Root ? (iSubModelsCount > 0) : false; // brak pliku albo problem z wczytaniem bool const result = Root ? (iSubModelsCount > 0) : false; // brak pliku albo problem z wczytaniem
if( false == result ) {
ErrorLog( "Failed to load 3d model \"" + FileName + "\"" );
}
return result;
}; };
void TModel3d::LoadFromBinFile(std::string const &FileName, bool dynamic) void TModel3d::LoadFromBinFile(std::string const &FileName, bool dynamic)

View File

@@ -572,7 +572,7 @@ void TPythonScreens::run()
void TPythonScreens::finish() void TPythonScreens::finish()
{ {
_thread == NULL; _thread = NULL;
} }
DWORD WINAPI ScreenRendererThread(LPVOID lpParam) DWORD WINAPI ScreenRendererThread(LPVOID lpParam)

View File

@@ -908,7 +908,7 @@ void TTrain::OnKeyDown(int cKey)
else if (cKey == Global::Keys[k_LeftSign]) // lewe swiatlo - w<><77>czenie else if (cKey == Global::Keys[k_LeftSign]) // lewe swiatlo - w<><77>czenie
// ABu 060205: dzielo Wingera po malutkim liftingu: // ABu 060205: dzielo Wingera po malutkim liftingu:
{ {
if (!mvOccupied->LightsPosNo > 0) if (false == (mvOccupied->LightsPosNo > 0))
{ {
if ((GetAsyncKeyState(VK_CONTROL) < 0) && if ((GetAsyncKeyState(VK_CONTROL) < 0) &&
(ggRearLeftLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu (ggRearLeftLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu
@@ -1083,7 +1083,7 @@ void TTrain::OnKeyDown(int cKey)
// tylne (koncowki) - // tylne (koncowki) -
// wlaczenie // wlaczenie
{ {
if (!mvOccupied->LightsPosNo > 0) if (false == (mvOccupied->LightsPosNo > 0))
{ {
if ((GetAsyncKeyState(VK_CONTROL) < 0) && if ((GetAsyncKeyState(VK_CONTROL) < 0) &&
(ggRearRightLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu (ggRearRightLightButton.SubModel)) // hunter-230112 - z controlem zapala z tylu
@@ -2115,7 +2115,7 @@ if
else if (cKey == Global::Keys[k_LeftSign]) // ABu 060205: lewe swiatlo - else if (cKey == Global::Keys[k_LeftSign]) // ABu 060205: lewe swiatlo -
// wylaczenie // wylaczenie
{ {
if (!mvOccupied->LightsPosNo > 0) if (false == (mvOccupied->LightsPosNo > 0))
{ {
if ((GetAsyncKeyState(VK_CONTROL) < 0) && if ((GetAsyncKeyState(VK_CONTROL) < 0) &&
(ggRearLeftLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu (ggRearLeftLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu
@@ -2288,7 +2288,7 @@ if
if (cKey == Global::Keys[k_RightSign]) // Winger 070304: swiatla tylne if (cKey == Global::Keys[k_RightSign]) // Winger 070304: swiatla tylne
// (koncowki) - wlaczenie // (koncowki) - wlaczenie
{ {
if (!mvOccupied->LightsPosNo > 0) if (false == (mvOccupied->LightsPosNo > 0))
{ {
if ((GetAsyncKeyState(VK_CONTROL) < 0) && if ((GetAsyncKeyState(VK_CONTROL) < 0) &&
(ggRearRightLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu (ggRearRightLightButton.SubModel)) // hunter-230112 - z controlem gasi z tylu
@@ -3239,7 +3239,7 @@ bool TTrain::Update()
rsRunningNoise.AM = am; rsRunningNoise.AM = am;
rsRunningNoise.AA = 0.7; rsRunningNoise.AA = 0.7;
rsRunningNoise.FA = fa; rsRunningNoise.FA = fa;
rsRunningNoise.FM - fm; rsRunningNoise.FM = fm;
} }
mvOccupied->EventFlag = false; mvOccupied->EventFlag = false;
} }

View File

@@ -330,5 +330,3 @@ void TTrackFollower::Render(float fNr)
} }
#endif #endif
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#pragma package(smart_init)

View File

@@ -35,7 +35,6 @@ http://mozilla.org/MPL/2.0/.
#define TEXTURE_FILTER_CONTROL_EXT 0x8500 #define TEXTURE_FILTER_CONTROL_EXT 0x8500
#define TEXTURE_LOD_BIAS_EXT 0x8501 #define TEXTURE_LOD_BIAS_EXT 0x8501
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
#pragma package(smart_init)
typedef void(APIENTRY *FglutBitmapCharacter)(void *font, int character); // typ funkcji typedef void(APIENTRY *FglutBitmapCharacter)(void *font, int character); // typ funkcji
FglutBitmapCharacter glutBitmapCharacterDLL = NULL; // deklaracja zmiennej FglutBitmapCharacter glutBitmapCharacterDLL = NULL; // deklaracja zmiennej