1 //  ---------------------------------------------------------------------------
2 //
3 //  @file       TwMgr.h
4 //  @brief      Tweak bar manager.
5 //  @author     Philippe Decaudin
6 //  @license    This file is part of the AntTweakBar library.
7 //              For conditions of distribution and use, see License.txt
8 //
9 //  note:       Private header
10 //
11 //  ---------------------------------------------------------------------------
12 
13 
14 #if !defined ANT_TW_MGR_INCLUDED
15 #define ANT_TW_MGR_INCLUDED
16 
17 #include <AntTweakBar.h>
18 #define ANT_CALL TW_CALL
19 
20 #include "TwColors.h"
21 #include "TwFonts.h"
22 #include "TwGraph.h"
23 #include "AntPerfTimer.h"
24 
25 
26 //#define BENCH // uncomment to activate benchmarks
27 
28 #ifdef BENCH
29 #   define PERF(cmd)    cmd
30 #else   // BENCH
31 #   define PERF(cmd)
32 #endif  // BENCH
33 
34 const int NB_ROTO_CURSORS = 12;
35 
36 
37 //  ---------------------------------------------------------------------------
38 //  API unexposed by AntTweakBar.h
39 //  ---------------------------------------------------------------------------
40 
41 // bar states -> use TwDefine instead
42 typedef enum ETwState
43 {
44     TW_STATE_SHOWN       = 1,
45     TW_STATE_ICONIFIED   = 2,
46     TW_STATE_HIDDEN      = 3,
47     TW_STATE_UNICONIFIED = 4,
48     TW_STATE_ERROR       = 0
49 } TwState;
50 /*ANT_TWEAK_BAR_API*/ int       ANT_CALL TwSetBarState(TwBar *bar, TwState state);
51 /*ANT_TWEAK_BAR_API*/ //TwState ANT_CALL TwGetBarState(const TwBar *bar);
52 // var states -> use TwDefine instead: visible/iconified implemented only as string commands
53 //ANT_TWEAK_BAR_API int     ANT_CALL TwSetVarState(TwBar *bar, const char *name, TwState state);
54 //ANT_TWEAK_BAR_API TwState ANT_CALL TwGetVarState(const TwBar *bar, const char *name);
55 
56 struct CTwVarGroup;
57 typedef void (ANT_CALL *TwStructExtInitCallback)(void *structExtValue, void *clientData);
58 typedef void (ANT_CALL *TwCopyVarFromExtCallback)(void *structValue, const void *structExtValue, unsigned int structExtMemberIndex, void *clientData);
59 typedef void (ANT_CALL *TwCopyVarToExtCallback)(const void *structValue, void *structExtValue, unsigned int structExtMemberIndex, void *clientData);
60 /*ANT_TWEAK_BAR_API*/ TwType    ANT_CALL TwDefineStructExt(const char *name, const TwStructMember *structExtMembers, unsigned int nbExtMembers, size_t structSize, size_t structExtSize, TwStructExtInitCallback structExtInitCallback, TwCopyVarFromExtCallback copyVarFromExtCallback, TwCopyVarToExtCallback copyVarToExtCallback, TwSummaryCallback summaryCallback, void *clientData, const char *help);
61 typedef void (ANT_CALL *TwCustomDrawCallback)(int w, int h, void *structExtValue, void *clientData, TwBar *bar, CTwVarGroup *varGrp);
62 typedef bool (ANT_CALL *TwCustomMouseMotionCallback)(int mouseX, int mouseY, int w, int h, void *structExtValue, void *clientData, TwBar *bar, CTwVarGroup *varGrp);
63 typedef bool (ANT_CALL *TwCustomMouseButtonCallback)(TwMouseButtonID button, bool pressed, int mouseX, int mouseY, int w, int h, void *structExtValue, void *clientData, TwBar *bar, CTwVarGroup *varGrp);
64 typedef void (ANT_CALL *TwCustomMouseLeaveCallback)(void *structExtValue, void *clientData, TwBar *bar);
65 
66 enum ERetType
67 {
68     RET_ERROR = 0,
69     RET_DOUBLE,
70     RET_STRING
71 };
72 
73 enum EButtonAlign
74 {
75     BUTTON_ALIGN_LEFT,
76     BUTTON_ALIGN_CENTER,
77     BUTTON_ALIGN_RIGHT
78 };
79 
80 //  ---------------------------------------------------------------------------
81 //  AntTweakBar Manager
82 //  ---------------------------------------------------------------------------
83 
84 struct CTwMgr
85 {
86     ETwGraphAPI         m_GraphAPI;
87     void *              m_Device;
88     int                 m_WndID;
89     class ITwGraph *    m_Graph;
90     int                 m_WndWidth;
91     int                 m_WndHeight;
92     const CTexFont *    m_CurrentFont;
93 
94     std::vector<TwBar*> m_Bars;
95     std::vector<int>    m_Order;
96 
97     std::vector<bool>   m_MinOccupied;
98     void                Minimize(TwBar *_Bar);
99     void                Maximize(TwBar *_Bar);
100     void                Hide(TwBar *_Bar);
101     void                Unhide(TwBar *_Bar);
102     void                SetFont(const CTexFont *_Font, bool _ResizeBars);
103     int                 m_LastMouseX;
104     int                 m_LastMouseY;
105     int                 m_LastMouseWheelPos;
106     int                 m_IconPos;      // 0: bottom-left, 1:bottom-right, 2:top-left, 3:top-right
107     int                 m_IconAlign;    // 0: vertical, 1: horizontal
108     int                 m_IconMarginX, m_IconMarginY;
109     bool                m_FontResizable;
110     std::string         m_BarAlwaysOnTop;
111     std::string         m_BarAlwaysOnBottom;
112     bool                m_UseOldColorScheme;
113     bool                m_Contained;
114     EButtonAlign        m_ButtonAlign;
115     bool                m_OverlapContent;
116     bool                m_Terminating;
117 
118     std::string         m_Help;
119     TwBar *             m_HelpBar;
120     float               m_LastHelpUpdateTime;
121     void                UpdateHelpBar();
122     bool                m_HelpBarNotUpToDate;
123     bool                m_HelpBarUpdateNow;
124     void *              m_KeyPressedTextObj;
125     bool                m_KeyPressedBuildText;
126     std::string         m_KeyPressedStr;
127     float               m_KeyPressedTime;
128     void *              m_InfoTextObj;
129     bool                m_InfoBuildText;
130     int                 m_BarInitColorHue;
131     int                 FindBar(const char *_Name) const;
132     int                 HasAttrib(const char *_Attrib, bool *_HasValue) const;
133     int                 SetAttrib(int _AttribID, const char *_Value);
134     ERetType            GetAttrib(int _AttribID, std::vector<double>& outDouble, std::ostringstream& outString) const;
135     void                SetLastError(const char *_StaticErrorMesssage); // _StaticErrorMesssage must be a static string
136     const char *        GetLastError();                                 // returns a static string describing the error, and set LastError to NULL
137     const char *        CheckLastError() const;                         // returns the LastError, but does not set it to NULL
138     void                SetCurrentDbgParams(const char *file, int line);
139     TwBar *             m_PopupBar;
140     //bool              IsProcessing() const            { return m_Processing);
141     //void              SetProcessing(bool processing)  { m_Processing = processing; }
142 
143                         CTwMgr(ETwGraphAPI _GraphAPI, void *_Device, int _WndID);
144                         ~CTwMgr();
145 
146     struct CStructMember
147     {
148         std::string     m_Name;
149         std::string     m_Label;
150         TwType          m_Type;
151         size_t          m_Offset;
152         std::string     m_DefString;
153         size_t          m_Size;
154         std::string     m_Help;
155     };
156     struct CStruct
157     {
158         std::string                 m_Name;
159         std::vector<CStructMember>  m_Members;
160         size_t                      m_Size;
161         TwSummaryCallback           m_SummaryCallback;
162         void *                      m_SummaryClientData;
163         std::string                 m_Help;
164         bool                        m_IsExt;
165         size_t                      m_ClientStructSize;
166         TwStructExtInitCallback     m_StructExtInitCallback;
167         TwCopyVarFromExtCallback    m_CopyVarFromExtCallback;
168         TwCopyVarToExtCallback      m_CopyVarToExtCallback;
169         void *                      m_ExtClientData;
CStructCTwMgr::CStruct170         CStruct() : m_IsExt(false), m_StructExtInitCallback(NULL), m_CopyVarFromExtCallback(NULL), m_CopyVarToExtCallback(NULL), m_ExtClientData(NULL) {}
171         static void ANT_CALL        DefaultSummary(char *_SummaryString, size_t _SummaryMaxLength, const void *_Value, void *_ClientData);
172         static void *               s_PassProxyAsClientData;
173     };
174     std::vector<CStruct> m_Structs;
175 
176     // followings are used for TwAddVarCB( ... StructType ... )
177     struct CStructProxy
178     {
179         TwType           m_Type;
180         void *           m_StructData;
181         bool             m_DeleteStructData;
182         void *           m_StructExtData;
183         TwSetVarCallback m_StructSetCallback;
184         TwGetVarCallback m_StructGetCallback;
185         void *           m_StructClientData;
186         TwCustomDrawCallback        m_CustomDrawCallback;
187         TwCustomMouseMotionCallback m_CustomMouseMotionCallback;
188         TwCustomMouseButtonCallback m_CustomMouseButtonCallback;
189         TwCustomMouseLeaveCallback  m_CustomMouseLeaveCallback;
190         bool             m_CustomCaptureFocus;
191         int              m_CustomIndexFirst;
192         int              m_CustomIndexLast;
193         CStructProxy();
194         ~CStructProxy();
195     };
196     struct CMemberProxy
197     {
198         CStructProxy *  m_StructProxy;
199         int             m_MemberIndex;
200         struct CTwVar * m_Var;
201         struct CTwVarGroup * m_VarParent;
202         CTwBar *        m_Bar;
203         CMemberProxy();
204         ~CMemberProxy();
205         static void ANT_CALL SetCB(const void *_Value, void *_ClientData);
206         static void ANT_CALL GetCB(void *_Value, void *_ClientData);
207     };
208     std::list<CStructProxy> m_StructProxies;    // elements should not move
209     std::list<CMemberProxy> m_MemberProxies;    // elements should not move
210     //void              InitVarData(TwType _Type, void *_Data, size_t _Size);
211     //void              UninitVarData(TwType _Type, void *_Data, size_t _Size);
212 
213     struct CEnum
214     {
215         std::string     m_Name;
216         typedef std::map<unsigned int, std::string> CEntries;
217         CEntries        m_Entries;
218     };
219     std::vector<CEnum>  m_Enums;
220 
221     TwType              m_TypeColor32;
222     TwType              m_TypeColor3F;
223     TwType              m_TypeColor4F;
224     TwType              m_TypeQuat4F;
225     TwType              m_TypeQuat4D;
226     TwType              m_TypeDir3F;
227     TwType              m_TypeDir3D;
228 
229     std::vector<char>   m_CSStringBuffer;
230     struct CCDStdString
231     {
232         std::string *        m_ClientStdStringPtr;
233         char                 m_LocalString[sizeof(std::string)+2*sizeof(void*)]; //+2*sizeof(void*) because of VC++ std::string extra info in Debug
234         TwSetVarCallback     m_ClientSetCallback;
235         TwGetVarCallback     m_ClientGetCallback;
236         void *               m_ClientData;
237         static void ANT_CALL SetCB(const void *_Value, void *_ClientData);
238         static void ANT_CALL GetCB(void *_Value, void *_ClientData);
239     };
240     std::list<CCDStdString>  m_CDStdStrings;
241     struct CClientStdString  // Convertion between VC++ Debug/Release std::string
242     {
243                         CClientStdString();
244         void            FromLib(const char *libStr);
245         std::string&    ToClient();
246     private:
247         char            m_Data[sizeof(std::string)+2*sizeof(void *)];
248         std::string     m_LibStr;
249     };
250     struct CLibStdString   // Convertion between VC++ Debug/Release std::string
251     {
252                         CLibStdString();
253         void            FromClient(const std::string& clientStr);
254         std::string&    ToLib();
255     private:
256         char            m_Data[sizeof(std::string)+2*sizeof(void *)];
257     };
258     struct CCDStdStringRecord
259     {
260         void *              m_DataPtr;
261         char                m_PrevValue[sizeof(std::string)+2*sizeof(void*)];
262         CClientStdString    m_ClientStdString;
263     };
264     std::vector<CCDStdStringRecord> m_CDStdStringRecords;
265     void                UnrollCDStdString(std::vector<CCDStdStringRecord>& _Records, TwType _Type, void *_Data);
266     void                RestoreCDStdString(const std::vector<CCDStdStringRecord>& _Records);
267     std::map<void *, std::vector<char> > m_CDStdStringCopyBuffers;
268 
269     struct CCustom      // custom var type
270     {
271         virtual         ~CCustom() = 0;
272     };
273     std::vector<CCustom *> m_Customs;
274 
275     PerfTimer           m_Timer;
276     double              m_LastMousePressedTime;
277     TwMouseButtonID     m_LastMousePressedButtonID;
278     int                 m_LastMousePressedPosition[2];
279     double              m_RepeatMousePressedDelay;
280     double              m_RepeatMousePressedPeriod;
281     bool                m_CanRepeatMousePressed;
282     bool                m_IsRepeatingMousePressed;
283     double              m_LastDrawTime;
284 
285     #if defined(ANT_WINDOWS)
286         typedef HCURSOR CCursor;
287         CCursor         PixmapCursor(int _CurIdx);
288     #elif defined(ANT_UNIX)
289         typedef Cursor  CCursor;
290         CCursor         PixmapCursor(int _CurIdx);
291         Display *       m_CurrentXDisplay;
292         Window          m_CurrentXWindow;
293     #elif defined(ANT_OSX)
294         typedef NSCursor * CCursor;
295         CCursor         PixmapCursor(int _CurIdx);
296     #endif  // defined(ANT_UNIX)
297     bool                m_CursorsCreated;
298     void                CreateCursors();
299     void                FreeCursors();
300     void                SetCursor(CCursor _Cursor);
301     CCursor             m_CursorArrow;
302     CCursor             m_CursorMove;
303     CCursor             m_CursorWE;
304     CCursor             m_CursorNS;
305     CCursor             m_CursorTopLeft;
306     CCursor             m_CursorTopRight;
307     CCursor             m_CursorBottomLeft;
308     CCursor             m_CursorBottomRight;
309     CCursor             m_CursorHelp;
310     CCursor             m_CursorHand;
311     CCursor             m_CursorCross;
312     CCursor             m_CursorUpArrow;
313     CCursor             m_CursorNo;
314     CCursor             m_CursorIBeam;
315     CCursor             m_RotoCursors[NB_ROTO_CURSORS];
316     CCursor             m_CursorCenter;
317     CCursor             m_CursorPoint;
318 
319     TwCopyCDStringToClient  m_CopyCDStringToClient;
320     TwCopyStdStringToClient m_CopyStdStringToClient;
321     size_t              m_ClientStdStringStructSize;
322     TwType              m_ClientStdStringBaseType;
323 
324 protected:
325     int                 m_NbMinimizedBars;
326     const char *        m_LastError;
327     const char *        m_CurrentDbgFile;
328     int                 m_CurrentDbgLine;
329     //bool              m_Processing;
330 };
331 
332 extern CTwMgr *g_TwMgr;
333 
334 
335 //  ---------------------------------------------------------------------------
336 //  Extra functions and TwTypes
337 //  ---------------------------------------------------------------------------
338 
339 
340 bool TwGetKeyCode(int *_Code, int *_Modif, const char *_String);
341 bool TwGetKeyString(std::string *_String, int _Code, int _Modif);
342 
343 const TwType TW_TYPE_SHORTCUT       = TwType(0xfff1);
344 const TwType TW_TYPE_HELP_GRP       = TwType(0xfff2);
345 const TwType TW_TYPE_HELP_ATOM      = TwType(0xfff3);
346 const TwType TW_TYPE_HELP_HEADER    = TwType(0xfff4);
347 const TwType TW_TYPE_HELP_STRUCT    = TwType(0xfff5);
348 const TwType TW_TYPE_BUTTON         = TwType(0xfff6);
349 const TwType TW_TYPE_CDSTDSTRING    = TwType(0xfff7);
350 const TwType TW_TYPE_STRUCT_BASE    = TwType(0x10000000);
351 const TwType TW_TYPE_ENUM_BASE      = TwType(0x20000000);
352 const TwType TW_TYPE_CSSTRING_BASE  = TW_TYPE_CSSTRING(0);          // defined as 0x30000000 (see AntTweakBar.h)
353 const TwType TW_TYPE_CSSTRING_MAX   = TW_TYPE_CSSTRING(0xfffffff);
354 #define TW_CSSTRING_SIZE(type)      ((int)((type)&0xfffffff))
355 const TwType TW_TYPE_CUSTOM_BASE    = TwType(0x40000000);
356 const TwType TW_TYPE_STDSTRING_VS2008 = TwType(0x2fff0000);
357 const TwType TW_TYPE_STDSTRING_VS2010 = TwType(0x2ffe0000);
358 
359 extern "C" int ANT_CALL TwSetLastError(const char *_StaticErrorMessage);
360 
361 //const TwGraphAPI TW_OPENGL_CORE = (TwGraphAPI)5; // WIP (note: OpenGL Core Profil requires OpenGL 3.2 or later)
362 
363 // Clipping helper
364 struct CRect
365 {
366     int X, Y, W, H;
CRectCRect367     CRect() : X(0), Y(0), W(0), H(0) {}
CRectCRect368     CRect(int _X, int _Y, int _W, int _H) : X(_X), Y(_Y), W(_W), H(_H) {}
369     bool operator==(const CRect& _Rect) { return (Empty() && _Rect.Empty()) || (X==_Rect.X && Y==_Rect.Y && W==_Rect.W && H==_Rect.H); }
370     bool Empty(int _Margin=0) const { return (W<=_Margin || H<=_Margin); }
371     bool Subtract(const CRect& _Rect, std::vector<CRect>& _OutRects) const;
372     bool Subtract(const std::vector<CRect>& _Rects, std::vector<CRect>& _OutRects) const;
373 };
374 
375 
376 //  ---------------------------------------------------------------------------
377 //  Global bar attribs
378 //  ---------------------------------------------------------------------------
379 
380 
381 enum EMgrAttribs
382 {
383     MGR_HELP = 1,
384     MGR_FONT_SIZE,
385     MGR_FONT_STYLE,
386     MGR_ICON_POS,
387     MGR_ICON_ALIGN,
388     MGR_ICON_MARGIN,
389     MGR_FONT_RESIZABLE,
390     MGR_COLOR_SCHEME,
391     MGR_CONTAINED,
392     MGR_BUTTON_ALIGN,
393     MGR_OVERLAP
394 };
395 
396 
397 //  ---------------------------------------------------------------------------
398 //  Color struct ext
399 //  ---------------------------------------------------------------------------
400 
401 
402 struct CColorExt
403 {
404     int                  R, G, B;
405     int                  H, L, S;
406     int                  A;
407     bool                 m_HLS, m_HasAlpha, m_OGL;
408     bool                 m_CanHaveAlpha;
409     bool                 m_IsColorF;
410     unsigned int         m_PrevConvertedColor;
411     CTwMgr::CStructProxy*m_StructProxy;
412     void                 RGB2HLS();
413     void                 HLS2RGB();
414     static void ANT_CALL InitColor32CB(void *_ExtValue, void *_ClientData);
415     static void ANT_CALL InitColor3FCB(void *_ExtValue, void *_ClientData);
416     static void ANT_CALL InitColor4FCB(void *_ExtValue, void *_ClientData);
417     static void ANT_CALL CopyVarFromExtCB(void *_VarValue, const void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData);
418     static void ANT_CALL CopyVarToExtCB(const void *_VarValue, void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData);
419     static void ANT_CALL SummaryCB(char *_SummaryString, size_t _SummaryMaxLength, const void *_ExtValue, void *_ClientData);
420     static void          CreateTypes();
421 };
422 
423 
424 //  ---------------------------------------------------------------------------
425 //  Quaternion struct ext
426 //  ---------------------------------------------------------------------------
427 
428 
429 struct CQuaternionExt
430 {
431     double               Qx, Qy, Qz, Qs;    // Quat value
432     double               Vx, Vy, Vz, Angle; // Not used
433     double               Dx, Dy, Dz;        // Dir value set when used as a direction
434     bool                 m_AAMode;          // Axis & angle mode -> disabled
435     bool                 m_ShowVal;         // Display values
436     bool                 m_IsFloat;         // Quat/Dir uses floats
437     bool                 m_IsDir;           // Mapped to a dir vector instead of a quat
438     double               m_Dir[3];          // If not zero, display one direction vector
439     color32              m_DirColor;        // Direction vector color
440     float                m_Permute[3][3];   // Permute frame axis
441     CTwMgr::CStructProxy*m_StructProxy;
442     static void ANT_CALL InitQuat4FCB(void *_ExtValue, void *_ClientData);
443     static void ANT_CALL InitQuat4DCB(void *_ExtValue, void *_ClientData);
444     static void ANT_CALL InitDir3FCB(void *_ExtValue, void *_ClientData);
445     static void ANT_CALL InitDir3DCB(void *_ExtValue, void *_ClientData);
446     static void ANT_CALL CopyVarFromExtCB(void *_VarValue, const void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData);
447     static void ANT_CALL CopyVarToExtCB(const void *_VarValue, void *_ExtValue, unsigned int _ExtMemberIndex, void *_ClientData);
448     static void ANT_CALL SummaryCB(char *_SummaryString, size_t _SummaryMaxLength, const void *_ExtValue, void *_ClientData);
449     static void ANT_CALL DrawCB(int _W, int _H, void *_ExtValue, void *_ClientData, TwBar *_Bar, CTwVarGroup *varGrp);
450     static bool ANT_CALL MouseMotionCB(int _MouseX, int _MouseY, int _W, int _H, void *_StructExtValue, void *_ClientData, TwBar *_Bar, CTwVarGroup *varGrp);
451     static bool ANT_CALL MouseButtonCB(TwMouseButtonID _Button, bool _Pressed, int _MouseX, int _MouseY, int _W, int _H, void *_StructExtValue, void *_ClientData, TwBar *_Bar, CTwVarGroup *varGrp);
452     static void ANT_CALL MouseLeaveCB(void *_StructExtValue, void *_ClientData, TwBar *_Bar);
453     static void          CreateTypes();
454     static TwType        s_CustomType;
455     void                 ConvertToAxisAngle();
456     void                 ConvertFromAxisAngle();
457     void                 CopyToVar();
458     static std::vector<float>   s_SphTri;
459     static std::vector<color32> s_SphCol;
460     static std::vector<int>     s_SphTriProj;
461     static std::vector<color32> s_SphColLight;
462     static std::vector<float>   s_ArrowTri[4];
463     static std::vector<int>     s_ArrowTriProj[4];
464     static std::vector<float>   s_ArrowNorm[4];
465     static std::vector<color32> s_ArrowColLight[4];
466     enum EArrowParts     { ARROW_CONE, ARROW_CONE_CAP, ARROW_CYL, ARROW_CYL_CAP };
467     static void          CreateSphere();
468     static void          CreateArrow();
469     static void          ApplyQuat(float *outX, float *outY, float *outZ, float x, float y, float z, float qx, float qy, float qz, float qs);
470     static void          QuatFromDir(double *outQx, double *outQy, double *outQz, double *outQs, double dx, double dy, double dz);
471     inline void          Permute(float *outX, float *outY, float *outZ, float x, float y, float z);
472     inline void          PermuteInv(float *outX, float *outY, float *outZ, float x, float y, float z);
473     inline void          Permute(double *outX, double *outY, double *outZ, double x, double y, double z);
474     inline void          PermuteInv(double *outX, double *outY, double *outZ, double x, double y, double z);
475     bool                 m_Highlighted;
476     bool                 m_Rotating;
477     double               m_OrigQuat[4];
478     float                m_OrigX, m_OrigY;
479     double               m_PrevX, m_PrevY;
480 };
481 
482 
483 //  ---------------------------------------------------------------------------
484 //  CTwFPU objects set and restore the fpu precision if needed.
485 //  (could be useful because DirectX changes it and AntTweakBar requires default double precision)
486 //  ---------------------------------------------------------------------------
487 
488 
489 struct CTwFPU
490 {
CTwFPUCTwFPU491     CTwFPU()
492     {
493     #ifdef ANT_WINDOWS
494         state0 = _controlfp(0, 0);
495         if( (state0&MCW_PC)==_PC_24 )   // we need at least _PC_53
496             _controlfp(_PC_53, MCW_PC);
497     #else
498         state0 = 0;
499     #endif
500     }
~CTwFPUCTwFPU501     ~CTwFPU()
502     {
503     #ifdef ANT_WINDOWS
504         if( (state0&MCW_PC)==_PC_24 )
505             _controlfp(_PC_24, MCW_PC);
506     #else
507         state0 = 0;
508     #endif
509     }
510 private:
511     unsigned int state0;
512 };
513 
514 //  ---------------------------------------------------------------------------
515 
516 
517 #endif // !defined ANT_TW_MGR_INCLUDED
518