]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/CIrrDeviceSDL.h
Reduce IrrCompileConfig usage to files that actually need it
[irrlicht.git] / source / Irrlicht / CIrrDeviceSDL.h
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 // This device code is based on the original SDL device implementation\r
5 // contributed by Shane Parker (sirshane).\r
6 \r
7 #ifndef __C_IRR_DEVICE_SDL_H_INCLUDED__\r
8 #define __C_IRR_DEVICE_SDL_H_INCLUDED__\r
9 \r
10 \r
11 #ifdef _IRR_COMPILE_WITH_SDL_DEVICE_\r
12 \r
13 #include "IrrlichtDevice.h"\r
14 #include "CIrrDeviceStub.h"\r
15 #include "ICursorControl.h"\r
16 \r
17 #ifdef _IRR_EMSCRIPTEN_PLATFORM_\r
18 #include <emscripten/html5.h>\r
19 #endif\r
20 \r
21 #include <SDL.h>\r
22 #include <SDL_syswm.h>\r
23 \r
24 #include <memory>\r
25 \r
26 namespace irr\r
27 {\r
28 \r
29         class CIrrDeviceSDL : public CIrrDeviceStub\r
30         {\r
31         public:\r
32 \r
33                 //! constructor\r
34                 CIrrDeviceSDL(const SIrrlichtCreationParameters& param);\r
35 \r
36                 //! destructor\r
37                 virtual ~CIrrDeviceSDL();\r
38 \r
39                 //! runs the device. Returns false if device wants to be deleted\r
40                 bool run() override;\r
41 \r
42                 //! pause execution temporarily\r
43                 void yield() override;\r
44 \r
45                 //! pause execution for a specified time\r
46                 void sleep(u32 timeMs, bool pauseTimer) override;\r
47 \r
48                 //! sets the caption of the window\r
49                 void setWindowCaption(const wchar_t* text) override;\r
50 \r
51                 //! returns if window is active. if not, nothing need to be drawn\r
52                 bool isWindowActive() const override;\r
53 \r
54                 //! returns if window has focus.\r
55                 bool isWindowFocused() const override;\r
56 \r
57                 //! returns if window is minimized.\r
58                 bool isWindowMinimized() const override;\r
59 \r
60                 //! returns color format of the window.\r
61                 video::ECOLOR_FORMAT getColorFormat() const override;\r
62 \r
63                 //! notifies the device that it should close itself\r
64                 void closeDevice() override;\r
65 \r
66                 //! Sets if the window should be resizable in windowed mode.\r
67                 void setResizable(bool resize=false) override;\r
68 \r
69                 //! Minimizes the window.\r
70                 void minimizeWindow() override;\r
71 \r
72                 //! Maximizes the window.\r
73                 void maximizeWindow() override;\r
74 \r
75                 //! Restores the window size.\r
76                 void restoreWindow() override;\r
77 \r
78                 //! Checks if the window is maximized.\r
79                 bool isWindowMaximized() const override;\r
80 \r
81                 //! Checks if the Irrlicht window is running in fullscreen mode\r
82                 /** \return True if window is fullscreen. */\r
83                 bool isFullscreen() const override;\r
84 \r
85                 //! Get the position of this window on screen\r
86                 core::position2di getWindowPosition() override;\r
87 \r
88                 //! Activate any joysticks, and generate events for them.\r
89                 bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) override;\r
90 \r
91                 //! Get the device type\r
92                 E_DEVICE_TYPE getType() const override\r
93                 {\r
94                         return EIDT_SDL;\r
95                 }\r
96 \r
97                 void SwapWindow();\r
98 \r
99                 //! Implementation of the linux cursor control\r
100                 class CCursorControl : public gui::ICursorControl\r
101                 {\r
102                 public:\r
103 \r
104                         CCursorControl(CIrrDeviceSDL* dev)\r
105                                 : Device(dev), IsVisible(true)\r
106                         {\r
107                                 initCursors();\r
108                         }\r
109 \r
110                         //! Changes the visible state of the mouse cursor.\r
111                         void setVisible(bool visible) override\r
112                         {\r
113                                 IsVisible = visible;\r
114                                 if ( visible )\r
115                                         SDL_ShowCursor( SDL_ENABLE );\r
116                                 else\r
117                                 {\r
118                                         SDL_ShowCursor( SDL_DISABLE );\r
119                                 }\r
120                         }\r
121 \r
122                         //! Returns if the cursor is currently visible.\r
123                         bool isVisible() const override\r
124                         {\r
125                                 return IsVisible;\r
126                         }\r
127 \r
128                         //! Sets the new position of the cursor.\r
129                         void setPosition(const core::position2d<f32> &pos) override\r
130                         {\r
131                                 setPosition(pos.X, pos.Y);\r
132                         }\r
133 \r
134                         //! Sets the new position of the cursor.\r
135                         void setPosition(f32 x, f32 y) override\r
136                         {\r
137                                 setPosition((s32)(x*Device->Width), (s32)(y*Device->Height));\r
138                         }\r
139 \r
140                         //! Sets the new position of the cursor.\r
141                         void setPosition(const core::position2d<s32> &pos) override\r
142                         {\r
143                                 setPosition(pos.X, pos.Y);\r
144                         }\r
145 \r
146                         //! Sets the new position of the cursor.\r
147                         void setPosition(s32 x, s32 y) override\r
148                         {\r
149                                 SDL_WarpMouseInWindow(Device->Window, x, y);\r
150 \r
151                                 if (SDL_GetRelativeMouseMode()) {\r
152                                         // There won't be an event for this warp (details on libsdl-org/SDL/issues/6034)\r
153                                         Device->MouseX = x;\r
154                                         Device->MouseY = y;\r
155                                 }\r
156                         }\r
157 \r
158                         //! Returns the current position of the mouse cursor.\r
159                         const core::position2d<s32>& getPosition(bool updateCursor) override\r
160                         {\r
161                                 if ( updateCursor )\r
162                                         updateCursorPos();\r
163                                 return CursorPos;\r
164                         }\r
165 \r
166                         //! Returns the current position of the mouse cursor.\r
167                         core::position2d<f32> getRelativePosition(bool updateCursor) override\r
168                         {\r
169                                 if ( updateCursor )\r
170                                         updateCursorPos();\r
171                                 return core::position2d<f32>(CursorPos.X / (f32)Device->Width,\r
172                                         CursorPos.Y / (f32)Device->Height);\r
173                         }\r
174 \r
175                         void setReferenceRect(core::rect<s32>* rect=0) override\r
176                         {\r
177                         }\r
178 \r
179                         virtual void setRelativeMode(bool relative) _IRR_OVERRIDE_\r
180                         {\r
181                                 // Only change it when necessary, as it flushes mouse motion when enabled\r
182                                 if ( relative != SDL_GetRelativeMouseMode()) {\r
183                                         if ( relative )\r
184                                                 SDL_SetRelativeMouseMode( SDL_TRUE );\r
185                                         else\r
186                                                 SDL_SetRelativeMouseMode( SDL_FALSE );\r
187                                 }\r
188                         }\r
189 \r
190                         void setActiveIcon(gui::ECURSOR_ICON iconId) override\r
191                         {\r
192                                 ActiveIcon = iconId;\r
193                                 if (iconId > Cursors.size() || !Cursors[iconId]) {\r
194                                         iconId = gui::ECI_NORMAL;\r
195                                         if (iconId > Cursors.size() || !Cursors[iconId])\r
196                                                 return;\r
197                                 }\r
198                                 SDL_SetCursor(Cursors[iconId].get());\r
199                         }\r
200 \r
201                         gui::ECURSOR_ICON getActiveIcon() const override\r
202                         {\r
203                                 return ActiveIcon;\r
204                         }\r
205 \r
206                 private:\r
207 \r
208                         void updateCursorPos()\r
209                         {\r
210 #ifdef _IRR_EMSCRIPTEN_PLATFORM_\r
211                                 EmscriptenPointerlockChangeEvent pointerlockStatus; // let's hope that test is not expensive ...\r
212                                 if ( emscripten_get_pointerlock_status(&pointerlockStatus) == EMSCRIPTEN_RESULT_SUCCESS )\r
213                                 {\r
214                                         if ( pointerlockStatus.isActive )\r
215                                         {\r
216                                                 CursorPos.X += Device->MouseXRel;\r
217                                                 CursorPos.Y += Device->MouseYRel;\r
218                                                 Device->MouseXRel = 0;\r
219                                                 Device->MouseYRel = 0;\r
220                                         }\r
221                                         else\r
222                                         {\r
223                                                 CursorPos.X = Device->MouseX;\r
224                                                 CursorPos.Y = Device->MouseY;\r
225                                         }\r
226                                 }\r
227 #else\r
228                                 CursorPos.X = Device->MouseX;\r
229                                 CursorPos.Y = Device->MouseY;\r
230 \r
231                                 if (CursorPos.X < 0)\r
232                                         CursorPos.X = 0;\r
233                                 if (CursorPos.X > (s32)Device->Width)\r
234                                         CursorPos.X = Device->Width;\r
235                                 if (CursorPos.Y < 0)\r
236                                         CursorPos.Y = 0;\r
237                                 if (CursorPos.Y > (s32)Device->Height)\r
238                                         CursorPos.Y = Device->Height;\r
239 #endif\r
240                         }\r
241 \r
242                         void initCursors();\r
243 \r
244                         CIrrDeviceSDL* Device;\r
245                         core::position2d<s32> CursorPos;\r
246                         bool IsVisible;\r
247 \r
248                         struct CursorDeleter {\r
249                                 void operator()(SDL_Cursor *ptr) {\r
250                                         if (ptr)\r
251                                                 SDL_FreeCursor(ptr);\r
252                                 }\r
253                         };\r
254                         std::vector<std::unique_ptr<SDL_Cursor, CursorDeleter>> Cursors;\r
255                         gui::ECURSOR_ICON ActiveIcon;\r
256                 };\r
257 \r
258         private:\r
259 \r
260 #ifdef _IRR_EMSCRIPTEN_PLATFORM_\r
261         static EM_BOOL MouseUpDownCallback(int eventType, const EmscriptenMouseEvent * event, void* userData);\r
262         static EM_BOOL MouseEnterCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);\r
263         static EM_BOOL MouseLeaveCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);\r
264 \r
265 #endif\r
266                 // Check if a key is a known special character with no side effects on text boxes.\r
267                 static bool keyIsKnownSpecial(EKEY_CODE key);\r
268 \r
269                 // Return the Char that should be sent to Irrlicht for the given key (either the one passed in or 0).\r
270                 static int findCharToPassToIrrlicht(int assumedChar, EKEY_CODE key);\r
271 \r
272                 // Check if a text box is in focus. Enable or disable SDL_TEXTINPUT events only if in focus.\r
273                 void resetReceiveTextInputEvents();\r
274 \r
275                 //! create the driver\r
276                 void createDriver();\r
277 \r
278                 bool createWindow();\r
279 \r
280                 void createKeyMap();\r
281 \r
282                 void logAttributes();\r
283                 SDL_GLContext Context;\r
284                 SDL_Window *Window;\r
285                 int SDL_Flags;\r
286 #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)\r
287                 core::array<SDL_Joystick*> Joysticks;\r
288 #endif\r
289 \r
290                 s32 MouseX, MouseY;\r
291                 s32 MouseXRel, MouseYRel;\r
292                 u32 MouseButtonStates;\r
293 \r
294                 u32 Width, Height;\r
295 \r
296                 bool Resizable;\r
297 \r
298                 struct SKeyMap\r
299                 {\r
300                         SKeyMap() {}\r
301                         SKeyMap(s32 x11, s32 win32)\r
302                                 : SDLKey(x11), Win32Key(win32)\r
303                         {\r
304                         }\r
305 \r
306                         s32 SDLKey;\r
307                         s32 Win32Key;\r
308 \r
309                         bool operator<(const SKeyMap& o) const\r
310                         {\r
311                                 return SDLKey<o.SDLKey;\r
312                         }\r
313                 };\r
314 \r
315                 core::array<SKeyMap> KeyMap;\r
316                 SDL_SysWMinfo Info;\r
317         };\r
318 \r
319 } // end namespace irr\r
320 \r
321 #endif // _IRR_COMPILE_WITH_SDL_DEVICE_\r
322 #endif // __C_IRR_DEVICE_SDL_H_INCLUDED__\r
323 \r