]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/CIrrDeviceStub.cpp
Prepare GUI for IME support
[irrlicht.git] / source / Irrlicht / CIrrDeviceStub.cpp
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt\r
2 // This file is part of the "Irrlicht Engine".\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
4 \r
5 #include "CIrrDeviceStub.h"\r
6 #include "ISceneManager.h"\r
7 #include "IEventReceiver.h"\r
8 #include "IFileSystem.h"\r
9 #include "IGUIElement.h"\r
10 #include "IGUIEnvironment.h"\r
11 #include "os.h"\r
12 #include "IrrCompileConfig.h"\r
13 #include "CTimer.h"\r
14 #include "CLogger.h"\r
15 #include "irrString.h"\r
16 #include "IRandomizer.h"\r
17 \r
18 namespace irr\r
19 {\r
20 //! constructor\r
21 CIrrDeviceStub::CIrrDeviceStub(const SIrrlichtCreationParameters& params)\r
22 : IrrlichtDevice(), VideoDriver(0), GUIEnvironment(0), SceneManager(0),\r
23         Timer(0), CursorControl(0), UserReceiver(params.EventReceiver),\r
24         Logger(0), Operator(0), Randomizer(0), FileSystem(0),\r
25         InputReceivingSceneManager(0), VideoModeList(0), ContextManager(0),\r
26         CreationParams(params), Close(false)\r
27 {\r
28         Timer = new CTimer(params.UsePerformanceTimer);\r
29         if (os::Printer::Logger)\r
30         {\r
31                 os::Printer::Logger->grab();\r
32                 Logger = (CLogger*)os::Printer::Logger;\r
33                 Logger->setReceiver(UserReceiver);\r
34         }\r
35         else\r
36         {\r
37                 Logger = new CLogger(UserReceiver);\r
38                 os::Printer::Logger = Logger;\r
39         }\r
40         Logger->setLogLevel(CreationParams.LoggingLevel);\r
41 \r
42         os::Printer::Logger = Logger;\r
43         Randomizer = createDefaultRandomizer();\r
44 \r
45         FileSystem = io::createFileSystem();\r
46         VideoModeList = new video::CVideoModeList();\r
47 \r
48         core::stringc s = "Irrlicht Engine version ";\r
49         s.append(getVersion());\r
50         os::Printer::log(s.c_str(), ELL_INFORMATION);\r
51 \r
52         checkVersion(params.SDK_version_do_not_use);\r
53 }\r
54 \r
55 \r
56 CIrrDeviceStub::~CIrrDeviceStub()\r
57 {\r
58         VideoModeList->drop();\r
59 \r
60         if (GUIEnvironment)\r
61                 GUIEnvironment->drop();\r
62 \r
63         if (SceneManager)\r
64                 SceneManager->drop();\r
65 \r
66         if (VideoDriver)\r
67                 VideoDriver->drop();\r
68 \r
69         if (ContextManager)\r
70                 ContextManager->drop();\r
71 \r
72         if ( FileSystem )\r
73                 FileSystem->drop();\r
74 \r
75         if (InputReceivingSceneManager)\r
76                 InputReceivingSceneManager->drop();\r
77 \r
78         if (CursorControl)\r
79                 CursorControl->drop();\r
80 \r
81         if (Operator)\r
82                 Operator->drop();\r
83 \r
84         if (Randomizer)\r
85                 Randomizer->drop();\r
86 \r
87         CursorControl = 0;\r
88 \r
89         if (Timer)\r
90                 Timer->drop();\r
91 \r
92         if (Logger->drop())\r
93                 os::Printer::Logger = 0;\r
94 }\r
95 \r
96 \r
97 void CIrrDeviceStub::createGUIAndScene()\r
98 {\r
99         #ifdef _IRR_COMPILE_WITH_GUI_\r
100         // create gui environment\r
101         GUIEnvironment = gui::createGUIEnvironment(FileSystem, VideoDriver, Operator);\r
102         #endif\r
103 \r
104         // create Scene manager\r
105         SceneManager = scene::createSceneManager(VideoDriver, FileSystem, CursorControl, GUIEnvironment);\r
106 \r
107         setEventReceiver(UserReceiver);\r
108 }\r
109 \r
110 \r
111 //! returns the video driver\r
112 video::IVideoDriver* CIrrDeviceStub::getVideoDriver()\r
113 {\r
114         return VideoDriver;\r
115 }\r
116 \r
117 \r
118 //! return file system\r
119 io::IFileSystem* CIrrDeviceStub::getFileSystem()\r
120 {\r
121         return FileSystem;\r
122 }\r
123 \r
124 \r
125 \r
126 //! returns the gui environment\r
127 gui::IGUIEnvironment* CIrrDeviceStub::getGUIEnvironment()\r
128 {\r
129         return GUIEnvironment;\r
130 }\r
131 \r
132 \r
133 \r
134 //! returns the scene manager\r
135 scene::ISceneManager* CIrrDeviceStub::getSceneManager()\r
136 {\r
137         return SceneManager;\r
138 }\r
139 \r
140 \r
141 //! \return Returns a pointer to the ITimer object. With it the\r
142 //! current Time can be received.\r
143 ITimer* CIrrDeviceStub::getTimer()\r
144 {\r
145         return Timer;\r
146 }\r
147 \r
148 \r
149 //! Returns the version of the engine.\r
150 const char* CIrrDeviceStub::getVersion() const\r
151 {\r
152         return IRRLICHT_SDK_VERSION;\r
153 }\r
154 \r
155 //! \return Returns a pointer to the mouse cursor control interface.\r
156 gui::ICursorControl* CIrrDeviceStub::getCursorControl()\r
157 {\r
158         return CursorControl;\r
159 }\r
160 \r
161 \r
162 //! \return Returns a pointer to a list with all video modes supported\r
163 //! by the gfx adapter.\r
164 video::IVideoModeList* CIrrDeviceStub::getVideoModeList()\r
165 {\r
166         return VideoModeList;\r
167 }\r
168 \r
169 //! return the context manager\r
170 video::IContextManager* CIrrDeviceStub::getContextManager()\r
171 {\r
172         return ContextManager;\r
173 }\r
174 \r
175 //! checks version of sdk and prints warning if there might be a problem\r
176 bool CIrrDeviceStub::checkVersion(const char* version)\r
177 {\r
178         if (strcmp(getVersion(), version))\r
179         {\r
180                 core::stringc w;\r
181                 w = "Warning: The library version of the Irrlicht Engine (";\r
182                 w += getVersion();\r
183                 w += ") does not match the version the application was compiled with (";\r
184                 w += version;\r
185                 w += "). This may cause problems.";\r
186                 os::Printer::log(w.c_str(), ELL_WARNING);\r
187 \r
188                 return false;\r
189         }\r
190 \r
191         return true;\r
192 }\r
193 \r
194 \r
195 //! Compares to the last call of this function to return double and triple clicks.\r
196 u32 CIrrDeviceStub::checkSuccessiveClicks(s32 mouseX, s32 mouseY, EMOUSE_INPUT_EVENT inputEvent )\r
197 {\r
198         const s32 MAX_MOUSEMOVE = 3;\r
199 \r
200         irr::u32 clickTime = getTimer()->getRealTime();\r
201 \r
202         if ( (clickTime-MouseMultiClicks.LastClickTime) < MouseMultiClicks.DoubleClickTime\r
203                 && core::abs_(MouseMultiClicks.LastClick.X - mouseX ) <= MAX_MOUSEMOVE\r
204                 && core::abs_(MouseMultiClicks.LastClick.Y - mouseY ) <= MAX_MOUSEMOVE\r
205                 && MouseMultiClicks.CountSuccessiveClicks < 3\r
206                 && MouseMultiClicks.LastMouseInputEvent == inputEvent\r
207            )\r
208         {\r
209                 ++MouseMultiClicks.CountSuccessiveClicks;\r
210         }\r
211         else\r
212         {\r
213                 MouseMultiClicks.CountSuccessiveClicks = 1;\r
214         }\r
215 \r
216         MouseMultiClicks.LastMouseInputEvent = inputEvent;\r
217         MouseMultiClicks.LastClickTime = clickTime;\r
218         MouseMultiClicks.LastClick.X = mouseX;\r
219         MouseMultiClicks.LastClick.Y = mouseY;\r
220 \r
221         return MouseMultiClicks.CountSuccessiveClicks;\r
222 }\r
223 \r
224 \r
225 //! send the event to the right receiver\r
226 bool CIrrDeviceStub::postEventFromUser(const SEvent& event)\r
227 {\r
228         bool absorbed = false;\r
229 \r
230         if (UserReceiver)\r
231                 absorbed = UserReceiver->OnEvent(event);\r
232 \r
233         if (!absorbed && GUIEnvironment)\r
234                 absorbed = GUIEnvironment->postEventFromUser(event);\r
235 \r
236         scene::ISceneManager* inputReceiver = InputReceivingSceneManager;\r
237         if (!inputReceiver)\r
238                 inputReceiver = SceneManager;\r
239 \r
240         if (!absorbed && inputReceiver)\r
241                 absorbed = inputReceiver->postEventFromUser(event);\r
242 \r
243         return absorbed;\r
244 }\r
245 \r
246 \r
247 //! Sets a new event receiver to receive events\r
248 void CIrrDeviceStub::setEventReceiver(IEventReceiver* receiver)\r
249 {\r
250         UserReceiver = receiver;\r
251         Logger->setReceiver(receiver);\r
252         if (GUIEnvironment)\r
253                 GUIEnvironment->setUserEventReceiver(receiver);\r
254 }\r
255 \r
256 \r
257 //! Returns poinhter to the current event receiver. Returns 0 if there is none.\r
258 IEventReceiver* CIrrDeviceStub::getEventReceiver()\r
259 {\r
260         return UserReceiver;\r
261 }\r
262 \r
263 \r
264 //! \return Returns a pointer to the logger.\r
265 ILogger* CIrrDeviceStub::getLogger()\r
266 {\r
267         return Logger;\r
268 }\r
269 \r
270 \r
271 //! Returns the operation system opertator object.\r
272 IOSOperator* CIrrDeviceStub::getOSOperator()\r
273 {\r
274         return Operator;\r
275 }\r
276 \r
277 \r
278 //! Provides access to the engine's currently set randomizer.\r
279 IRandomizer* CIrrDeviceStub::getRandomizer() const\r
280 {\r
281         return Randomizer;\r
282 }\r
283 \r
284 //! Sets a new randomizer.\r
285 void CIrrDeviceStub::setRandomizer(IRandomizer* r)\r
286 {\r
287         if (r!=Randomizer)\r
288         {\r
289                 if (Randomizer)\r
290                         Randomizer->drop();\r
291                 Randomizer=r;\r
292                 if (Randomizer)\r
293                         Randomizer->grab();\r
294         }\r
295 }\r
296 \r
297 namespace\r
298 {\r
299         struct SDefaultRandomizer : public IRandomizer\r
300         {\r
301                 virtual void reset(s32 value=0x0f0f0f0f) _IRR_OVERRIDE_\r
302                 {\r
303                         os::Randomizer::reset(value);\r
304                 }\r
305 \r
306                 virtual s32 rand() const _IRR_OVERRIDE_\r
307                 {\r
308                         return os::Randomizer::rand();\r
309                 }\r
310 \r
311                 virtual f32 frand() const _IRR_OVERRIDE_\r
312                 {\r
313                         return os::Randomizer::frand();\r
314                 }\r
315 \r
316                 virtual s32 randMax() const _IRR_OVERRIDE_\r
317                 {\r
318                         return os::Randomizer::randMax();\r
319                 }\r
320         };\r
321 }\r
322 \r
323 //! Creates a new default randomizer.\r
324 IRandomizer* CIrrDeviceStub::createDefaultRandomizer() const\r
325 {\r
326         IRandomizer* r = new SDefaultRandomizer();\r
327         if (r)\r
328                 r->reset();\r
329         return r;\r
330 }\r
331 \r
332 \r
333 //! Sets the input receiving scene manager.\r
334 void CIrrDeviceStub::setInputReceivingSceneManager(scene::ISceneManager* sceneManager)\r
335 {\r
336         if (sceneManager)\r
337                 sceneManager->grab();\r
338         if (InputReceivingSceneManager)\r
339                 InputReceivingSceneManager->drop();\r
340 \r
341         InputReceivingSceneManager = sceneManager;\r
342 }\r
343 \r
344 \r
345 //! Checks if the window is running in fullscreen mode\r
346 bool CIrrDeviceStub::isFullscreen() const\r
347 {\r
348         return CreationParams.Fullscreen;\r
349 }\r
350 \r
351 \r
352 //! returns color format\r
353 video::ECOLOR_FORMAT CIrrDeviceStub::getColorFormat() const\r
354 {\r
355         return video::ECF_R5G6B5;\r
356 }\r
357 \r
358 //! No-op in this implementation\r
359 bool CIrrDeviceStub::activateJoysticks(core::array<SJoystickInfo> & joystickInfo)\r
360 {\r
361         return false;\r
362 }\r
363 \r
364 //! No-op in this implementation\r
365 bool CIrrDeviceStub::activateAccelerometer(float updateInterval)\r
366 {\r
367     return false;\r
368 }\r
369 \r
370 //! No-op in this implementation\r
371 bool CIrrDeviceStub::deactivateAccelerometer()\r
372 {\r
373     return false;\r
374 }\r
375 \r
376 //! No-op in this implementation\r
377 bool CIrrDeviceStub::isAccelerometerActive()\r
378 {\r
379     return false;\r
380 }\r
381 \r
382 //! No-op in this implementation\r
383 bool CIrrDeviceStub::isAccelerometerAvailable()\r
384 {\r
385     return false;\r
386 }\r
387 \r
388 //! No-op in this implementation\r
389 bool CIrrDeviceStub::activateGyroscope(float updateInterval)\r
390 {\r
391     return false;\r
392 }\r
393 \r
394 //! No-op in this implementation\r
395 bool CIrrDeviceStub::deactivateGyroscope()\r
396 {\r
397     return false;\r
398 }\r
399 \r
400 //! No-op in this implementation\r
401 bool CIrrDeviceStub::isGyroscopeActive()\r
402 {\r
403     return false;\r
404 }\r
405 \r
406 //! No-op in this implementation\r
407 bool CIrrDeviceStub::isGyroscopeAvailable()\r
408 {\r
409     return false;\r
410 }\r
411 \r
412 //! No-op in this implementation\r
413 bool CIrrDeviceStub::activateDeviceMotion(float updateInterval)\r
414 {\r
415     return false;\r
416 }\r
417 \r
418 //! No-op in this implementation\r
419 bool CIrrDeviceStub::deactivateDeviceMotion()\r
420 {\r
421     return false;\r
422 }\r
423 \r
424 //! No-op in this implementation\r
425 bool CIrrDeviceStub::isDeviceMotionActive()\r
426 {\r
427     return false;\r
428 }\r
429 \r
430 //! No-op in this implementation\r
431 bool CIrrDeviceStub::isDeviceMotionAvailable()\r
432 {\r
433     return false;\r
434 }\r
435 \r
436 /*!\r
437 */\r
438 void CIrrDeviceStub::calculateGammaRamp ( u16 *ramp, f32 gamma, f32 relativebrightness, f32 relativecontrast )\r
439 {\r
440         s32 i;\r
441         s32 value;\r
442         s32 rbright = (s32) ( relativebrightness * (65535.f / 4 ) );\r
443         f32 rcontrast = 1.f / (255.f - ( relativecontrast * 127.5f ) );\r
444 \r
445         gamma = gamma > 0.f ? 1.0f / gamma : 0.f;\r
446 \r
447         for ( i = 0; i < 256; ++i )\r
448         {\r
449                 value = (s32)(pow( rcontrast * i, gamma)*65535.f + 0.5f );\r
450                 ramp[i] = (u16) core::s32_clamp ( value + rbright, 0, 65535 );\r
451         }\r
452 \r
453 }\r
454 \r
455 void CIrrDeviceStub::calculateGammaFromRamp ( f32 &gamma, const u16 *ramp )\r
456 {\r
457         /* The following is adapted from a post by Garrett Bass on OpenGL\r
458         Gamedev list, March 4, 2000.\r
459         */\r
460         f32 sum = 0.0;\r
461         s32 i, count = 0;\r
462 \r
463         gamma = 1.0;\r
464         for ( i = 1; i < 256; ++i ) {\r
465                 if ( (ramp[i] != 0) && (ramp[i] != 65535) ) {\r
466                         f32 B = (f32)i / 256.f;\r
467                         f32 A = ramp[i] / 65535.f;\r
468                         sum += (f32) ( logf(A) / logf(B) );\r
469                         count++;\r
470                 }\r
471         }\r
472         if ( count && sum ) {\r
473                 gamma = 1.0f / (sum / count);\r
474         }\r
475 \r
476 }\r
477 \r
478 //! Set the current Gamma Value for the Display\r
479 bool CIrrDeviceStub::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast )\r
480 {\r
481         return false;\r
482 }\r
483 \r
484 //! Get the current Gamma Value for the Display\r
485 bool CIrrDeviceStub::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast )\r
486 {\r
487         return false;\r
488 }\r
489 \r
490 //! Set the maximal elapsed time between 2 clicks to generate doubleclicks for the mouse. It also affects tripleclick behavior.\r
491 void CIrrDeviceStub::setDoubleClickTime( u32 timeMs )\r
492 {\r
493         MouseMultiClicks.DoubleClickTime = timeMs;\r
494 }\r
495 \r
496 //! Get the maximal elapsed time between 2 clicks to generate double- and tripleclicks for the mouse.\r
497 u32 CIrrDeviceStub::getDoubleClickTime() const\r
498 {\r
499         return MouseMultiClicks.DoubleClickTime;\r
500 }\r
501 \r
502 //! Remove all messages pending in the system message loop\r
503 void CIrrDeviceStub::clearSystemMessages()\r
504 {\r
505 }\r
506 \r
507 //! Checks whether the input device should take input from the IME\r
508 bool CIrrDeviceStub::acceptsIME()\r
509 {\r
510         if (!GUIEnvironment)\r
511                 return false;\r
512         gui::IGUIElement *elem = GUIEnvironment->getFocus();\r
513         return elem && elem->acceptsIME();\r
514 }\r
515 \r
516 \r
517 } // end namespace irr\r
518 \r