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