diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceWin32.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceWin32.cpp | 4136 |
1 files changed, 2068 insertions, 2068 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceWin32.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceWin32.cpp index 22c405e..5112289 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceWin32.cpp +++ b/libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceWin32.cpp | |||
@@ -1,2068 +1,2068 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | 1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt |
2 | // This file is part of the "Irrlicht Engine". | 2 | // This file is part of the "Irrlicht Engine". |
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | 3 | // For conditions of distribution and use, see copyright notice in irrlicht.h |
4 | 4 | ||
5 | #include "IrrCompileConfig.h" | 5 | #include "IrrCompileConfig.h" |
6 | 6 | ||
7 | #ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ | 7 | #ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ |
8 | 8 | ||
9 | #include "CIrrDeviceWin32.h" | 9 | #include "CIrrDeviceWin32.h" |
10 | #include "IEventReceiver.h" | 10 | #include "IEventReceiver.h" |
11 | #include "irrList.h" | 11 | #include "irrList.h" |
12 | #include "os.h" | 12 | #include "os.h" |
13 | 13 | ||
14 | #include "CTimer.h" | 14 | #include "CTimer.h" |
15 | #include "irrString.h" | 15 | #include "irrString.h" |
16 | #include "COSOperator.h" | 16 | #include "COSOperator.h" |
17 | #include "dimension2d.h" | 17 | #include "dimension2d.h" |
18 | #include "IGUISpriteBank.h" | 18 | #include "IGUISpriteBank.h" |
19 | #include <winuser.h> | 19 | #include <winuser.h> |
20 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) | 20 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) |
21 | #ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ | 21 | #ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ |
22 | #define DIRECTINPUT_VERSION 0x0800 | 22 | #define DIRECTINPUT_VERSION 0x0800 |
23 | #include <dinput.h> | 23 | #include <dinput.h> |
24 | #ifdef _MSC_VER | 24 | #ifdef _MSC_VER |
25 | #pragma comment(lib, "dinput8.lib") | 25 | #pragma comment(lib, "dinput8.lib") |
26 | #pragma comment(lib, "dxguid.lib") | 26 | #pragma comment(lib, "dxguid.lib") |
27 | #endif | 27 | #endif |
28 | #else | 28 | #else |
29 | #ifdef _MSC_VER | 29 | #ifdef _MSC_VER |
30 | #pragma comment(lib, "winmm.lib") | 30 | #pragma comment(lib, "winmm.lib") |
31 | #endif | 31 | #endif |
32 | #endif | 32 | #endif |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | namespace irr | 35 | namespace irr |
36 | { | 36 | { |
37 | namespace video | 37 | namespace video |
38 | { | 38 | { |
39 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ | 39 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ |
40 | IVideoDriver* createDirectX8Driver(const irr::SIrrlichtCreationParameters& params, | 40 | IVideoDriver* createDirectX8Driver(const irr::SIrrlichtCreationParameters& params, |
41 | io::IFileSystem* io, HWND window); | 41 | io::IFileSystem* io, HWND window); |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ | 44 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ |
45 | IVideoDriver* createDirectX9Driver(const irr::SIrrlichtCreationParameters& params, | 45 | IVideoDriver* createDirectX9Driver(const irr::SIrrlichtCreationParameters& params, |
46 | io::IFileSystem* io, HWND window); | 46 | io::IFileSystem* io, HWND window); |
47 | #endif | 47 | #endif |
48 | 48 | ||
49 | #ifdef _IRR_COMPILE_WITH_OPENGL_ | 49 | #ifdef _IRR_COMPILE_WITH_OPENGL_ |
50 | IVideoDriver* createOpenGLDriver(const irr::SIrrlichtCreationParameters& params, | 50 | IVideoDriver* createOpenGLDriver(const irr::SIrrlichtCreationParameters& params, |
51 | io::IFileSystem* io, CIrrDeviceWin32* device); | 51 | io::IFileSystem* io, CIrrDeviceWin32* device); |
52 | #endif | 52 | #endif |
53 | } | 53 | } |
54 | } // end namespace irr | 54 | } // end namespace irr |
55 | 55 | ||
56 | namespace irr | 56 | namespace irr |
57 | { | 57 | { |
58 | struct SJoystickWin32Control | 58 | struct SJoystickWin32Control |
59 | { | 59 | { |
60 | CIrrDeviceWin32* Device; | 60 | CIrrDeviceWin32* Device; |
61 | 61 | ||
62 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) | 62 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) |
63 | IDirectInput8* DirectInputDevice; | 63 | IDirectInput8* DirectInputDevice; |
64 | #endif | 64 | #endif |
65 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) | 65 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) |
66 | struct JoystickInfo | 66 | struct JoystickInfo |
67 | { | 67 | { |
68 | u32 Index; | 68 | u32 Index; |
69 | #ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ | 69 | #ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ |
70 | core::stringc Name; | 70 | core::stringc Name; |
71 | GUID guid; | 71 | GUID guid; |
72 | LPDIRECTINPUTDEVICE8 lpdijoy; | 72 | LPDIRECTINPUTDEVICE8 lpdijoy; |
73 | DIDEVCAPS devcaps; | 73 | DIDEVCAPS devcaps; |
74 | u8 axisValid[8]; | 74 | u8 axisValid[8]; |
75 | #else | 75 | #else |
76 | JOYCAPS Caps; | 76 | JOYCAPS Caps; |
77 | #endif | 77 | #endif |
78 | }; | 78 | }; |
79 | core::array<JoystickInfo> ActiveJoysticks; | 79 | core::array<JoystickInfo> ActiveJoysticks; |
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | SJoystickWin32Control(CIrrDeviceWin32* dev) : Device(dev) | 82 | SJoystickWin32Control(CIrrDeviceWin32* dev) : Device(dev) |
83 | { | 83 | { |
84 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) | 84 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) |
85 | DirectInputDevice=0; | 85 | DirectInputDevice=0; |
86 | if (DI_OK != (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&DirectInputDevice, NULL))) | 86 | if (DI_OK != (DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&DirectInputDevice, NULL))) |
87 | { | 87 | { |
88 | os::Printer::log("Could not create DirectInput8 Object", ELL_WARNING); | 88 | os::Printer::log("Could not create DirectInput8 Object", ELL_WARNING); |
89 | return; | 89 | return; |
90 | } | 90 | } |
91 | #endif | 91 | #endif |
92 | } | 92 | } |
93 | ~SJoystickWin32Control() | 93 | ~SJoystickWin32Control() |
94 | { | 94 | { |
95 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) | 95 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) |
96 | for(u32 joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) | 96 | for(u32 joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) |
97 | { | 97 | { |
98 | LPDIRECTINPUTDEVICE8 dev = ActiveJoysticks[joystick].lpdijoy; | 98 | LPDIRECTINPUTDEVICE8 dev = ActiveJoysticks[joystick].lpdijoy; |
99 | if (dev) | 99 | if (dev) |
100 | { | 100 | { |
101 | dev->Unacquire(); | 101 | dev->Unacquire(); |
102 | } | 102 | } |
103 | dev->Release(); | 103 | dev->Release(); |
104 | } | 104 | } |
105 | 105 | ||
106 | if (DirectInputDevice) | 106 | if (DirectInputDevice) |
107 | DirectInputDevice->Release(); | 107 | DirectInputDevice->Release(); |
108 | #endif | 108 | #endif |
109 | } | 109 | } |
110 | 110 | ||
111 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) | 111 | #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) && defined(_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_) |
112 | static BOOL CALLBACK EnumJoysticks(LPCDIDEVICEINSTANCE lpddi, LPVOID cp) | 112 | static BOOL CALLBACK EnumJoysticks(LPCDIDEVICEINSTANCE lpddi, LPVOID cp) |
113 | { | 113 | { |
114 | SJoystickWin32Control* p=(SJoystickWin32Control*)cp; | 114 | SJoystickWin32Control* p=(SJoystickWin32Control*)cp; |
115 | p->directInputAddJoystick(lpddi); | 115 | p->directInputAddJoystick(lpddi); |
116 | return DIENUM_CONTINUE; | 116 | return DIENUM_CONTINUE; |
117 | } | 117 | } |
118 | void directInputAddJoystick(LPCDIDEVICEINSTANCE lpddi) | 118 | void directInputAddJoystick(LPCDIDEVICEINSTANCE lpddi) |
119 | { | 119 | { |
120 | //Get the GUID of the joystuck | 120 | //Get the GUID of the joystuck |
121 | const GUID guid = lpddi->guidInstance; | 121 | const GUID guid = lpddi->guidInstance; |
122 | 122 | ||
123 | JoystickInfo activeJoystick; | 123 | JoystickInfo activeJoystick; |
124 | activeJoystick.Index=ActiveJoysticks.size(); | 124 | activeJoystick.Index=ActiveJoysticks.size(); |
125 | activeJoystick.guid=guid; | 125 | activeJoystick.guid=guid; |
126 | activeJoystick.Name=lpddi->tszProductName; | 126 | activeJoystick.Name=lpddi->tszProductName; |
127 | if (FAILED(DirectInputDevice->CreateDevice(guid, &activeJoystick.lpdijoy, NULL))) | 127 | if (FAILED(DirectInputDevice->CreateDevice(guid, &activeJoystick.lpdijoy, NULL))) |
128 | { | 128 | { |
129 | os::Printer::log("Could not create DirectInput device", ELL_WARNING); | 129 | os::Printer::log("Could not create DirectInput device", ELL_WARNING); |
130 | return; | 130 | return; |
131 | } | 131 | } |
132 | 132 | ||
133 | activeJoystick.devcaps.dwSize=sizeof(activeJoystick.devcaps); | 133 | activeJoystick.devcaps.dwSize=sizeof(activeJoystick.devcaps); |
134 | if (FAILED(activeJoystick.lpdijoy->GetCapabilities(&activeJoystick.devcaps))) | 134 | if (FAILED(activeJoystick.lpdijoy->GetCapabilities(&activeJoystick.devcaps))) |
135 | { | 135 | { |
136 | os::Printer::log("Could not create DirectInput device", ELL_WARNING); | 136 | os::Printer::log("Could not create DirectInput device", ELL_WARNING); |
137 | return; | 137 | return; |
138 | } | 138 | } |
139 | 139 | ||
140 | if (FAILED(activeJoystick.lpdijoy->SetCooperativeLevel(Device->HWnd, DISCL_BACKGROUND | DISCL_EXCLUSIVE))) | 140 | if (FAILED(activeJoystick.lpdijoy->SetCooperativeLevel(Device->HWnd, DISCL_BACKGROUND | DISCL_EXCLUSIVE))) |
141 | { | 141 | { |
142 | os::Printer::log("Could not set DirectInput device cooperative level", ELL_WARNING); | 142 | os::Printer::log("Could not set DirectInput device cooperative level", ELL_WARNING); |
143 | return; | 143 | return; |
144 | } | 144 | } |
145 | 145 | ||
146 | if (FAILED(activeJoystick.lpdijoy->SetDataFormat(&c_dfDIJoystick2))) | 146 | if (FAILED(activeJoystick.lpdijoy->SetDataFormat(&c_dfDIJoystick2))) |
147 | { | 147 | { |
148 | os::Printer::log("Could not set DirectInput device data format", ELL_WARNING); | 148 | os::Printer::log("Could not set DirectInput device data format", ELL_WARNING); |
149 | return; | 149 | return; |
150 | } | 150 | } |
151 | 151 | ||
152 | if (FAILED(activeJoystick.lpdijoy->Acquire())) | 152 | if (FAILED(activeJoystick.lpdijoy->Acquire())) |
153 | { | 153 | { |
154 | os::Printer::log("Could not set DirectInput cooperative level", ELL_WARNING); | 154 | os::Printer::log("Could not set DirectInput cooperative level", ELL_WARNING); |
155 | return; | 155 | return; |
156 | } | 156 | } |
157 | 157 | ||
158 | DIJOYSTATE2 info; | 158 | DIJOYSTATE2 info; |
159 | if (FAILED(activeJoystick.lpdijoy->GetDeviceState(sizeof(info),&info))) | 159 | if (FAILED(activeJoystick.lpdijoy->GetDeviceState(sizeof(info),&info))) |
160 | { | 160 | { |
161 | os::Printer::log("Could not read DirectInput device state", ELL_WARNING); | 161 | os::Printer::log("Could not read DirectInput device state", ELL_WARNING); |
162 | return; | 162 | return; |
163 | } | 163 | } |
164 | 164 | ||
165 | ZeroMemory(activeJoystick.axisValid,sizeof(activeJoystick.axisValid)); | 165 | ZeroMemory(activeJoystick.axisValid,sizeof(activeJoystick.axisValid)); |
166 | activeJoystick.axisValid[0]= (info.lX!=0) ? 1 : 0; | 166 | activeJoystick.axisValid[0]= (info.lX!=0) ? 1 : 0; |
167 | activeJoystick.axisValid[1]= (info.lY!=0) ? 1 : 0; | 167 | activeJoystick.axisValid[1]= (info.lY!=0) ? 1 : 0; |
168 | activeJoystick.axisValid[2]= (info.lZ!=0) ? 1 : 0; | 168 | activeJoystick.axisValid[2]= (info.lZ!=0) ? 1 : 0; |
169 | activeJoystick.axisValid[3]= (info.lRx!=0) ? 1 : 0; | 169 | activeJoystick.axisValid[3]= (info.lRx!=0) ? 1 : 0; |
170 | activeJoystick.axisValid[4]= (info.lRy!=0) ? 1 : 0; | 170 | activeJoystick.axisValid[4]= (info.lRy!=0) ? 1 : 0; |
171 | activeJoystick.axisValid[5]= (info.lRz!=0) ? 1 : 0; | 171 | activeJoystick.axisValid[5]= (info.lRz!=0) ? 1 : 0; |
172 | 172 | ||
173 | int caxis=0; | 173 | int caxis=0; |
174 | for (u8 i=0; i<6; i++) | 174 | for (u8 i=0; i<6; i++) |
175 | { | 175 | { |
176 | if (activeJoystick.axisValid[i]) | 176 | if (activeJoystick.axisValid[i]) |
177 | caxis++; | 177 | caxis++; |
178 | } | 178 | } |
179 | 179 | ||
180 | for (u8 i=0; i<(activeJoystick.devcaps.dwAxes)-caxis; i++) | 180 | for (u8 i=0; i<(activeJoystick.devcaps.dwAxes)-caxis; i++) |
181 | { | 181 | { |
182 | if (i+caxis < 8) | 182 | if (i+caxis < 8) |
183 | activeJoystick.axisValid[i+caxis]=1; | 183 | activeJoystick.axisValid[i+caxis]=1; |
184 | } | 184 | } |
185 | 185 | ||
186 | ActiveJoysticks.push_back(activeJoystick); | 186 | ActiveJoysticks.push_back(activeJoystick); |
187 | } | 187 | } |
188 | #endif | 188 | #endif |
189 | 189 | ||
190 | void pollJoysticks() | 190 | void pollJoysticks() |
191 | { | 191 | { |
192 | #if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ | 192 | #if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ |
193 | #ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ | 193 | #ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ |
194 | if(0 == ActiveJoysticks.size()) | 194 | if(0 == ActiveJoysticks.size()) |
195 | return; | 195 | return; |
196 | 196 | ||
197 | u32 joystick; | 197 | u32 joystick; |
198 | DIJOYSTATE2 info; | 198 | DIJOYSTATE2 info; |
199 | 199 | ||
200 | for(joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) | 200 | for(joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) |
201 | { | 201 | { |
202 | // needs to be reset for each joystick | 202 | // needs to be reset for each joystick |
203 | // request ALL values and POV as continuous if possible | 203 | // request ALL values and POV as continuous if possible |
204 | 204 | ||
205 | const DIDEVCAPS & caps = ActiveJoysticks[joystick].devcaps; | 205 | const DIDEVCAPS & caps = ActiveJoysticks[joystick].devcaps; |
206 | // if no POV is available don't ask for POV values | 206 | // if no POV is available don't ask for POV values |
207 | 207 | ||
208 | if (!FAILED(ActiveJoysticks[joystick].lpdijoy->GetDeviceState(sizeof(info),&info))) | 208 | if (!FAILED(ActiveJoysticks[joystick].lpdijoy->GetDeviceState(sizeof(info),&info))) |
209 | { | 209 | { |
210 | SEvent event; | 210 | SEvent event; |
211 | 211 | ||
212 | event.EventType = irr::EET_JOYSTICK_INPUT_EVENT; | 212 | event.EventType = irr::EET_JOYSTICK_INPUT_EVENT; |
213 | event.JoystickEvent.Joystick = (u8)joystick; | 213 | event.JoystickEvent.Joystick = (u8)joystick; |
214 | 214 | ||
215 | event.JoystickEvent.POV = (u16)info.rgdwPOV[0]; | 215 | event.JoystickEvent.POV = (u16)info.rgdwPOV[0]; |
216 | // set to undefined if no POV value was returned or the value | 216 | // set to undefined if no POV value was returned or the value |
217 | // is out of range | 217 | // is out of range |
218 | if ((caps.dwPOVs==0) || (event.JoystickEvent.POV > 35900)) | 218 | if ((caps.dwPOVs==0) || (event.JoystickEvent.POV > 35900)) |
219 | event.JoystickEvent.POV = 65535; | 219 | event.JoystickEvent.POV = 65535; |
220 | 220 | ||
221 | for(int axis = 0; axis < SEvent::SJoystickEvent::NUMBER_OF_AXES; ++axis) | 221 | for(int axis = 0; axis < SEvent::SJoystickEvent::NUMBER_OF_AXES; ++axis) |
222 | event.JoystickEvent.Axis[axis] = 0; | 222 | event.JoystickEvent.Axis[axis] = 0; |
223 | 223 | ||
224 | u16 dxAxis=0; | 224 | u16 dxAxis=0; |
225 | u16 irrAxis=0; | 225 | u16 irrAxis=0; |
226 | 226 | ||
227 | while (dxAxis < 6 && irrAxis <caps.dwAxes) | 227 | while (dxAxis < 6 && irrAxis <caps.dwAxes) |
228 | { | 228 | { |
229 | bool axisFound=0; | 229 | bool axisFound=0; |
230 | s32 axisValue=0; | 230 | s32 axisValue=0; |
231 | 231 | ||
232 | switch (dxAxis) | 232 | switch (dxAxis) |
233 | { | 233 | { |
234 | case 0: | 234 | case 0: |
235 | axisValue=info.lX; | 235 | axisValue=info.lX; |
236 | break; | 236 | break; |
237 | case 1: | 237 | case 1: |
238 | axisValue=info.lY; | 238 | axisValue=info.lY; |
239 | break; | 239 | break; |
240 | case 2: | 240 | case 2: |
241 | axisValue=info.lZ; | 241 | axisValue=info.lZ; |
242 | break; | 242 | break; |
243 | case 3: | 243 | case 3: |
244 | axisValue=info.lRx; | 244 | axisValue=info.lRx; |
245 | break; | 245 | break; |
246 | case 4: | 246 | case 4: |
247 | axisValue=info.lRy; | 247 | axisValue=info.lRy; |
248 | break; | 248 | break; |
249 | case 5: | 249 | case 5: |
250 | axisValue=info.lRz; | 250 | axisValue=info.lRz; |
251 | break; | 251 | break; |
252 | case 6: | 252 | case 6: |
253 | axisValue=info.rglSlider[0]; | 253 | axisValue=info.rglSlider[0]; |
254 | break; | 254 | break; |
255 | case 7: | 255 | case 7: |
256 | axisValue=info.rglSlider[1]; | 256 | axisValue=info.rglSlider[1]; |
257 | break; | 257 | break; |
258 | default: | 258 | default: |
259 | break; | 259 | break; |
260 | } | 260 | } |
261 | 261 | ||
262 | if (ActiveJoysticks[joystick].axisValid[dxAxis]>0) | 262 | if (ActiveJoysticks[joystick].axisValid[dxAxis]>0) |
263 | axisFound=1; | 263 | axisFound=1; |
264 | 264 | ||
265 | if (axisFound) | 265 | if (axisFound) |
266 | { | 266 | { |
267 | s32 val=axisValue - 32768; | 267 | s32 val=axisValue - 32768; |
268 | 268 | ||
269 | if (val <-32767) val=-32767; | 269 | if (val <-32767) val=-32767; |
270 | if (val > 32767) val=32767; | 270 | if (val > 32767) val=32767; |
271 | event.JoystickEvent.Axis[irrAxis]=(s16)(val); | 271 | event.JoystickEvent.Axis[irrAxis]=(s16)(val); |
272 | irrAxis++; | 272 | irrAxis++; |
273 | } | 273 | } |
274 | 274 | ||
275 | dxAxis++; | 275 | dxAxis++; |
276 | } | 276 | } |
277 | 277 | ||
278 | u32 buttons=0; | 278 | u32 buttons=0; |
279 | BYTE* bytebuttons=info.rgbButtons; | 279 | BYTE* bytebuttons=info.rgbButtons; |
280 | for (u16 i=0; i<32; i++) | 280 | for (u16 i=0; i<32; i++) |
281 | { | 281 | { |
282 | if (bytebuttons[i] >0) | 282 | if (bytebuttons[i] >0) |
283 | { | 283 | { |
284 | buttons |= (1 << i); | 284 | buttons |= (1 << i); |
285 | } | 285 | } |
286 | } | 286 | } |
287 | event.JoystickEvent.ButtonStates = buttons; | 287 | event.JoystickEvent.ButtonStates = buttons; |
288 | 288 | ||
289 | (void)Device->postEventFromUser(event); | 289 | (void)Device->postEventFromUser(event); |
290 | } | 290 | } |
291 | } | 291 | } |
292 | #else | 292 | #else |
293 | if (0 == ActiveJoysticks.size()) | 293 | if (0 == ActiveJoysticks.size()) |
294 | return; | 294 | return; |
295 | 295 | ||
296 | u32 joystick; | 296 | u32 joystick; |
297 | JOYINFOEX info; | 297 | JOYINFOEX info; |
298 | 298 | ||
299 | for(joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) | 299 | for(joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) |
300 | { | 300 | { |
301 | // needs to be reset for each joystick | 301 | // needs to be reset for each joystick |
302 | // request ALL values and POV as continuous if possible | 302 | // request ALL values and POV as continuous if possible |
303 | info.dwSize = sizeof(info); | 303 | info.dwSize = sizeof(info); |
304 | info.dwFlags = JOY_RETURNALL|JOY_RETURNPOVCTS; | 304 | info.dwFlags = JOY_RETURNALL|JOY_RETURNPOVCTS; |
305 | const JOYCAPS & caps = ActiveJoysticks[joystick].Caps; | 305 | const JOYCAPS & caps = ActiveJoysticks[joystick].Caps; |
306 | // if no POV is available don't ask for POV values | 306 | // if no POV is available don't ask for POV values |
307 | if (!(caps.wCaps & JOYCAPS_HASPOV)) | 307 | if (!(caps.wCaps & JOYCAPS_HASPOV)) |
308 | info.dwFlags &= ~(JOY_RETURNPOV|JOY_RETURNPOVCTS); | 308 | info.dwFlags &= ~(JOY_RETURNPOV|JOY_RETURNPOVCTS); |
309 | if(JOYERR_NOERROR == joyGetPosEx(ActiveJoysticks[joystick].Index, &info)) | 309 | if(JOYERR_NOERROR == joyGetPosEx(ActiveJoysticks[joystick].Index, &info)) |
310 | { | 310 | { |
311 | SEvent event; | 311 | SEvent event; |
312 | 312 | ||
313 | event.EventType = irr::EET_JOYSTICK_INPUT_EVENT; | 313 | event.EventType = irr::EET_JOYSTICK_INPUT_EVENT; |
314 | event.JoystickEvent.Joystick = (u8)joystick; | 314 | event.JoystickEvent.Joystick = (u8)joystick; |
315 | 315 | ||
316 | event.JoystickEvent.POV = (u16)info.dwPOV; | 316 | event.JoystickEvent.POV = (u16)info.dwPOV; |
317 | // set to undefined if no POV value was returned or the value | 317 | // set to undefined if no POV value was returned or the value |
318 | // is out of range | 318 | // is out of range |
319 | if (!(info.dwFlags & JOY_RETURNPOV) || (event.JoystickEvent.POV > 35900)) | 319 | if (!(info.dwFlags & JOY_RETURNPOV) || (event.JoystickEvent.POV > 35900)) |
320 | event.JoystickEvent.POV = 65535; | 320 | event.JoystickEvent.POV = 65535; |
321 | 321 | ||
322 | for(int axis = 0; axis < SEvent::SJoystickEvent::NUMBER_OF_AXES; ++axis) | 322 | for(int axis = 0; axis < SEvent::SJoystickEvent::NUMBER_OF_AXES; ++axis) |
323 | event.JoystickEvent.Axis[axis] = 0; | 323 | event.JoystickEvent.Axis[axis] = 0; |
324 | 324 | ||
325 | event.JoystickEvent.ButtonStates = info.dwButtons; | 325 | event.JoystickEvent.ButtonStates = info.dwButtons; |
326 | 326 | ||
327 | switch(caps.wNumAxes) | 327 | switch(caps.wNumAxes) |
328 | { | 328 | { |
329 | default: | 329 | default: |
330 | case 6: | 330 | case 6: |
331 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_V] = | 331 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_V] = |
332 | (s16)((65535 * (info.dwVpos - caps.wVmin)) / (caps.wVmax - caps.wVmin) - 32768); | 332 | (s16)((65535 * (info.dwVpos - caps.wVmin)) / (caps.wVmax - caps.wVmin) - 32768); |
333 | 333 | ||
334 | case 5: | 334 | case 5: |
335 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_U] = | 335 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_U] = |
336 | (s16)((65535 * (info.dwUpos - caps.wUmin)) / (caps.wUmax - caps.wUmin) - 32768); | 336 | (s16)((65535 * (info.dwUpos - caps.wUmin)) / (caps.wUmax - caps.wUmin) - 32768); |
337 | 337 | ||
338 | case 4: | 338 | case 4: |
339 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_R] = | 339 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_R] = |
340 | (s16)((65535 * (info.dwRpos - caps.wRmin)) / (caps.wRmax - caps.wRmin) - 32768); | 340 | (s16)((65535 * (info.dwRpos - caps.wRmin)) / (caps.wRmax - caps.wRmin) - 32768); |
341 | 341 | ||
342 | case 3: | 342 | case 3: |
343 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_Z] = | 343 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_Z] = |
344 | (s16)((65535 * (info.dwZpos - caps.wZmin)) / (caps.wZmax - caps.wZmin) - 32768); | 344 | (s16)((65535 * (info.dwZpos - caps.wZmin)) / (caps.wZmax - caps.wZmin) - 32768); |
345 | 345 | ||
346 | case 2: | 346 | case 2: |
347 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_Y] = | 347 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_Y] = |
348 | (s16)((65535 * (info.dwYpos - caps.wYmin)) / (caps.wYmax - caps.wYmin) - 32768); | 348 | (s16)((65535 * (info.dwYpos - caps.wYmin)) / (caps.wYmax - caps.wYmin) - 32768); |
349 | 349 | ||
350 | case 1: | 350 | case 1: |
351 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_X] = | 351 | event.JoystickEvent.Axis[SEvent::SJoystickEvent::AXIS_X] = |
352 | (s16)((65535 * (info.dwXpos - caps.wXmin)) / (caps.wXmax - caps.wXmin) - 32768); | 352 | (s16)((65535 * (info.dwXpos - caps.wXmin)) / (caps.wXmax - caps.wXmin) - 32768); |
353 | } | 353 | } |
354 | 354 | ||
355 | (void)Device->postEventFromUser(event); | 355 | (void)Device->postEventFromUser(event); |
356 | } | 356 | } |
357 | } | 357 | } |
358 | #endif | 358 | #endif |
359 | #endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ | 359 | #endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ |
360 | } | 360 | } |
361 | 361 | ||
362 | bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) | 362 | bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) |
363 | { | 363 | { |
364 | #if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ | 364 | #if defined _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ |
365 | #ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ | 365 | #ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ |
366 | if (!DirectInputDevice || (DirectInputDevice->EnumDevices(DI8DEVCLASS_GAMECTRL, SJoystickWin32Control::EnumJoysticks, this, DIEDFL_ATTACHEDONLY ))) | 366 | if (!DirectInputDevice || (DirectInputDevice->EnumDevices(DI8DEVCLASS_GAMECTRL, SJoystickWin32Control::EnumJoysticks, this, DIEDFL_ATTACHEDONLY ))) |
367 | { | 367 | { |
368 | os::Printer::log("Could not enum DirectInput8 controllers", ELL_WARNING); | 368 | os::Printer::log("Could not enum DirectInput8 controllers", ELL_WARNING); |
369 | return false; | 369 | return false; |
370 | } | 370 | } |
371 | 371 | ||
372 | for(u32 joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) | 372 | for(u32 joystick = 0; joystick < ActiveJoysticks.size(); ++joystick) |
373 | { | 373 | { |
374 | JoystickInfo& activeJoystick = ActiveJoysticks[joystick]; | 374 | JoystickInfo& activeJoystick = ActiveJoysticks[joystick]; |
375 | SJoystickInfo info; | 375 | SJoystickInfo info; |
376 | info.Axes=activeJoystick.devcaps.dwAxes; | 376 | info.Axes=activeJoystick.devcaps.dwAxes; |
377 | info.Buttons=activeJoystick.devcaps.dwButtons; | 377 | info.Buttons=activeJoystick.devcaps.dwButtons; |
378 | info.Name=activeJoystick.Name; | 378 | info.Name=activeJoystick.Name; |
379 | info.PovHat = (activeJoystick.devcaps.dwPOVs != 0) | 379 | info.PovHat = (activeJoystick.devcaps.dwPOVs != 0) |
380 | ? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT; | 380 | ? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT; |
381 | joystickInfo.push_back(info); | 381 | joystickInfo.push_back(info); |
382 | } | 382 | } |
383 | return true; | 383 | return true; |
384 | #else | 384 | #else |
385 | joystickInfo.clear(); | 385 | joystickInfo.clear(); |
386 | ActiveJoysticks.clear(); | 386 | ActiveJoysticks.clear(); |
387 | 387 | ||
388 | const u32 numberOfJoysticks = ::joyGetNumDevs(); | 388 | const u32 numberOfJoysticks = ::joyGetNumDevs(); |
389 | JOYINFOEX info; | 389 | JOYINFOEX info; |
390 | info.dwSize = sizeof(info); | 390 | info.dwSize = sizeof(info); |
391 | info.dwFlags = JOY_RETURNALL; | 391 | info.dwFlags = JOY_RETURNALL; |
392 | 392 | ||
393 | JoystickInfo activeJoystick; | 393 | JoystickInfo activeJoystick; |
394 | SJoystickInfo returnInfo; | 394 | SJoystickInfo returnInfo; |
395 | 395 | ||
396 | joystickInfo.reallocate(numberOfJoysticks); | 396 | joystickInfo.reallocate(numberOfJoysticks); |
397 | ActiveJoysticks.reallocate(numberOfJoysticks); | 397 | ActiveJoysticks.reallocate(numberOfJoysticks); |
398 | 398 | ||
399 | u32 joystick = 0; | 399 | u32 joystick = 0; |
400 | for(; joystick < numberOfJoysticks; ++joystick) | 400 | for(; joystick < numberOfJoysticks; ++joystick) |
401 | { | 401 | { |
402 | if(JOYERR_NOERROR == joyGetPosEx(joystick, &info) | 402 | if(JOYERR_NOERROR == joyGetPosEx(joystick, &info) |
403 | && | 403 | && |
404 | JOYERR_NOERROR == joyGetDevCaps(joystick, | 404 | JOYERR_NOERROR == joyGetDevCaps(joystick, |
405 | &activeJoystick.Caps, | 405 | &activeJoystick.Caps, |
406 | sizeof(activeJoystick.Caps))) | 406 | sizeof(activeJoystick.Caps))) |
407 | { | 407 | { |
408 | activeJoystick.Index = joystick; | 408 | activeJoystick.Index = joystick; |
409 | ActiveJoysticks.push_back(activeJoystick); | 409 | ActiveJoysticks.push_back(activeJoystick); |
410 | 410 | ||
411 | returnInfo.Joystick = (u8)joystick; | 411 | returnInfo.Joystick = (u8)joystick; |
412 | returnInfo.Axes = activeJoystick.Caps.wNumAxes; | 412 | returnInfo.Axes = activeJoystick.Caps.wNumAxes; |
413 | returnInfo.Buttons = activeJoystick.Caps.wNumButtons; | 413 | returnInfo.Buttons = activeJoystick.Caps.wNumButtons; |
414 | returnInfo.Name = activeJoystick.Caps.szPname; | 414 | returnInfo.Name = activeJoystick.Caps.szPname; |
415 | returnInfo.PovHat = ((activeJoystick.Caps.wCaps & JOYCAPS_HASPOV) == JOYCAPS_HASPOV) | 415 | returnInfo.PovHat = ((activeJoystick.Caps.wCaps & JOYCAPS_HASPOV) == JOYCAPS_HASPOV) |
416 | ? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT; | 416 | ? SJoystickInfo::POV_HAT_PRESENT : SJoystickInfo::POV_HAT_ABSENT; |
417 | 417 | ||
418 | joystickInfo.push_back(returnInfo); | 418 | joystickInfo.push_back(returnInfo); |
419 | } | 419 | } |
420 | } | 420 | } |
421 | 421 | ||
422 | for(joystick = 0; joystick < joystickInfo.size(); ++joystick) | 422 | for(joystick = 0; joystick < joystickInfo.size(); ++joystick) |
423 | { | 423 | { |
424 | char logString[256]; | 424 | char logString[256]; |
425 | (void)sprintf(logString, "Found joystick %d, %d axes, %d buttons '%s'", | 425 | (void)sprintf(logString, "Found joystick %d, %d axes, %d buttons '%s'", |
426 | joystick, joystickInfo[joystick].Axes, | 426 | joystick, joystickInfo[joystick].Axes, |
427 | joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str()); | 427 | joystickInfo[joystick].Buttons, joystickInfo[joystick].Name.c_str()); |
428 | os::Printer::log(logString, ELL_INFORMATION); | 428 | os::Printer::log(logString, ELL_INFORMATION); |
429 | } | 429 | } |
430 | 430 | ||
431 | return true; | 431 | return true; |
432 | #endif | 432 | #endif |
433 | #else | 433 | #else |
434 | return false; | 434 | return false; |
435 | #endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ | 435 | #endif // _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ |
436 | } | 436 | } |
437 | }; | 437 | }; |
438 | } // end namespace irr | 438 | } // end namespace irr |
439 | 439 | ||
440 | // Get the codepage from the locale language id | 440 | // Get the codepage from the locale language id |
441 | // Based on the table from http://www.science.co.il/Language/Locale-Codes.asp?s=decimal | 441 | // Based on the table from http://www.science.co.il/Language/Locale-Codes.asp?s=decimal |
442 | static unsigned int LocaleIdToCodepage(unsigned int lcid) | 442 | static unsigned int LocaleIdToCodepage(unsigned int lcid) |
443 | { | 443 | { |
444 | switch ( lcid ) | 444 | switch ( lcid ) |
445 | { | 445 | { |
446 | case 1098: // Telugu | 446 | case 1098: // Telugu |
447 | case 1095: // Gujarati | 447 | case 1095: // Gujarati |
448 | case 1094: // Punjabi | 448 | case 1094: // Punjabi |
449 | case 1103: // Sanskrit | 449 | case 1103: // Sanskrit |
450 | case 1111: // Konkani | 450 | case 1111: // Konkani |
451 | case 1114: // Syriac | 451 | case 1114: // Syriac |
452 | case 1099: // Kannada | 452 | case 1099: // Kannada |
453 | case 1102: // Marathi | 453 | case 1102: // Marathi |
454 | case 1125: // Divehi | 454 | case 1125: // Divehi |
455 | case 1067: // Armenian | 455 | case 1067: // Armenian |
456 | case 1081: // Hindi | 456 | case 1081: // Hindi |
457 | case 1079: // Georgian | 457 | case 1079: // Georgian |
458 | case 1097: // Tamil | 458 | case 1097: // Tamil |
459 | return 0; | 459 | return 0; |
460 | case 1054: // Thai | 460 | case 1054: // Thai |
461 | return 874; | 461 | return 874; |
462 | case 1041: // Japanese | 462 | case 1041: // Japanese |
463 | return 932; | 463 | return 932; |
464 | case 2052: // Chinese (PRC) | 464 | case 2052: // Chinese (PRC) |
465 | case 4100: // Chinese (Singapore) | 465 | case 4100: // Chinese (Singapore) |
466 | return 936; | 466 | return 936; |
467 | case 1042: // Korean | 467 | case 1042: // Korean |
468 | return 949; | 468 | return 949; |
469 | case 5124: // Chinese (Macau S.A.R.) | 469 | case 5124: // Chinese (Macau S.A.R.) |
470 | case 3076: // Chinese (Hong Kong S.A.R.) | 470 | case 3076: // Chinese (Hong Kong S.A.R.) |
471 | case 1028: // Chinese (Taiwan) | 471 | case 1028: // Chinese (Taiwan) |
472 | return 950; | 472 | return 950; |
473 | case 1048: // Romanian | 473 | case 1048: // Romanian |
474 | case 1060: // Slovenian | 474 | case 1060: // Slovenian |
475 | case 1038: // Hungarian | 475 | case 1038: // Hungarian |
476 | case 1051: // Slovak | 476 | case 1051: // Slovak |
477 | case 1045: // Polish | 477 | case 1045: // Polish |
478 | case 1052: // Albanian | 478 | case 1052: // Albanian |
479 | case 2074: // Serbian (Latin) | 479 | case 2074: // Serbian (Latin) |
480 | case 1050: // Croatian | 480 | case 1050: // Croatian |
481 | case 1029: // Czech | 481 | case 1029: // Czech |
482 | return 1250; | 482 | return 1250; |
483 | case 1104: // Mongolian (Cyrillic) | 483 | case 1104: // Mongolian (Cyrillic) |
484 | case 1071: // FYRO Macedonian | 484 | case 1071: // FYRO Macedonian |
485 | case 2115: // Uzbek (Cyrillic) | 485 | case 2115: // Uzbek (Cyrillic) |
486 | case 1058: // Ukrainian | 486 | case 1058: // Ukrainian |
487 | case 2092: // Azeri (Cyrillic) | 487 | case 2092: // Azeri (Cyrillic) |
488 | case 1092: // Tatar | 488 | case 1092: // Tatar |
489 | case 1087: // Kazakh | 489 | case 1087: // Kazakh |
490 | case 1059: // Belarusian | 490 | case 1059: // Belarusian |
491 | case 1088: // Kyrgyz (Cyrillic) | 491 | case 1088: // Kyrgyz (Cyrillic) |
492 | case 1026: // Bulgarian | 492 | case 1026: // Bulgarian |
493 | case 3098: // Serbian (Cyrillic) | 493 | case 3098: // Serbian (Cyrillic) |
494 | case 1049: // Russian | 494 | case 1049: // Russian |
495 | return 1251; | 495 | return 1251; |
496 | case 8201: // English (Jamaica) | 496 | case 8201: // English (Jamaica) |
497 | case 3084: // French (Canada) | 497 | case 3084: // French (Canada) |
498 | case 1036: // French (France) | 498 | case 1036: // French (France) |
499 | case 5132: // French (Luxembourg) | 499 | case 5132: // French (Luxembourg) |
500 | case 5129: // English (New Zealand) | 500 | case 5129: // English (New Zealand) |
501 | case 6153: // English (Ireland) | 501 | case 6153: // English (Ireland) |
502 | case 1043: // Dutch (Netherlands) | 502 | case 1043: // Dutch (Netherlands) |
503 | case 9225: // English (Caribbean) | 503 | case 9225: // English (Caribbean) |
504 | case 4108: // French (Switzerland) | 504 | case 4108: // French (Switzerland) |
505 | case 4105: // English (Canada) | 505 | case 4105: // English (Canada) |
506 | case 1110: // Galician | 506 | case 1110: // Galician |
507 | case 10249: // English (Belize) | 507 | case 10249: // English (Belize) |
508 | case 3079: // German (Austria) | 508 | case 3079: // German (Austria) |
509 | case 6156: // French (Monaco) | 509 | case 6156: // French (Monaco) |
510 | case 12297: // English (Zimbabwe) | 510 | case 12297: // English (Zimbabwe) |
511 | case 1069: // Basque | 511 | case 1069: // Basque |
512 | case 2067: // Dutch (Belgium) | 512 | case 2067: // Dutch (Belgium) |
513 | case 2060: // French (Belgium) | 513 | case 2060: // French (Belgium) |
514 | case 1035: // Finnish | 514 | case 1035: // Finnish |
515 | case 1080: // Faroese | 515 | case 1080: // Faroese |
516 | case 1031: // German (Germany) | 516 | case 1031: // German (Germany) |
517 | case 3081: // English (Australia) | 517 | case 3081: // English (Australia) |
518 | case 1033: // English (United States) | 518 | case 1033: // English (United States) |
519 | case 2057: // English (United Kingdom) | 519 | case 2057: // English (United Kingdom) |
520 | case 1027: // Catalan | 520 | case 1027: // Catalan |
521 | case 11273: // English (Trinidad) | 521 | case 11273: // English (Trinidad) |
522 | case 7177: // English (South Africa) | 522 | case 7177: // English (South Africa) |
523 | case 1030: // Danish | 523 | case 1030: // Danish |
524 | case 13321: // English (Philippines) | 524 | case 13321: // English (Philippines) |
525 | case 15370: // Spanish (Paraguay) | 525 | case 15370: // Spanish (Paraguay) |
526 | case 9226: // Spanish (Colombia) | 526 | case 9226: // Spanish (Colombia) |
527 | case 5130: // Spanish (Costa Rica) | 527 | case 5130: // Spanish (Costa Rica) |
528 | case 7178: // Spanish (Dominican Republic) | 528 | case 7178: // Spanish (Dominican Republic) |
529 | case 12298: // Spanish (Ecuador) | 529 | case 12298: // Spanish (Ecuador) |
530 | case 17418: // Spanish (El Salvador) | 530 | case 17418: // Spanish (El Salvador) |
531 | case 4106: // Spanish (Guatemala) | 531 | case 4106: // Spanish (Guatemala) |
532 | case 18442: // Spanish (Honduras) | 532 | case 18442: // Spanish (Honduras) |
533 | case 3082: // Spanish (International Sort) | 533 | case 3082: // Spanish (International Sort) |
534 | case 13322: // Spanish (Chile) | 534 | case 13322: // Spanish (Chile) |
535 | case 19466: // Spanish (Nicaragua) | 535 | case 19466: // Spanish (Nicaragua) |
536 | case 2058: // Spanish (Mexico) | 536 | case 2058: // Spanish (Mexico) |
537 | case 10250: // Spanish (Peru) | 537 | case 10250: // Spanish (Peru) |
538 | case 20490: // Spanish (Puerto Rico) | 538 | case 20490: // Spanish (Puerto Rico) |
539 | case 1034: // Spanish (Traditional Sort) | 539 | case 1034: // Spanish (Traditional Sort) |
540 | case 14346: // Spanish (Uruguay) | 540 | case 14346: // Spanish (Uruguay) |
541 | case 8202: // Spanish (Venezuela) | 541 | case 8202: // Spanish (Venezuela) |
542 | case 1089: // Swahili | 542 | case 1089: // Swahili |
543 | case 1053: // Swedish | 543 | case 1053: // Swedish |
544 | case 2077: // Swedish (Finland) | 544 | case 2077: // Swedish (Finland) |
545 | case 5127: // German (Liechtenstein) | 545 | case 5127: // German (Liechtenstein) |
546 | case 1078: // Afrikaans | 546 | case 1078: // Afrikaans |
547 | case 6154: // Spanish (Panama) | 547 | case 6154: // Spanish (Panama) |
548 | case 4103: // German (Luxembourg) | 548 | case 4103: // German (Luxembourg) |
549 | case 16394: // Spanish (Bolivia) | 549 | case 16394: // Spanish (Bolivia) |
550 | case 2055: // German (Switzerland) | 550 | case 2055: // German (Switzerland) |
551 | case 1039: // Icelandic | 551 | case 1039: // Icelandic |
552 | case 1057: // Indonesian | 552 | case 1057: // Indonesian |
553 | case 1040: // Italian (Italy) | 553 | case 1040: // Italian (Italy) |
554 | case 2064: // Italian (Switzerland) | 554 | case 2064: // Italian (Switzerland) |
555 | case 2068: // Norwegian (Nynorsk) | 555 | case 2068: // Norwegian (Nynorsk) |
556 | case 11274: // Spanish (Argentina) | 556 | case 11274: // Spanish (Argentina) |
557 | case 1046: // Portuguese (Brazil) | 557 | case 1046: // Portuguese (Brazil) |
558 | case 1044: // Norwegian (Bokmal) | 558 | case 1044: // Norwegian (Bokmal) |
559 | case 1086: // Malay (Malaysia) | 559 | case 1086: // Malay (Malaysia) |
560 | case 2110: // Malay (Brunei Darussalam) | 560 | case 2110: // Malay (Brunei Darussalam) |
561 | case 2070: // Portuguese (Portugal) | 561 | case 2070: // Portuguese (Portugal) |
562 | return 1252; | 562 | return 1252; |
563 | case 1032: // Greek | 563 | case 1032: // Greek |
564 | return 1253; | 564 | return 1253; |
565 | case 1091: // Uzbek (Latin) | 565 | case 1091: // Uzbek (Latin) |
566 | case 1068: // Azeri (Latin) | 566 | case 1068: // Azeri (Latin) |
567 | case 1055: // Turkish | 567 | case 1055: // Turkish |
568 | return 1254; | 568 | return 1254; |
569 | case 1037: // Hebrew | 569 | case 1037: // Hebrew |
570 | return 1255; | 570 | return 1255; |
571 | case 5121: // Arabic (Algeria) | 571 | case 5121: // Arabic (Algeria) |
572 | case 15361: // Arabic (Bahrain) | 572 | case 15361: // Arabic (Bahrain) |
573 | case 9217: // Arabic (Yemen) | 573 | case 9217: // Arabic (Yemen) |
574 | case 3073: // Arabic (Egypt) | 574 | case 3073: // Arabic (Egypt) |
575 | case 2049: // Arabic (Iraq) | 575 | case 2049: // Arabic (Iraq) |
576 | case 11265: // Arabic (Jordan) | 576 | case 11265: // Arabic (Jordan) |
577 | case 13313: // Arabic (Kuwait) | 577 | case 13313: // Arabic (Kuwait) |
578 | case 12289: // Arabic (Lebanon) | 578 | case 12289: // Arabic (Lebanon) |
579 | case 4097: // Arabic (Libya) | 579 | case 4097: // Arabic (Libya) |
580 | case 6145: // Arabic (Morocco) | 580 | case 6145: // Arabic (Morocco) |
581 | case 8193: // Arabic (Oman) | 581 | case 8193: // Arabic (Oman) |
582 | case 16385: // Arabic (Qatar) | 582 | case 16385: // Arabic (Qatar) |
583 | case 1025: // Arabic (Saudi Arabia) | 583 | case 1025: // Arabic (Saudi Arabia) |
584 | case 10241: // Arabic (Syria) | 584 | case 10241: // Arabic (Syria) |
585 | case 14337: // Arabic (U.A.E.) | 585 | case 14337: // Arabic (U.A.E.) |
586 | case 1065: // Farsi | 586 | case 1065: // Farsi |
587 | case 1056: // Urdu | 587 | case 1056: // Urdu |
588 | case 7169: // Arabic (Tunisia) | 588 | case 7169: // Arabic (Tunisia) |
589 | return 1256; | 589 | return 1256; |
590 | case 1061: // Estonian | 590 | case 1061: // Estonian |
591 | case 1062: // Latvian | 591 | case 1062: // Latvian |
592 | case 1063: // Lithuanian | 592 | case 1063: // Lithuanian |
593 | return 1257; | 593 | return 1257; |
594 | case 1066: // Vietnamese | 594 | case 1066: // Vietnamese |
595 | return 1258; | 595 | return 1258; |
596 | } | 596 | } |
597 | return 65001; // utf-8 | 597 | return 65001; // utf-8 |
598 | } | 598 | } |
599 | 599 | ||
600 | namespace | 600 | namespace |
601 | { | 601 | { |
602 | struct SEnvMapper | 602 | struct SEnvMapper |
603 | { | 603 | { |
604 | HWND hWnd; | 604 | HWND hWnd; |
605 | irr::CIrrDeviceWin32* irrDev; | 605 | irr::CIrrDeviceWin32* irrDev; |
606 | }; | 606 | }; |
607 | irr::core::list<SEnvMapper> EnvMap; | 607 | irr::core::list<SEnvMapper> EnvMap; |
608 | 608 | ||
609 | HKL KEYBOARD_INPUT_HKL=0; | 609 | HKL KEYBOARD_INPUT_HKL=0; |
610 | unsigned int KEYBOARD_INPUT_CODEPAGE = 1252; | 610 | unsigned int KEYBOARD_INPUT_CODEPAGE = 1252; |
611 | } | 611 | } |
612 | 612 | ||
613 | SEnvMapper* getEnvMapperFromHWnd(HWND hWnd) | 613 | SEnvMapper* getEnvMapperFromHWnd(HWND hWnd) |
614 | { | 614 | { |
615 | irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin(); | 615 | irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin(); |
616 | for (; it!= EnvMap.end(); ++it) | 616 | for (; it!= EnvMap.end(); ++it) |
617 | if ((*it).hWnd == hWnd) | 617 | if ((*it).hWnd == hWnd) |
618 | return &(*it); | 618 | return &(*it); |
619 | 619 | ||
620 | return 0; | 620 | return 0; |
621 | } | 621 | } |
622 | 622 | ||
623 | 623 | ||
624 | irr::CIrrDeviceWin32* getDeviceFromHWnd(HWND hWnd) | 624 | irr::CIrrDeviceWin32* getDeviceFromHWnd(HWND hWnd) |
625 | { | 625 | { |
626 | irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin(); | 626 | irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin(); |
627 | for (; it!= EnvMap.end(); ++it) | 627 | for (; it!= EnvMap.end(); ++it) |
628 | if ((*it).hWnd == hWnd) | 628 | if ((*it).hWnd == hWnd) |
629 | return (*it).irrDev; | 629 | return (*it).irrDev; |
630 | 630 | ||
631 | return 0; | 631 | return 0; |
632 | } | 632 | } |
633 | 633 | ||
634 | 634 | ||
635 | LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) | 635 | LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) |
636 | { | 636 | { |
637 | #ifndef WM_MOUSEWHEEL | 637 | #ifndef WM_MOUSEWHEEL |
638 | #define WM_MOUSEWHEEL 0x020A | 638 | #define WM_MOUSEWHEEL 0x020A |
639 | #endif | 639 | #endif |
640 | #ifndef WHEEL_DELTA | 640 | #ifndef WHEEL_DELTA |
641 | #define WHEEL_DELTA 120 | 641 | #define WHEEL_DELTA 120 |
642 | #endif | 642 | #endif |
643 | 643 | ||
644 | irr::CIrrDeviceWin32* dev = 0; | 644 | irr::CIrrDeviceWin32* dev = 0; |
645 | irr::SEvent event; | 645 | irr::SEvent event; |
646 | 646 | ||
647 | static irr::s32 ClickCount=0; | 647 | static irr::s32 ClickCount=0; |
648 | if (GetCapture() != hWnd && ClickCount > 0) | 648 | if (GetCapture() != hWnd && ClickCount > 0) |
649 | ClickCount = 0; | 649 | ClickCount = 0; |
650 | 650 | ||
651 | 651 | ||
652 | struct messageMap | 652 | struct messageMap |
653 | { | 653 | { |
654 | irr::s32 group; | 654 | irr::s32 group; |
655 | UINT winMessage; | 655 | UINT winMessage; |
656 | irr::s32 irrMessage; | 656 | irr::s32 irrMessage; |
657 | }; | 657 | }; |
658 | 658 | ||
659 | static messageMap mouseMap[] = | 659 | static messageMap mouseMap[] = |
660 | { | 660 | { |
661 | {0, WM_LBUTTONDOWN, irr::EMIE_LMOUSE_PRESSED_DOWN}, | 661 | {0, WM_LBUTTONDOWN, irr::EMIE_LMOUSE_PRESSED_DOWN}, |
662 | {1, WM_LBUTTONUP, irr::EMIE_LMOUSE_LEFT_UP}, | 662 | {1, WM_LBUTTONUP, irr::EMIE_LMOUSE_LEFT_UP}, |
663 | {0, WM_RBUTTONDOWN, irr::EMIE_RMOUSE_PRESSED_DOWN}, | 663 | {0, WM_RBUTTONDOWN, irr::EMIE_RMOUSE_PRESSED_DOWN}, |
664 | {1, WM_RBUTTONUP, irr::EMIE_RMOUSE_LEFT_UP}, | 664 | {1, WM_RBUTTONUP, irr::EMIE_RMOUSE_LEFT_UP}, |
665 | {0, WM_MBUTTONDOWN, irr::EMIE_MMOUSE_PRESSED_DOWN}, | 665 | {0, WM_MBUTTONDOWN, irr::EMIE_MMOUSE_PRESSED_DOWN}, |
666 | {1, WM_MBUTTONUP, irr::EMIE_MMOUSE_LEFT_UP}, | 666 | {1, WM_MBUTTONUP, irr::EMIE_MMOUSE_LEFT_UP}, |
667 | {2, WM_MOUSEMOVE, irr::EMIE_MOUSE_MOVED}, | 667 | {2, WM_MOUSEMOVE, irr::EMIE_MOUSE_MOVED}, |
668 | {3, WM_MOUSEWHEEL, irr::EMIE_MOUSE_WHEEL}, | 668 | {3, WM_MOUSEWHEEL, irr::EMIE_MOUSE_WHEEL}, |
669 | {-1, 0, 0} | 669 | {-1, 0, 0} |
670 | }; | 670 | }; |
671 | 671 | ||
672 | // handle grouped events | 672 | // handle grouped events |
673 | messageMap * m = mouseMap; | 673 | messageMap * m = mouseMap; |
674 | while ( m->group >=0 && m->winMessage != message ) | 674 | while ( m->group >=0 && m->winMessage != message ) |
675 | m += 1; | 675 | m += 1; |
676 | 676 | ||
677 | if ( m->group >= 0 ) | 677 | if ( m->group >= 0 ) |
678 | { | 678 | { |
679 | if ( m->group == 0 ) // down | 679 | if ( m->group == 0 ) // down |
680 | { | 680 | { |
681 | ClickCount++; | 681 | ClickCount++; |
682 | SetCapture(hWnd); | 682 | SetCapture(hWnd); |
683 | } | 683 | } |
684 | else | 684 | else |
685 | if ( m->group == 1 ) // up | 685 | if ( m->group == 1 ) // up |
686 | { | 686 | { |
687 | ClickCount--; | 687 | ClickCount--; |
688 | if (ClickCount<1) | 688 | if (ClickCount<1) |
689 | { | 689 | { |
690 | ClickCount=0; | 690 | ClickCount=0; |
691 | ReleaseCapture(); | 691 | ReleaseCapture(); |
692 | } | 692 | } |
693 | } | 693 | } |
694 | 694 | ||
695 | event.EventType = irr::EET_MOUSE_INPUT_EVENT; | 695 | event.EventType = irr::EET_MOUSE_INPUT_EVENT; |
696 | event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT) m->irrMessage; | 696 | event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT) m->irrMessage; |
697 | event.MouseInput.X = (short)LOWORD(lParam); | 697 | event.MouseInput.X = (short)LOWORD(lParam); |
698 | event.MouseInput.Y = (short)HIWORD(lParam); | 698 | event.MouseInput.Y = (short)HIWORD(lParam); |
699 | event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0); | 699 | event.MouseInput.Shift = ((LOWORD(wParam) & MK_SHIFT) != 0); |
700 | event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0); | 700 | event.MouseInput.Control = ((LOWORD(wParam) & MK_CONTROL) != 0); |
701 | // left and right mouse buttons | 701 | // left and right mouse buttons |
702 | event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON); | 702 | event.MouseInput.ButtonStates = wParam & ( MK_LBUTTON | MK_RBUTTON); |
703 | // middle and extra buttons | 703 | // middle and extra buttons |
704 | if (wParam & MK_MBUTTON) | 704 | if (wParam & MK_MBUTTON) |
705 | event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE; | 705 | event.MouseInput.ButtonStates |= irr::EMBSM_MIDDLE; |
706 | #if(_WIN32_WINNT >= 0x0500) | 706 | #if(_WIN32_WINNT >= 0x0500) |
707 | if (wParam & MK_XBUTTON1) | 707 | if (wParam & MK_XBUTTON1) |
708 | event.MouseInput.ButtonStates |= irr::EMBSM_EXTRA1; | 708 | event.MouseInput.ButtonStates |= irr::EMBSM_EXTRA1; |
709 | if (wParam & MK_XBUTTON2) | 709 | if (wParam & MK_XBUTTON2) |
710 | event.MouseInput.ButtonStates |= irr::EMBSM_EXTRA2; | 710 | event.MouseInput.ButtonStates |= irr::EMBSM_EXTRA2; |
711 | #endif | 711 | #endif |
712 | event.MouseInput.Wheel = 0.f; | 712 | event.MouseInput.Wheel = 0.f; |
713 | 713 | ||
714 | // wheel | 714 | // wheel |
715 | if ( m->group == 3 ) | 715 | if ( m->group == 3 ) |
716 | { | 716 | { |
717 | POINT p; // fixed by jox | 717 | POINT p; // fixed by jox |
718 | p.x = 0; p.y = 0; | 718 | p.x = 0; p.y = 0; |
719 | ClientToScreen(hWnd, &p); | 719 | ClientToScreen(hWnd, &p); |
720 | event.MouseInput.X -= p.x; | 720 | event.MouseInput.X -= p.x; |
721 | event.MouseInput.Y -= p.y; | 721 | event.MouseInput.Y -= p.y; |
722 | event.MouseInput.Wheel = ((irr::f32)((short)HIWORD(wParam))) / (irr::f32)WHEEL_DELTA; | 722 | event.MouseInput.Wheel = ((irr::f32)((short)HIWORD(wParam))) / (irr::f32)WHEEL_DELTA; |
723 | } | 723 | } |
724 | 724 | ||
725 | dev = getDeviceFromHWnd(hWnd); | 725 | dev = getDeviceFromHWnd(hWnd); |
726 | if (dev) | 726 | if (dev) |
727 | { | 727 | { |
728 | dev->postEventFromUser(event); | 728 | dev->postEventFromUser(event); |
729 | 729 | ||
730 | if ( event.MouseInput.Event >= irr::EMIE_LMOUSE_PRESSED_DOWN && event.MouseInput.Event <= irr::EMIE_MMOUSE_PRESSED_DOWN ) | 730 | if ( event.MouseInput.Event >= irr::EMIE_LMOUSE_PRESSED_DOWN && event.MouseInput.Event <= irr::EMIE_MMOUSE_PRESSED_DOWN ) |
731 | { | 731 | { |
732 | irr::u32 clicks = dev->checkSuccessiveClicks(event.MouseInput.X, event.MouseInput.Y, event.MouseInput.Event); | 732 | irr::u32 clicks = dev->checkSuccessiveClicks(event.MouseInput.X, event.MouseInput.Y, event.MouseInput.Event); |
733 | if ( clicks == 2 ) | 733 | if ( clicks == 2 ) |
734 | { | 734 | { |
735 | event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT)(irr::EMIE_LMOUSE_DOUBLE_CLICK + event.MouseInput.Event-irr::EMIE_LMOUSE_PRESSED_DOWN); | 735 | event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT)(irr::EMIE_LMOUSE_DOUBLE_CLICK + event.MouseInput.Event-irr::EMIE_LMOUSE_PRESSED_DOWN); |
736 | dev->postEventFromUser(event); | 736 | dev->postEventFromUser(event); |
737 | } | 737 | } |
738 | else if ( clicks == 3 ) | 738 | else if ( clicks == 3 ) |
739 | { | 739 | { |
740 | event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT)(irr::EMIE_LMOUSE_TRIPLE_CLICK + event.MouseInput.Event-irr::EMIE_LMOUSE_PRESSED_DOWN); | 740 | event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT)(irr::EMIE_LMOUSE_TRIPLE_CLICK + event.MouseInput.Event-irr::EMIE_LMOUSE_PRESSED_DOWN); |
741 | dev->postEventFromUser(event); | 741 | dev->postEventFromUser(event); |
742 | } | 742 | } |
743 | } | 743 | } |
744 | } | 744 | } |
745 | return 0; | 745 | return 0; |
746 | } | 746 | } |
747 | 747 | ||
748 | switch (message) | 748 | switch (message) |
749 | { | 749 | { |
750 | case WM_PAINT: | 750 | case WM_PAINT: |
751 | { | 751 | { |
752 | PAINTSTRUCT ps; | 752 | PAINTSTRUCT ps; |
753 | BeginPaint(hWnd, &ps); | 753 | BeginPaint(hWnd, &ps); |
754 | EndPaint(hWnd, &ps); | 754 | EndPaint(hWnd, &ps); |
755 | } | 755 | } |
756 | return 0; | 756 | return 0; |
757 | 757 | ||
758 | case WM_ERASEBKGND: | 758 | case WM_ERASEBKGND: |
759 | return 0; | 759 | return 0; |
760 | 760 | ||
761 | case WM_SYSKEYDOWN: | 761 | case WM_SYSKEYDOWN: |
762 | case WM_SYSKEYUP: | 762 | case WM_SYSKEYUP: |
763 | case WM_KEYDOWN: | 763 | case WM_KEYDOWN: |
764 | case WM_KEYUP: | 764 | case WM_KEYUP: |
765 | { | 765 | { |
766 | BYTE allKeys[256]; | 766 | BYTE allKeys[256]; |
767 | 767 | ||
768 | event.EventType = irr::EET_KEY_INPUT_EVENT; | 768 | event.EventType = irr::EET_KEY_INPUT_EVENT; |
769 | event.KeyInput.Key = (irr::EKEY_CODE)wParam; | 769 | event.KeyInput.Key = (irr::EKEY_CODE)wParam; |
770 | event.KeyInput.PressedDown = (message==WM_KEYDOWN || message == WM_SYSKEYDOWN); | 770 | event.KeyInput.PressedDown = (message==WM_KEYDOWN || message == WM_SYSKEYDOWN); |
771 | 771 | ||
772 | const UINT MY_MAPVK_VSC_TO_VK_EX = 3; // MAPVK_VSC_TO_VK_EX should be in SDK according to MSDN, but isn't in mine. | 772 | const UINT MY_MAPVK_VSC_TO_VK_EX = 3; // MAPVK_VSC_TO_VK_EX should be in SDK according to MSDN, but isn't in mine. |
773 | if ( event.KeyInput.Key == irr::KEY_SHIFT ) | 773 | if ( event.KeyInput.Key == irr::KEY_SHIFT ) |
774 | { | 774 | { |
775 | // this will fail on systems before windows NT/2000/XP, not sure _what_ will return there instead. | 775 | // this will fail on systems before windows NT/2000/XP, not sure _what_ will return there instead. |
776 | event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX ); | 776 | event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX ); |
777 | } | 777 | } |
778 | if ( event.KeyInput.Key == irr::KEY_CONTROL ) | 778 | if ( event.KeyInput.Key == irr::KEY_CONTROL ) |
779 | { | 779 | { |
780 | event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX ); | 780 | event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX ); |
781 | // some keyboards will just return LEFT for both - left and right keys. So also check extend bit. | 781 | // some keyboards will just return LEFT for both - left and right keys. So also check extend bit. |
782 | if (lParam & 0x1000000) | 782 | if (lParam & 0x1000000) |
783 | event.KeyInput.Key = irr::KEY_RCONTROL; | 783 | event.KeyInput.Key = irr::KEY_RCONTROL; |
784 | } | 784 | } |
785 | if ( event.KeyInput.Key == irr::KEY_MENU ) | 785 | if ( event.KeyInput.Key == irr::KEY_MENU ) |
786 | { | 786 | { |
787 | event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX ); | 787 | event.KeyInput.Key = (irr::EKEY_CODE)MapVirtualKey( ((lParam>>16) & 255), MY_MAPVK_VSC_TO_VK_EX ); |
788 | if (lParam & 0x1000000) | 788 | if (lParam & 0x1000000) |
789 | event.KeyInput.Key = irr::KEY_RMENU; | 789 | event.KeyInput.Key = irr::KEY_RMENU; |
790 | } | 790 | } |
791 | 791 | ||
792 | GetKeyboardState(allKeys); | 792 | GetKeyboardState(allKeys); |
793 | 793 | ||
794 | event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0); | 794 | event.KeyInput.Shift = ((allKeys[VK_SHIFT] & 0x80)!=0); |
795 | event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0); | 795 | event.KeyInput.Control = ((allKeys[VK_CONTROL] & 0x80)!=0); |
796 | 796 | ||
797 | // Handle unicode and deadkeys in a way that works since Windows 95 and nt4.0 | 797 | // Handle unicode and deadkeys in a way that works since Windows 95 and nt4.0 |
798 | // Using ToUnicode instead would be shorter, but would to my knowledge not run on 95 and 98. | 798 | // Using ToUnicode instead would be shorter, but would to my knowledge not run on 95 and 98. |
799 | WORD keyChars[2]; | 799 | WORD keyChars[2]; |
800 | UINT scanCode = HIWORD(lParam); | 800 | UINT scanCode = HIWORD(lParam); |
801 | int conversionResult = ToAsciiEx(wParam,scanCode,allKeys,keyChars,0,KEYBOARD_INPUT_HKL); | 801 | int conversionResult = ToAsciiEx(wParam,scanCode,allKeys,keyChars,0,KEYBOARD_INPUT_HKL); |
802 | if (conversionResult == 1) | 802 | if (conversionResult == 1) |
803 | { | 803 | { |
804 | WORD unicodeChar; | 804 | WORD unicodeChar; |
805 | MultiByteToWideChar( | 805 | MultiByteToWideChar( |
806 | KEYBOARD_INPUT_CODEPAGE, | 806 | KEYBOARD_INPUT_CODEPAGE, |
807 | MB_PRECOMPOSED, // default | 807 | MB_PRECOMPOSED, // default |
808 | (LPCSTR)keyChars, | 808 | (LPCSTR)keyChars, |
809 | sizeof(keyChars), | 809 | sizeof(keyChars), |
810 | (WCHAR*)&unicodeChar, | 810 | (WCHAR*)&unicodeChar, |
811 | 1 ); | 811 | 1 ); |
812 | event.KeyInput.Char = unicodeChar; | 812 | event.KeyInput.Char = unicodeChar; |
813 | } | 813 | } |
814 | else | 814 | else |
815 | event.KeyInput.Char = 0; | 815 | event.KeyInput.Char = 0; |
816 | 816 | ||
817 | // allow composing characters like '@' with Alt Gr on non-US keyboards | 817 | // allow composing characters like '@' with Alt Gr on non-US keyboards |
818 | if ((allKeys[VK_MENU] & 0x80) != 0) | 818 | if ((allKeys[VK_MENU] & 0x80) != 0) |
819 | event.KeyInput.Control = 0; | 819 | event.KeyInput.Control = 0; |
820 | 820 | ||
821 | dev = getDeviceFromHWnd(hWnd); | 821 | dev = getDeviceFromHWnd(hWnd); |
822 | if (dev) | 822 | if (dev) |
823 | dev->postEventFromUser(event); | 823 | dev->postEventFromUser(event); |
824 | 824 | ||
825 | if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP) | 825 | if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP) |
826 | return DefWindowProc(hWnd, message, wParam, lParam); | 826 | return DefWindowProc(hWnd, message, wParam, lParam); |
827 | else | 827 | else |
828 | return 0; | 828 | return 0; |
829 | } | 829 | } |
830 | 830 | ||
831 | case WM_SIZE: | 831 | case WM_SIZE: |
832 | { | 832 | { |
833 | // resize | 833 | // resize |
834 | dev = getDeviceFromHWnd(hWnd); | 834 | dev = getDeviceFromHWnd(hWnd); |
835 | if (dev) | 835 | if (dev) |
836 | dev->OnResized(); | 836 | dev->OnResized(); |
837 | } | 837 | } |
838 | return 0; | 838 | return 0; |
839 | 839 | ||
840 | case WM_DESTROY: | 840 | case WM_DESTROY: |
841 | PostQuitMessage(0); | 841 | PostQuitMessage(0); |
842 | return 0; | 842 | return 0; |
843 | 843 | ||
844 | case WM_SYSCOMMAND: | 844 | case WM_SYSCOMMAND: |
845 | // prevent screensaver or monitor powersave mode from starting | 845 | // prevent screensaver or monitor powersave mode from starting |
846 | if ((wParam & 0xFFF0) == SC_SCREENSAVE || | 846 | if ((wParam & 0xFFF0) == SC_SCREENSAVE || |
847 | (wParam & 0xFFF0) == SC_MONITORPOWER || | 847 | (wParam & 0xFFF0) == SC_MONITORPOWER || |
848 | (wParam & 0xFFF0) == SC_KEYMENU | 848 | (wParam & 0xFFF0) == SC_KEYMENU |
849 | ) | 849 | ) |
850 | return 0; | 850 | return 0; |
851 | 851 | ||
852 | break; | 852 | break; |
853 | 853 | ||
854 | case WM_ACTIVATE: | 854 | case WM_ACTIVATE: |
855 | // we need to take care for screen changes, e.g. Alt-Tab | 855 | // we need to take care for screen changes, e.g. Alt-Tab |
856 | dev = getDeviceFromHWnd(hWnd); | 856 | dev = getDeviceFromHWnd(hWnd); |
857 | if (dev && dev->isFullscreen()) | 857 | if (dev && dev->isFullscreen()) |
858 | { | 858 | { |
859 | if ((wParam&0xFF)==WA_INACTIVE) | 859 | if ((wParam&0xFF)==WA_INACTIVE) |
860 | { | 860 | { |
861 | // If losing focus we minimize the app to show other one | 861 | // If losing focus we minimize the app to show other one |
862 | ShowWindow(hWnd,SW_MINIMIZE); | 862 | ShowWindow(hWnd,SW_MINIMIZE); |
863 | // and switch back to default resolution | 863 | // and switch back to default resolution |
864 | dev->switchToFullScreen(true); | 864 | dev->switchToFullScreen(true); |
865 | } | 865 | } |
866 | else | 866 | else |
867 | { | 867 | { |
868 | // Otherwise we retore the fullscreen Irrlicht app | 868 | // Otherwise we retore the fullscreen Irrlicht app |
869 | SetForegroundWindow(hWnd); | 869 | SetForegroundWindow(hWnd); |
870 | ShowWindow(hWnd, SW_RESTORE); | 870 | ShowWindow(hWnd, SW_RESTORE); |
871 | // and set the fullscreen resolution again | 871 | // and set the fullscreen resolution again |
872 | dev->switchToFullScreen(); | 872 | dev->switchToFullScreen(); |
873 | } | 873 | } |
874 | } | 874 | } |
875 | break; | 875 | break; |
876 | 876 | ||
877 | case WM_USER: | 877 | case WM_USER: |
878 | event.EventType = irr::EET_USER_EVENT; | 878 | event.EventType = irr::EET_USER_EVENT; |
879 | event.UserEvent.UserData1 = (irr::s32)wParam; | 879 | event.UserEvent.UserData1 = (irr::s32)wParam; |
880 | event.UserEvent.UserData2 = (irr::s32)lParam; | 880 | event.UserEvent.UserData2 = (irr::s32)lParam; |
881 | dev = getDeviceFromHWnd(hWnd); | 881 | dev = getDeviceFromHWnd(hWnd); |
882 | 882 | ||
883 | if (dev) | 883 | if (dev) |
884 | dev->postEventFromUser(event); | 884 | dev->postEventFromUser(event); |
885 | 885 | ||
886 | return 0; | 886 | return 0; |
887 | 887 | ||
888 | case WM_SETCURSOR: | 888 | case WM_SETCURSOR: |
889 | // because Windows forgot about that in the meantime | 889 | // because Windows forgot about that in the meantime |
890 | dev = getDeviceFromHWnd(hWnd); | 890 | dev = getDeviceFromHWnd(hWnd); |
891 | if (dev) | 891 | if (dev) |
892 | { | 892 | { |
893 | dev->getCursorControl()->setActiveIcon( dev->getCursorControl()->getActiveIcon() ); | 893 | dev->getCursorControl()->setActiveIcon( dev->getCursorControl()->getActiveIcon() ); |
894 | dev->getCursorControl()->setVisible( dev->getCursorControl()->isVisible() ); | 894 | dev->getCursorControl()->setVisible( dev->getCursorControl()->isVisible() ); |
895 | } | 895 | } |
896 | break; | 896 | break; |
897 | 897 | ||
898 | case WM_INPUTLANGCHANGE: | 898 | case WM_INPUTLANGCHANGE: |
899 | // get the new codepage used for keyboard input | 899 | // get the new codepage used for keyboard input |
900 | KEYBOARD_INPUT_HKL = GetKeyboardLayout(0); | 900 | KEYBOARD_INPUT_HKL = GetKeyboardLayout(0); |
901 | KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) ); | 901 | KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) ); |
902 | return 0; | 902 | return 0; |
903 | } | 903 | } |
904 | return DefWindowProc(hWnd, message, wParam, lParam); | 904 | return DefWindowProc(hWnd, message, wParam, lParam); |
905 | } | 905 | } |
906 | 906 | ||
907 | 907 | ||
908 | namespace irr | 908 | namespace irr |
909 | { | 909 | { |
910 | 910 | ||
911 | //! constructor | 911 | //! constructor |
912 | CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params) | 912 | CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params) |
913 | : CIrrDeviceStub(params), HWnd(0), ChangedToFullScreen(false), Resized(false), | 913 | : CIrrDeviceStub(params), HWnd(0), ChangedToFullScreen(false), Resized(false), |
914 | ExternalWindow(false), Win32CursorControl(0), JoyControl(0) | 914 | ExternalWindow(false), Win32CursorControl(0), JoyControl(0) |
915 | { | 915 | { |
916 | #ifdef _DEBUG | 916 | #ifdef _DEBUG |
917 | setDebugName("CIrrDeviceWin32"); | 917 | setDebugName("CIrrDeviceWin32"); |
918 | #endif | 918 | #endif |
919 | 919 | ||
920 | // get windows version and create OS operator | 920 | // get windows version and create OS operator |
921 | core::stringc winversion; | 921 | core::stringc winversion; |
922 | getWindowsVersion(winversion); | 922 | getWindowsVersion(winversion); |
923 | Operator = new COSOperator(winversion); | 923 | Operator = new COSOperator(winversion); |
924 | os::Printer::log(winversion.c_str(), ELL_INFORMATION); | 924 | os::Printer::log(winversion.c_str(), ELL_INFORMATION); |
925 | 925 | ||
926 | // get handle to exe file | 926 | // get handle to exe file |
927 | HINSTANCE hInstance = GetModuleHandle(0); | 927 | HINSTANCE hInstance = GetModuleHandle(0); |
928 | 928 | ||
929 | // Store original desktop mode. | 929 | // Store original desktop mode. |
930 | 930 | ||
931 | memset(&DesktopMode, 0, sizeof(DesktopMode)); | 931 | memset(&DesktopMode, 0, sizeof(DesktopMode)); |
932 | DesktopMode.dmSize = sizeof(DesktopMode); | 932 | DesktopMode.dmSize = sizeof(DesktopMode); |
933 | 933 | ||
934 | EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DesktopMode); | 934 | EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DesktopMode); |
935 | 935 | ||
936 | // create the window if we need to and we do not use the null device | 936 | // create the window if we need to and we do not use the null device |
937 | if (!CreationParams.WindowId && CreationParams.DriverType != video::EDT_NULL) | 937 | if (!CreationParams.WindowId && CreationParams.DriverType != video::EDT_NULL) |
938 | { | 938 | { |
939 | const fschar_t* ClassName = __TEXT("CIrrDeviceWin32"); | 939 | const fschar_t* ClassName = __TEXT("CIrrDeviceWin32"); |
940 | 940 | ||
941 | // Register Class | 941 | // Register Class |
942 | WNDCLASSEX wcex; | 942 | WNDCLASSEX wcex; |
943 | wcex.cbSize = sizeof(WNDCLASSEX); | 943 | wcex.cbSize = sizeof(WNDCLASSEX); |
944 | wcex.style = CS_HREDRAW | CS_VREDRAW; | 944 | wcex.style = CS_HREDRAW | CS_VREDRAW; |
945 | wcex.lpfnWndProc = WndProc; | 945 | wcex.lpfnWndProc = WndProc; |
946 | wcex.cbClsExtra = 0; | 946 | wcex.cbClsExtra = 0; |
947 | wcex.cbWndExtra = 0; | 947 | wcex.cbWndExtra = 0; |
948 | wcex.hInstance = hInstance; | 948 | wcex.hInstance = hInstance; |
949 | wcex.hIcon = NULL; | 949 | wcex.hIcon = NULL; |
950 | wcex.hCursor = 0; // LoadCursor(NULL, IDC_ARROW); | 950 | wcex.hCursor = 0; // LoadCursor(NULL, IDC_ARROW); |
951 | wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); | 951 | wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); |
952 | wcex.lpszMenuName = 0; | 952 | wcex.lpszMenuName = 0; |
953 | wcex.lpszClassName = ClassName; | 953 | wcex.lpszClassName = ClassName; |
954 | wcex.hIconSm = 0; | 954 | wcex.hIconSm = 0; |
955 | 955 | ||
956 | // if there is an icon, load it | 956 | // if there is an icon, load it |
957 | wcex.hIcon = (HICON)LoadImage(hInstance, __TEXT("irrlicht.ico"), IMAGE_ICON, 0,0, LR_LOADFROMFILE); | 957 | wcex.hIcon = (HICON)LoadImage(hInstance, __TEXT("irrlicht.ico"), IMAGE_ICON, 0,0, LR_LOADFROMFILE); |
958 | 958 | ||
959 | RegisterClassEx(&wcex); | 959 | RegisterClassEx(&wcex); |
960 | 960 | ||
961 | // calculate client size | 961 | // calculate client size |
962 | 962 | ||
963 | RECT clientSize; | 963 | RECT clientSize; |
964 | clientSize.top = 0; | 964 | clientSize.top = 0; |
965 | clientSize.left = 0; | 965 | clientSize.left = 0; |
966 | clientSize.right = CreationParams.WindowSize.Width; | 966 | clientSize.right = CreationParams.WindowSize.Width; |
967 | clientSize.bottom = CreationParams.WindowSize.Height; | 967 | clientSize.bottom = CreationParams.WindowSize.Height; |
968 | 968 | ||
969 | DWORD style = WS_POPUP; | 969 | DWORD style = WS_POPUP; |
970 | 970 | ||
971 | if (!CreationParams.Fullscreen) | 971 | if (!CreationParams.Fullscreen) |
972 | style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; | 972 | style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; |
973 | 973 | ||
974 | AdjustWindowRect(&clientSize, style, FALSE); | 974 | AdjustWindowRect(&clientSize, style, FALSE); |
975 | 975 | ||
976 | const s32 realWidth = clientSize.right - clientSize.left; | 976 | const s32 realWidth = clientSize.right - clientSize.left; |
977 | const s32 realHeight = clientSize.bottom - clientSize.top; | 977 | const s32 realHeight = clientSize.bottom - clientSize.top; |
978 | 978 | ||
979 | s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; | 979 | s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; |
980 | s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; | 980 | s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; |
981 | 981 | ||
982 | if ( windowLeft < 0 ) | 982 | if ( windowLeft < 0 ) |
983 | windowLeft = 0; | 983 | windowLeft = 0; |
984 | if ( windowTop < 0 ) | 984 | if ( windowTop < 0 ) |
985 | windowTop = 0; // make sure window menus are in screen on creation | 985 | windowTop = 0; // make sure window menus are in screen on creation |
986 | 986 | ||
987 | if (CreationParams.Fullscreen) | 987 | if (CreationParams.Fullscreen) |
988 | { | 988 | { |
989 | windowLeft = 0; | 989 | windowLeft = 0; |
990 | windowTop = 0; | 990 | windowTop = 0; |
991 | } | 991 | } |
992 | 992 | ||
993 | // create window | 993 | // create window |
994 | 994 | ||
995 | HWnd = CreateWindow( ClassName, __TEXT(""), style, windowLeft, windowTop, | 995 | HWnd = CreateWindow( ClassName, __TEXT(""), style, windowLeft, windowTop, |
996 | realWidth, realHeight, NULL, NULL, hInstance, NULL); | 996 | realWidth, realHeight, NULL, NULL, hInstance, NULL); |
997 | CreationParams.WindowId = HWnd; | 997 | CreationParams.WindowId = HWnd; |
998 | // CreationParams.WindowSize.Width = realWidth; | 998 | // CreationParams.WindowSize.Width = realWidth; |
999 | // CreationParams.WindowSize.Height = realHeight; | 999 | // CreationParams.WindowSize.Height = realHeight; |
1000 | 1000 | ||
1001 | ShowWindow(HWnd, SW_SHOWNORMAL); | 1001 | ShowWindow(HWnd, SW_SHOWNORMAL); |
1002 | UpdateWindow(HWnd); | 1002 | UpdateWindow(HWnd); |
1003 | 1003 | ||
1004 | // fix ugly ATI driver bugs. Thanks to ariaci | 1004 | // fix ugly ATI driver bugs. Thanks to ariaci |
1005 | MoveWindow(HWnd, windowLeft, windowTop, realWidth, realHeight, TRUE); | 1005 | MoveWindow(HWnd, windowLeft, windowTop, realWidth, realHeight, TRUE); |
1006 | 1006 | ||
1007 | // make sure everything gets updated to the real sizes | 1007 | // make sure everything gets updated to the real sizes |
1008 | Resized = true; | 1008 | Resized = true; |
1009 | } | 1009 | } |
1010 | else if (CreationParams.WindowId) | 1010 | else if (CreationParams.WindowId) |
1011 | { | 1011 | { |
1012 | // attach external window | 1012 | // attach external window |
1013 | HWnd = static_cast<HWND>(CreationParams.WindowId); | 1013 | HWnd = static_cast<HWND>(CreationParams.WindowId); |
1014 | RECT r; | 1014 | RECT r; |
1015 | GetWindowRect(HWnd, &r); | 1015 | GetWindowRect(HWnd, &r); |
1016 | CreationParams.WindowSize.Width = r.right - r.left; | 1016 | CreationParams.WindowSize.Width = r.right - r.left; |
1017 | CreationParams.WindowSize.Height = r.bottom - r.top; | 1017 | CreationParams.WindowSize.Height = r.bottom - r.top; |
1018 | CreationParams.Fullscreen = false; | 1018 | CreationParams.Fullscreen = false; |
1019 | ExternalWindow = true; | 1019 | ExternalWindow = true; |
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | // create cursor control | 1022 | // create cursor control |
1023 | 1023 | ||
1024 | Win32CursorControl = new CCursorControl(this, CreationParams.WindowSize, HWnd, CreationParams.Fullscreen); | 1024 | Win32CursorControl = new CCursorControl(this, CreationParams.WindowSize, HWnd, CreationParams.Fullscreen); |
1025 | CursorControl = Win32CursorControl; | 1025 | CursorControl = Win32CursorControl; |
1026 | JoyControl = new SJoystickWin32Control(this); | 1026 | JoyControl = new SJoystickWin32Control(this); |
1027 | 1027 | ||
1028 | // initialize doubleclicks with system values | 1028 | // initialize doubleclicks with system values |
1029 | MouseMultiClicks.DoubleClickTime = GetDoubleClickTime(); | 1029 | MouseMultiClicks.DoubleClickTime = GetDoubleClickTime(); |
1030 | 1030 | ||
1031 | // create driver | 1031 | // create driver |
1032 | 1032 | ||
1033 | createDriver(); | 1033 | createDriver(); |
1034 | 1034 | ||
1035 | if (VideoDriver) | 1035 | if (VideoDriver) |
1036 | createGUIAndScene(); | 1036 | createGUIAndScene(); |
1037 | 1037 | ||
1038 | // register environment | 1038 | // register environment |
1039 | 1039 | ||
1040 | SEnvMapper em; | 1040 | SEnvMapper em; |
1041 | em.irrDev = this; | 1041 | em.irrDev = this; |
1042 | em.hWnd = HWnd; | 1042 | em.hWnd = HWnd; |
1043 | EnvMap.push_back(em); | 1043 | EnvMap.push_back(em); |
1044 | 1044 | ||
1045 | // set this as active window | 1045 | // set this as active window |
1046 | if (!ExternalWindow) | 1046 | if (!ExternalWindow) |
1047 | { | 1047 | { |
1048 | SetActiveWindow(HWnd); | 1048 | SetActiveWindow(HWnd); |
1049 | SetForegroundWindow(HWnd); | 1049 | SetForegroundWindow(HWnd); |
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | // get the codepage used for keyboard input | 1052 | // get the codepage used for keyboard input |
1053 | KEYBOARD_INPUT_HKL = GetKeyboardLayout(0); | 1053 | KEYBOARD_INPUT_HKL = GetKeyboardLayout(0); |
1054 | KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) ); | 1054 | KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) ); |
1055 | 1055 | ||
1056 | // inform driver about the window size etc. | 1056 | // inform driver about the window size etc. |
1057 | resizeIfNecessary(); | 1057 | resizeIfNecessary(); |
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | 1060 | ||
1061 | //! destructor | 1061 | //! destructor |
1062 | CIrrDeviceWin32::~CIrrDeviceWin32() | 1062 | CIrrDeviceWin32::~CIrrDeviceWin32() |
1063 | { | 1063 | { |
1064 | delete JoyControl; | 1064 | delete JoyControl; |
1065 | 1065 | ||
1066 | // unregister environment | 1066 | // unregister environment |
1067 | 1067 | ||
1068 | irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin(); | 1068 | irr::core::list<SEnvMapper>::Iterator it = EnvMap.begin(); |
1069 | for (; it!= EnvMap.end(); ++it) | 1069 | for (; it!= EnvMap.end(); ++it) |
1070 | { | 1070 | { |
1071 | if ((*it).hWnd == HWnd) | 1071 | if ((*it).hWnd == HWnd) |
1072 | { | 1072 | { |
1073 | EnvMap.erase(it); | 1073 | EnvMap.erase(it); |
1074 | break; | 1074 | break; |
1075 | } | 1075 | } |
1076 | } | 1076 | } |
1077 | 1077 | ||
1078 | switchToFullScreen(true); | 1078 | switchToFullScreen(true); |
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | 1081 | ||
1082 | //! create the driver | 1082 | //! create the driver |
1083 | void CIrrDeviceWin32::createDriver() | 1083 | void CIrrDeviceWin32::createDriver() |
1084 | { | 1084 | { |
1085 | switch(CreationParams.DriverType) | 1085 | switch(CreationParams.DriverType) |
1086 | { | 1086 | { |
1087 | case video::EDT_DIRECT3D8: | 1087 | case video::EDT_DIRECT3D8: |
1088 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ | 1088 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ |
1089 | 1089 | ||
1090 | VideoDriver = video::createDirectX8Driver(CreationParams, FileSystem, HWnd); | 1090 | VideoDriver = video::createDirectX8Driver(CreationParams, FileSystem, HWnd); |
1091 | 1091 | ||
1092 | if (!VideoDriver) | 1092 | if (!VideoDriver) |
1093 | { | 1093 | { |
1094 | os::Printer::log("Could not create DIRECT3D8 Driver.", ELL_ERROR); | 1094 | os::Printer::log("Could not create DIRECT3D8 Driver.", ELL_ERROR); |
1095 | } | 1095 | } |
1096 | #else | 1096 | #else |
1097 | os::Printer::log("DIRECT3D8 Driver was not compiled into this dll. Try another one.", ELL_ERROR); | 1097 | os::Printer::log("DIRECT3D8 Driver was not compiled into this dll. Try another one.", ELL_ERROR); |
1098 | #endif // _IRR_COMPILE_WITH_DIRECT3D_8_ | 1098 | #endif // _IRR_COMPILE_WITH_DIRECT3D_8_ |
1099 | 1099 | ||
1100 | break; | 1100 | break; |
1101 | 1101 | ||
1102 | case video::EDT_DIRECT3D9: | 1102 | case video::EDT_DIRECT3D9: |
1103 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ | 1103 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ |
1104 | 1104 | ||
1105 | VideoDriver = video::createDirectX9Driver(CreationParams, FileSystem, HWnd); | 1105 | VideoDriver = video::createDirectX9Driver(CreationParams, FileSystem, HWnd); |
1106 | 1106 | ||
1107 | if (!VideoDriver) | 1107 | if (!VideoDriver) |
1108 | { | 1108 | { |
1109 | os::Printer::log("Could not create DIRECT3D9 Driver.", ELL_ERROR); | 1109 | os::Printer::log("Could not create DIRECT3D9 Driver.", ELL_ERROR); |
1110 | } | 1110 | } |
1111 | #else | 1111 | #else |
1112 | os::Printer::log("DIRECT3D9 Driver was not compiled into this dll. Try another one.", ELL_ERROR); | 1112 | os::Printer::log("DIRECT3D9 Driver was not compiled into this dll. Try another one.", ELL_ERROR); |
1113 | #endif // _IRR_COMPILE_WITH_DIRECT3D_9_ | 1113 | #endif // _IRR_COMPILE_WITH_DIRECT3D_9_ |
1114 | 1114 | ||
1115 | break; | 1115 | break; |
1116 | 1116 | ||
1117 | case video::EDT_OPENGL: | 1117 | case video::EDT_OPENGL: |
1118 | 1118 | ||
1119 | #ifdef _IRR_COMPILE_WITH_OPENGL_ | 1119 | #ifdef _IRR_COMPILE_WITH_OPENGL_ |
1120 | switchToFullScreen(); | 1120 | switchToFullScreen(); |
1121 | 1121 | ||
1122 | VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this); | 1122 | VideoDriver = video::createOpenGLDriver(CreationParams, FileSystem, this); |
1123 | if (!VideoDriver) | 1123 | if (!VideoDriver) |
1124 | { | 1124 | { |
1125 | os::Printer::log("Could not create OpenGL driver.", ELL_ERROR); | 1125 | os::Printer::log("Could not create OpenGL driver.", ELL_ERROR); |
1126 | } | 1126 | } |
1127 | #else | 1127 | #else |
1128 | os::Printer::log("OpenGL driver was not compiled in.", ELL_ERROR); | 1128 | os::Printer::log("OpenGL driver was not compiled in.", ELL_ERROR); |
1129 | #endif | 1129 | #endif |
1130 | break; | 1130 | break; |
1131 | 1131 | ||
1132 | case video::EDT_SOFTWARE: | 1132 | case video::EDT_SOFTWARE: |
1133 | 1133 | ||
1134 | #ifdef _IRR_COMPILE_WITH_SOFTWARE_ | 1134 | #ifdef _IRR_COMPILE_WITH_SOFTWARE_ |
1135 | switchToFullScreen(); | 1135 | switchToFullScreen(); |
1136 | 1136 | ||
1137 | VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this); | 1137 | VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this); |
1138 | #else | 1138 | #else |
1139 | os::Printer::log("Software driver was not compiled in.", ELL_ERROR); | 1139 | os::Printer::log("Software driver was not compiled in.", ELL_ERROR); |
1140 | #endif | 1140 | #endif |
1141 | 1141 | ||
1142 | break; | 1142 | break; |
1143 | 1143 | ||
1144 | case video::EDT_BURNINGSVIDEO: | 1144 | case video::EDT_BURNINGSVIDEO: |
1145 | #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ | 1145 | #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ |
1146 | switchToFullScreen(); | 1146 | switchToFullScreen(); |
1147 | 1147 | ||
1148 | VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this); | 1148 | VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this); |
1149 | #else | 1149 | #else |
1150 | os::Printer::log("Burning's Video driver was not compiled in.", ELL_ERROR); | 1150 | os::Printer::log("Burning's Video driver was not compiled in.", ELL_ERROR); |
1151 | #endif | 1151 | #endif |
1152 | break; | 1152 | break; |
1153 | 1153 | ||
1154 | case video::EDT_NULL: | 1154 | case video::EDT_NULL: |
1155 | // create null driver | 1155 | // create null driver |
1156 | VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); | 1156 | VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); |
1157 | break; | 1157 | break; |
1158 | 1158 | ||
1159 | default: | 1159 | default: |
1160 | os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); | 1160 | os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); |
1161 | break; | 1161 | break; |
1162 | } | 1162 | } |
1163 | } | 1163 | } |
1164 | 1164 | ||
1165 | 1165 | ||
1166 | //! runs the device. Returns false if device wants to be deleted | 1166 | //! runs the device. Returns false if device wants to be deleted |
1167 | bool CIrrDeviceWin32::run() | 1167 | bool CIrrDeviceWin32::run() |
1168 | { | 1168 | { |
1169 | os::Timer::tick(); | 1169 | os::Timer::tick(); |
1170 | 1170 | ||
1171 | static_cast<CCursorControl*>(CursorControl)->update(); | 1171 | static_cast<CCursorControl*>(CursorControl)->update(); |
1172 | 1172 | ||
1173 | handleSystemMessages(); | 1173 | handleSystemMessages(); |
1174 | 1174 | ||
1175 | if (!Close) | 1175 | if (!Close) |
1176 | resizeIfNecessary(); | 1176 | resizeIfNecessary(); |
1177 | 1177 | ||
1178 | if(!Close && JoyControl) | 1178 | if(!Close && JoyControl) |
1179 | JoyControl->pollJoysticks(); | 1179 | JoyControl->pollJoysticks(); |
1180 | 1180 | ||
1181 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 1181 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
1182 | return !Close; | 1182 | return !Close; |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | 1185 | ||
1186 | //! Pause the current process for the minimum time allowed only to allow other processes to execute | 1186 | //! Pause the current process for the minimum time allowed only to allow other processes to execute |
1187 | void CIrrDeviceWin32::yield() | 1187 | void CIrrDeviceWin32::yield() |
1188 | { | 1188 | { |
1189 | Sleep(1); | 1189 | Sleep(1); |
1190 | } | 1190 | } |
1191 | 1191 | ||
1192 | //! Pause execution and let other processes to run for a specified amount of time. | 1192 | //! Pause execution and let other processes to run for a specified amount of time. |
1193 | void CIrrDeviceWin32::sleep(u32 timeMs, bool pauseTimer) | 1193 | void CIrrDeviceWin32::sleep(u32 timeMs, bool pauseTimer) |
1194 | { | 1194 | { |
1195 | const bool wasStopped = Timer ? Timer->isStopped() : true; | 1195 | const bool wasStopped = Timer ? Timer->isStopped() : true; |
1196 | if (pauseTimer && !wasStopped) | 1196 | if (pauseTimer && !wasStopped) |
1197 | Timer->stop(); | 1197 | Timer->stop(); |
1198 | 1198 | ||
1199 | Sleep(timeMs); | 1199 | Sleep(timeMs); |
1200 | 1200 | ||
1201 | if (pauseTimer && !wasStopped) | 1201 | if (pauseTimer && !wasStopped) |
1202 | Timer->start(); | 1202 | Timer->start(); |
1203 | } | 1203 | } |
1204 | 1204 | ||
1205 | 1205 | ||
1206 | void CIrrDeviceWin32::resizeIfNecessary() | 1206 | void CIrrDeviceWin32::resizeIfNecessary() |
1207 | { | 1207 | { |
1208 | if (!Resized || !getVideoDriver()) | 1208 | if (!Resized || !getVideoDriver()) |
1209 | return; | 1209 | return; |
1210 | 1210 | ||
1211 | RECT r; | 1211 | RECT r; |
1212 | GetClientRect(HWnd, &r); | 1212 | GetClientRect(HWnd, &r); |
1213 | 1213 | ||
1214 | char tmp[255]; | 1214 | char tmp[255]; |
1215 | 1215 | ||
1216 | if (r.right < 2 || r.bottom < 2) | 1216 | if (r.right < 2 || r.bottom < 2) |
1217 | { | 1217 | { |
1218 | sprintf(tmp, "Ignoring resize operation to (%ld %ld)", r.right, r.bottom); | 1218 | sprintf(tmp, "Ignoring resize operation to (%ld %ld)", r.right, r.bottom); |
1219 | os::Printer::log(tmp); | 1219 | os::Printer::log(tmp); |
1220 | } | 1220 | } |
1221 | else | 1221 | else |
1222 | { | 1222 | { |
1223 | sprintf(tmp, "Resizing window (%ld %ld)", r.right, r.bottom); | 1223 | sprintf(tmp, "Resizing window (%ld %ld)", r.right, r.bottom); |
1224 | os::Printer::log(tmp); | 1224 | os::Printer::log(tmp); |
1225 | 1225 | ||
1226 | getVideoDriver()->OnResize(irr::core::dimension2du((u32)r.right, (u32)r.bottom)); | 1226 | getVideoDriver()->OnResize(irr::core::dimension2du((u32)r.right, (u32)r.bottom)); |
1227 | getWin32CursorControl()->OnResize(getVideoDriver()->getScreenSize()); | 1227 | getWin32CursorControl()->OnResize(getVideoDriver()->getScreenSize()); |
1228 | } | 1228 | } |
1229 | 1229 | ||
1230 | Resized = false; | 1230 | Resized = false; |
1231 | } | 1231 | } |
1232 | 1232 | ||
1233 | 1233 | ||
1234 | //! sets the caption of the window | 1234 | //! sets the caption of the window |
1235 | void CIrrDeviceWin32::setWindowCaption(const wchar_t* text) | 1235 | void CIrrDeviceWin32::setWindowCaption(const wchar_t* text) |
1236 | { | 1236 | { |
1237 | // We use SendMessage instead of SetText to ensure proper | 1237 | // We use SendMessage instead of SetText to ensure proper |
1238 | // function even in cases where the HWND was created in a different thread | 1238 | // function even in cases where the HWND was created in a different thread |
1239 | DWORD_PTR dwResult; | 1239 | DWORD_PTR dwResult; |
1240 | SendMessageTimeoutW(HWnd, WM_SETTEXT, 0, | 1240 | SendMessageTimeoutW(HWnd, WM_SETTEXT, 0, |
1241 | reinterpret_cast<LPARAM>(text), | 1241 | reinterpret_cast<LPARAM>(text), |
1242 | SMTO_ABORTIFHUNG, 2000, &dwResult); | 1242 | SMTO_ABORTIFHUNG, 2000, &dwResult); |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | 1245 | ||
1246 | //! presents a surface in the client area | 1246 | //! presents a surface in the client area |
1247 | bool CIrrDeviceWin32::present(video::IImage* image, void* windowId, core::rect<s32>* src) | 1247 | bool CIrrDeviceWin32::present(video::IImage* image, void* windowId, core::rect<s32>* src) |
1248 | { | 1248 | { |
1249 | HWND hwnd = HWnd; | 1249 | HWND hwnd = HWnd; |
1250 | if ( windowId ) | 1250 | if ( windowId ) |
1251 | hwnd = reinterpret_cast<HWND>(windowId); | 1251 | hwnd = reinterpret_cast<HWND>(windowId); |
1252 | 1252 | ||
1253 | HDC dc = GetDC(hwnd); | 1253 | HDC dc = GetDC(hwnd); |
1254 | 1254 | ||
1255 | if ( dc ) | 1255 | if ( dc ) |
1256 | { | 1256 | { |
1257 | RECT rect; | 1257 | RECT rect; |
1258 | GetClientRect(hwnd, &rect); | 1258 | GetClientRect(hwnd, &rect); |
1259 | const void* memory = (const void *)image->lock(); | 1259 | const void* memory = (const void *)image->lock(); |
1260 | 1260 | ||
1261 | BITMAPV4HEADER bi; | 1261 | BITMAPV4HEADER bi; |
1262 | ZeroMemory (&bi, sizeof(bi)); | 1262 | ZeroMemory (&bi, sizeof(bi)); |
1263 | bi.bV4Size = sizeof(BITMAPINFOHEADER); | 1263 | bi.bV4Size = sizeof(BITMAPINFOHEADER); |
1264 | bi.bV4BitCount = (WORD)image->getBitsPerPixel(); | 1264 | bi.bV4BitCount = (WORD)image->getBitsPerPixel(); |
1265 | bi.bV4Planes = 1; | 1265 | bi.bV4Planes = 1; |
1266 | bi.bV4Width = image->getDimension().Width; | 1266 | bi.bV4Width = image->getDimension().Width; |
1267 | bi.bV4Height = -((s32)image->getDimension().Height); | 1267 | bi.bV4Height = -((s32)image->getDimension().Height); |
1268 | bi.bV4V4Compression = BI_BITFIELDS; | 1268 | bi.bV4V4Compression = BI_BITFIELDS; |
1269 | bi.bV4AlphaMask = image->getAlphaMask(); | 1269 | bi.bV4AlphaMask = image->getAlphaMask(); |
1270 | bi.bV4RedMask = image->getRedMask(); | 1270 | bi.bV4RedMask = image->getRedMask(); |
1271 | bi.bV4GreenMask = image->getGreenMask(); | 1271 | bi.bV4GreenMask = image->getGreenMask(); |
1272 | bi.bV4BlueMask = image->getBlueMask(); | 1272 | bi.bV4BlueMask = image->getBlueMask(); |
1273 | 1273 | ||
1274 | if ( src ) | 1274 | if ( src ) |
1275 | { | 1275 | { |
1276 | StretchDIBits(dc, 0,0, rect.right, rect.bottom, | 1276 | StretchDIBits(dc, 0,0, rect.right, rect.bottom, |
1277 | src->UpperLeftCorner.X, src->UpperLeftCorner.Y, | 1277 | src->UpperLeftCorner.X, src->UpperLeftCorner.Y, |
1278 | src->getWidth(), src->getHeight(), | 1278 | src->getWidth(), src->getHeight(), |
1279 | memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY); | 1279 | memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY); |
1280 | } | 1280 | } |
1281 | else | 1281 | else |
1282 | { | 1282 | { |
1283 | StretchDIBits(dc, 0,0, rect.right, rect.bottom, | 1283 | StretchDIBits(dc, 0,0, rect.right, rect.bottom, |
1284 | 0, 0, image->getDimension().Width, image->getDimension().Height, | 1284 | 0, 0, image->getDimension().Width, image->getDimension().Height, |
1285 | memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY); | 1285 | memory, (const BITMAPINFO*)(&bi), DIB_RGB_COLORS, SRCCOPY); |
1286 | } | 1286 | } |
1287 | 1287 | ||
1288 | image->unlock(); | 1288 | image->unlock(); |
1289 | 1289 | ||
1290 | ReleaseDC(hwnd, dc); | 1290 | ReleaseDC(hwnd, dc); |
1291 | } | 1291 | } |
1292 | return true; | 1292 | return true; |
1293 | } | 1293 | } |
1294 | 1294 | ||
1295 | 1295 | ||
1296 | //! notifies the device that it should close itself | 1296 | //! notifies the device that it should close itself |
1297 | void CIrrDeviceWin32::closeDevice() | 1297 | void CIrrDeviceWin32::closeDevice() |
1298 | { | 1298 | { |
1299 | MSG msg; | 1299 | MSG msg; |
1300 | PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); | 1300 | PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); |
1301 | PostQuitMessage(0); | 1301 | PostQuitMessage(0); |
1302 | PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); | 1302 | PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT, PM_REMOVE); |
1303 | if (!ExternalWindow) | 1303 | if (!ExternalWindow) |
1304 | { | 1304 | { |
1305 | DestroyWindow(HWnd); | 1305 | DestroyWindow(HWnd); |
1306 | const fschar_t* ClassName = __TEXT("CIrrDeviceWin32"); | 1306 | const fschar_t* ClassName = __TEXT("CIrrDeviceWin32"); |
1307 | HINSTANCE hInstance = GetModuleHandle(0); | 1307 | HINSTANCE hInstance = GetModuleHandle(0); |
1308 | UnregisterClass(ClassName, hInstance); | 1308 | UnregisterClass(ClassName, hInstance); |
1309 | } | 1309 | } |
1310 | Close=true; | 1310 | Close=true; |
1311 | } | 1311 | } |
1312 | 1312 | ||
1313 | 1313 | ||
1314 | //! returns if window is active. if not, nothing needs to be drawn | 1314 | //! returns if window is active. if not, nothing needs to be drawn |
1315 | bool CIrrDeviceWin32::isWindowActive() const | 1315 | bool CIrrDeviceWin32::isWindowActive() const |
1316 | { | 1316 | { |
1317 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 1317 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
1318 | return (GetActiveWindow() == HWnd); | 1318 | return (GetActiveWindow() == HWnd); |
1319 | } | 1319 | } |
1320 | 1320 | ||
1321 | 1321 | ||
1322 | //! returns if window has focus | 1322 | //! returns if window has focus |
1323 | bool CIrrDeviceWin32::isWindowFocused() const | 1323 | bool CIrrDeviceWin32::isWindowFocused() const |
1324 | { | 1324 | { |
1325 | bool ret = (GetFocus() == HWnd); | 1325 | bool ret = (GetFocus() == HWnd); |
1326 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 1326 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
1327 | return ret; | 1327 | return ret; |
1328 | } | 1328 | } |
1329 | 1329 | ||
1330 | 1330 | ||
1331 | //! returns if window is minimized | 1331 | //! returns if window is minimized |
1332 | bool CIrrDeviceWin32::isWindowMinimized() const | 1332 | bool CIrrDeviceWin32::isWindowMinimized() const |
1333 | { | 1333 | { |
1334 | WINDOWPLACEMENT plc; | 1334 | WINDOWPLACEMENT plc; |
1335 | plc.length=sizeof(WINDOWPLACEMENT); | 1335 | plc.length=sizeof(WINDOWPLACEMENT); |
1336 | bool ret=false; | 1336 | bool ret=false; |
1337 | if (GetWindowPlacement(HWnd,&plc)) | 1337 | if (GetWindowPlacement(HWnd,&plc)) |
1338 | ret=(plc.showCmd & SW_SHOWMINIMIZED)!=0; | 1338 | ret=(plc.showCmd & SW_SHOWMINIMIZED)!=0; |
1339 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 1339 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
1340 | return ret; | 1340 | return ret; |
1341 | } | 1341 | } |
1342 | 1342 | ||
1343 | 1343 | ||
1344 | //! switches to fullscreen | 1344 | //! switches to fullscreen |
1345 | bool CIrrDeviceWin32::switchToFullScreen(bool reset) | 1345 | bool CIrrDeviceWin32::switchToFullScreen(bool reset) |
1346 | { | 1346 | { |
1347 | if (!CreationParams.Fullscreen) | 1347 | if (!CreationParams.Fullscreen) |
1348 | return true; | 1348 | return true; |
1349 | 1349 | ||
1350 | if (reset) | 1350 | if (reset) |
1351 | { | 1351 | { |
1352 | if (ChangedToFullScreen) | 1352 | if (ChangedToFullScreen) |
1353 | { | 1353 | { |
1354 | return (ChangeDisplaySettings(&DesktopMode,0)==DISP_CHANGE_SUCCESSFUL); | 1354 | return (ChangeDisplaySettings(&DesktopMode,0)==DISP_CHANGE_SUCCESSFUL); |
1355 | } | 1355 | } |
1356 | else | 1356 | else |
1357 | return true; | 1357 | return true; |
1358 | } | 1358 | } |
1359 | 1359 | ||
1360 | // use default values from current setting | 1360 | // use default values from current setting |
1361 | 1361 | ||
1362 | DEVMODE dm; | 1362 | DEVMODE dm; |
1363 | memset(&dm, 0, sizeof(dm)); | 1363 | memset(&dm, 0, sizeof(dm)); |
1364 | dm.dmSize = sizeof(dm); | 1364 | dm.dmSize = sizeof(dm); |
1365 | 1365 | ||
1366 | EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm); | 1366 | EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm); |
1367 | dm.dmPelsWidth = CreationParams.WindowSize.Width; | 1367 | dm.dmPelsWidth = CreationParams.WindowSize.Width; |
1368 | dm.dmPelsHeight = CreationParams.WindowSize.Height; | 1368 | dm.dmPelsHeight = CreationParams.WindowSize.Height; |
1369 | dm.dmBitsPerPel = CreationParams.Bits; | 1369 | dm.dmBitsPerPel = CreationParams.Bits; |
1370 | dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; | 1370 | dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY; |
1371 | 1371 | ||
1372 | LONG res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN); | 1372 | LONG res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN); |
1373 | if (res != DISP_CHANGE_SUCCESSFUL) | 1373 | if (res != DISP_CHANGE_SUCCESSFUL) |
1374 | { // try again without forcing display frequency | 1374 | { // try again without forcing display frequency |
1375 | dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; | 1375 | dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; |
1376 | res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN); | 1376 | res = ChangeDisplaySettings(&dm, CDS_FULLSCREEN); |
1377 | } | 1377 | } |
1378 | 1378 | ||
1379 | bool ret = false; | 1379 | bool ret = false; |
1380 | switch(res) | 1380 | switch(res) |
1381 | { | 1381 | { |
1382 | case DISP_CHANGE_SUCCESSFUL: | 1382 | case DISP_CHANGE_SUCCESSFUL: |
1383 | ChangedToFullScreen = true; | 1383 | ChangedToFullScreen = true; |
1384 | ret = true; | 1384 | ret = true; |
1385 | break; | 1385 | break; |
1386 | case DISP_CHANGE_RESTART: | 1386 | case DISP_CHANGE_RESTART: |
1387 | os::Printer::log("Switch to fullscreen: The computer must be restarted in order for the graphics mode to work.", ELL_ERROR); | 1387 | os::Printer::log("Switch to fullscreen: The computer must be restarted in order for the graphics mode to work.", ELL_ERROR); |
1388 | break; | 1388 | break; |
1389 | case DISP_CHANGE_BADFLAGS: | 1389 | case DISP_CHANGE_BADFLAGS: |
1390 | os::Printer::log("Switch to fullscreen: An invalid set of flags was passed in.", ELL_ERROR); | 1390 | os::Printer::log("Switch to fullscreen: An invalid set of flags was passed in.", ELL_ERROR); |
1391 | break; | 1391 | break; |
1392 | case DISP_CHANGE_BADPARAM: | 1392 | case DISP_CHANGE_BADPARAM: |
1393 | os::Printer::log("Switch to fullscreen: An invalid parameter was passed in. This can include an invalid flag or combination of flags.", ELL_ERROR); | 1393 | os::Printer::log("Switch to fullscreen: An invalid parameter was passed in. This can include an invalid flag or combination of flags.", ELL_ERROR); |
1394 | break; | 1394 | break; |
1395 | case DISP_CHANGE_FAILED: | 1395 | case DISP_CHANGE_FAILED: |
1396 | os::Printer::log("Switch to fullscreen: The display driver failed the specified graphics mode.", ELL_ERROR); | 1396 | os::Printer::log("Switch to fullscreen: The display driver failed the specified graphics mode.", ELL_ERROR); |
1397 | break; | 1397 | break; |
1398 | case DISP_CHANGE_BADMODE: | 1398 | case DISP_CHANGE_BADMODE: |
1399 | os::Printer::log("Switch to fullscreen: The graphics mode is not supported.", ELL_ERROR); | 1399 | os::Printer::log("Switch to fullscreen: The graphics mode is not supported.", ELL_ERROR); |
1400 | break; | 1400 | break; |
1401 | default: | 1401 | default: |
1402 | os::Printer::log("An unknown error occured while changing to fullscreen.", ELL_ERROR); | 1402 | os::Printer::log("An unknown error occured while changing to fullscreen.", ELL_ERROR); |
1403 | break; | 1403 | break; |
1404 | } | 1404 | } |
1405 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; | 1405 | _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX; |
1406 | return ret; | 1406 | return ret; |
1407 | } | 1407 | } |
1408 | 1408 | ||
1409 | 1409 | ||
1410 | //! returns the win32 cursor control | 1410 | //! returns the win32 cursor control |
1411 | CIrrDeviceWin32::CCursorControl* CIrrDeviceWin32::getWin32CursorControl() | 1411 | CIrrDeviceWin32::CCursorControl* CIrrDeviceWin32::getWin32CursorControl() |
1412 | { | 1412 | { |
1413 | return Win32CursorControl; | 1413 | return Win32CursorControl; |
1414 | } | 1414 | } |
1415 | 1415 | ||
1416 | 1416 | ||
1417 | //! \return Returns a pointer to a list with all video modes supported | 1417 | //! \return Returns a pointer to a list with all video modes supported |
1418 | //! by the gfx adapter. | 1418 | //! by the gfx adapter. |
1419 | video::IVideoModeList* CIrrDeviceWin32::getVideoModeList() | 1419 | video::IVideoModeList* CIrrDeviceWin32::getVideoModeList() |
1420 | { | 1420 | { |
1421 | if (!VideoModeList.getVideoModeCount()) | 1421 | if (!VideoModeList.getVideoModeCount()) |
1422 | { | 1422 | { |
1423 | // enumerate video modes. | 1423 | // enumerate video modes. |
1424 | DWORD i=0; | 1424 | DWORD i=0; |
1425 | DEVMODE mode; | 1425 | DEVMODE mode; |
1426 | memset(&mode, 0, sizeof(mode)); | 1426 | memset(&mode, 0, sizeof(mode)); |
1427 | mode.dmSize = sizeof(mode); | 1427 | mode.dmSize = sizeof(mode); |
1428 | 1428 | ||
1429 | while (EnumDisplaySettings(NULL, i, &mode)) | 1429 | while (EnumDisplaySettings(NULL, i, &mode)) |
1430 | { | 1430 | { |
1431 | VideoModeList.addMode(core::dimension2d<u32>(mode.dmPelsWidth, mode.dmPelsHeight), | 1431 | VideoModeList.addMode(core::dimension2d<u32>(mode.dmPelsWidth, mode.dmPelsHeight), |
1432 | mode.dmBitsPerPel); | 1432 | mode.dmBitsPerPel); |
1433 | 1433 | ||
1434 | ++i; | 1434 | ++i; |
1435 | } | 1435 | } |
1436 | 1436 | ||
1437 | if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode)) | 1437 | if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &mode)) |
1438 | VideoModeList.setDesktop(mode.dmBitsPerPel, core::dimension2d<u32>(mode.dmPelsWidth, mode.dmPelsHeight)); | 1438 | VideoModeList.setDesktop(mode.dmBitsPerPel, core::dimension2d<u32>(mode.dmPelsWidth, mode.dmPelsHeight)); |
1439 | } | 1439 | } |
1440 | 1440 | ||
1441 | return &VideoModeList; | 1441 | return &VideoModeList; |
1442 | } | 1442 | } |
1443 | 1443 | ||
1444 | typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); | 1444 | typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); |
1445 | // Needed for old windows apis | 1445 | // Needed for old windows apis |
1446 | // depending on the SDK version and compilers some defines might be available | 1446 | // depending on the SDK version and compilers some defines might be available |
1447 | // or not | 1447 | // or not |
1448 | #ifndef PRODUCT_ULTIMATE | 1448 | #ifndef PRODUCT_ULTIMATE |
1449 | #define PRODUCT_ULTIMATE 0x00000001 | 1449 | #define PRODUCT_ULTIMATE 0x00000001 |
1450 | #define PRODUCT_HOME_BASIC 0x00000002 | 1450 | #define PRODUCT_HOME_BASIC 0x00000002 |
1451 | #define PRODUCT_HOME_PREMIUM 0x00000003 | 1451 | #define PRODUCT_HOME_PREMIUM 0x00000003 |
1452 | #define PRODUCT_ENTERPRISE 0x00000004 | 1452 | #define PRODUCT_ENTERPRISE 0x00000004 |
1453 | #define PRODUCT_HOME_BASIC_N 0x00000005 | 1453 | #define PRODUCT_HOME_BASIC_N 0x00000005 |
1454 | #define PRODUCT_BUSINESS 0x00000006 | 1454 | #define PRODUCT_BUSINESS 0x00000006 |
1455 | #define PRODUCT_STARTER 0x0000000B | 1455 | #define PRODUCT_STARTER 0x0000000B |
1456 | #endif | 1456 | #endif |
1457 | #ifndef PRODUCT_ULTIMATE_N | 1457 | #ifndef PRODUCT_ULTIMATE_N |
1458 | #define PRODUCT_BUSINESS_N 0x00000010 | 1458 | #define PRODUCT_BUSINESS_N 0x00000010 |
1459 | #define PRODUCT_HOME_PREMIUM_N 0x0000001A | 1459 | #define PRODUCT_HOME_PREMIUM_N 0x0000001A |
1460 | #define PRODUCT_ENTERPRISE_N 0x0000001B | 1460 | #define PRODUCT_ENTERPRISE_N 0x0000001B |
1461 | #define PRODUCT_ULTIMATE_N 0x0000001C | 1461 | #define PRODUCT_ULTIMATE_N 0x0000001C |
1462 | #endif | 1462 | #endif |
1463 | #ifndef PRODUCT_STARTER_N | 1463 | #ifndef PRODUCT_STARTER_N |
1464 | #define PRODUCT_STARTER_N 0x0000002F | 1464 | #define PRODUCT_STARTER_N 0x0000002F |
1465 | #endif | 1465 | #endif |
1466 | #ifndef PRODUCT_PROFESSIONAL | 1466 | #ifndef PRODUCT_PROFESSIONAL |
1467 | #define PRODUCT_PROFESSIONAL 0x00000030 | 1467 | #define PRODUCT_PROFESSIONAL 0x00000030 |
1468 | #define PRODUCT_PROFESSIONAL_N 0x00000031 | 1468 | #define PRODUCT_PROFESSIONAL_N 0x00000031 |
1469 | #endif | 1469 | #endif |
1470 | #ifndef PRODUCT_ULTIMATE_E | 1470 | #ifndef PRODUCT_ULTIMATE_E |
1471 | #define PRODUCT_STARTER_E 0x00000042 | 1471 | #define PRODUCT_STARTER_E 0x00000042 |
1472 | #define PRODUCT_HOME_BASIC_E 0x00000043 | 1472 | #define PRODUCT_HOME_BASIC_E 0x00000043 |
1473 | #define PRODUCT_HOME_PREMIUM_E 0x00000044 | 1473 | #define PRODUCT_HOME_PREMIUM_E 0x00000044 |
1474 | #define PRODUCT_PROFESSIONAL_E 0x00000045 | 1474 | #define PRODUCT_PROFESSIONAL_E 0x00000045 |
1475 | #define PRODUCT_ENTERPRISE_E 0x00000046 | 1475 | #define PRODUCT_ENTERPRISE_E 0x00000046 |
1476 | #define PRODUCT_ULTIMATE_E 0x00000047 | 1476 | #define PRODUCT_ULTIMATE_E 0x00000047 |
1477 | #endif | 1477 | #endif |
1478 | 1478 | ||
1479 | void CIrrDeviceWin32::getWindowsVersion(core::stringc& out) | 1479 | void CIrrDeviceWin32::getWindowsVersion(core::stringc& out) |
1480 | { | 1480 | { |
1481 | OSVERSIONINFOEX osvi; | 1481 | OSVERSIONINFOEX osvi; |
1482 | PGPI pGPI; | 1482 | PGPI pGPI; |
1483 | BOOL bOsVersionInfoEx; | 1483 | BOOL bOsVersionInfoEx; |
1484 | 1484 | ||
1485 | ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); | 1485 | ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); |
1486 | osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); | 1486 | osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); |
1487 | 1487 | ||
1488 | bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi); | 1488 | bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi); |
1489 | if (!bOsVersionInfoEx) | 1489 | if (!bOsVersionInfoEx) |
1490 | { | 1490 | { |
1491 | osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); | 1491 | osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
1492 | if (! GetVersionEx((OSVERSIONINFO *) &osvi)) | 1492 | if (! GetVersionEx((OSVERSIONINFO *) &osvi)) |
1493 | return; | 1493 | return; |
1494 | } | 1494 | } |
1495 | 1495 | ||
1496 | switch (osvi.dwPlatformId) | 1496 | switch (osvi.dwPlatformId) |
1497 | { | 1497 | { |
1498 | case VER_PLATFORM_WIN32_NT: | 1498 | case VER_PLATFORM_WIN32_NT: |
1499 | if (osvi.dwMajorVersion <= 4) | 1499 | if (osvi.dwMajorVersion <= 4) |
1500 | out.append("Microsoft Windows NT "); | 1500 | out.append("Microsoft Windows NT "); |
1501 | else | 1501 | else |
1502 | if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) | 1502 | if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) |
1503 | out.append("Microsoft Windows 2000 "); | 1503 | out.append("Microsoft Windows 2000 "); |
1504 | else | 1504 | else |
1505 | if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) | 1505 | if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) |
1506 | out.append("Microsoft Windows XP "); | 1506 | out.append("Microsoft Windows XP "); |
1507 | else | 1507 | else |
1508 | if (osvi.dwMajorVersion == 6 ) | 1508 | if (osvi.dwMajorVersion == 6 ) |
1509 | { | 1509 | { |
1510 | if (osvi.dwMinorVersion == 0) | 1510 | if (osvi.dwMinorVersion == 0) |
1511 | { | 1511 | { |
1512 | if (osvi.wProductType == VER_NT_WORKSTATION) | 1512 | if (osvi.wProductType == VER_NT_WORKSTATION) |
1513 | out.append("Microsoft Windows Vista "); | 1513 | out.append("Microsoft Windows Vista "); |
1514 | else | 1514 | else |
1515 | out.append("Microsoft Windows Server 2008 "); | 1515 | out.append("Microsoft Windows Server 2008 "); |
1516 | } | 1516 | } |
1517 | else if (osvi.dwMinorVersion == 1) | 1517 | else if (osvi.dwMinorVersion == 1) |
1518 | { | 1518 | { |
1519 | if (osvi.wProductType == VER_NT_WORKSTATION) | 1519 | if (osvi.wProductType == VER_NT_WORKSTATION) |
1520 | out.append("Microsoft Windows 7 "); | 1520 | out.append("Microsoft Windows 7 "); |
1521 | else | 1521 | else |
1522 | out.append("Microsoft Windows Server 2008 R2 "); | 1522 | out.append("Microsoft Windows Server 2008 R2 "); |
1523 | } | 1523 | } |
1524 | } | 1524 | } |
1525 | 1525 | ||
1526 | if (bOsVersionInfoEx) | 1526 | if (bOsVersionInfoEx) |
1527 | { | 1527 | { |
1528 | if (osvi.dwMajorVersion == 6) | 1528 | if (osvi.dwMajorVersion == 6) |
1529 | { | 1529 | { |
1530 | DWORD dwType; | 1530 | DWORD dwType; |
1531 | pGPI = (PGPI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo"); | 1531 | pGPI = (PGPI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo"); |
1532 | pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType); | 1532 | pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType); |
1533 | 1533 | ||
1534 | switch (dwType) | 1534 | switch (dwType) |
1535 | { | 1535 | { |
1536 | case PRODUCT_ULTIMATE: | 1536 | case PRODUCT_ULTIMATE: |
1537 | case PRODUCT_ULTIMATE_E: | 1537 | case PRODUCT_ULTIMATE_E: |
1538 | case PRODUCT_ULTIMATE_N: | 1538 | case PRODUCT_ULTIMATE_N: |
1539 | out.append("Ultimate Edition "); | 1539 | out.append("Ultimate Edition "); |
1540 | break; | 1540 | break; |
1541 | case PRODUCT_PROFESSIONAL: | 1541 | case PRODUCT_PROFESSIONAL: |
1542 | case PRODUCT_PROFESSIONAL_E: | 1542 | case PRODUCT_PROFESSIONAL_E: |
1543 | case PRODUCT_PROFESSIONAL_N: | 1543 | case PRODUCT_PROFESSIONAL_N: |
1544 | out.append("Professional Edition "); | 1544 | out.append("Professional Edition "); |
1545 | break; | 1545 | break; |
1546 | case PRODUCT_HOME_BASIC: | 1546 | case PRODUCT_HOME_BASIC: |
1547 | case PRODUCT_HOME_BASIC_E: | 1547 | case PRODUCT_HOME_BASIC_E: |
1548 | case PRODUCT_HOME_BASIC_N: | 1548 | case PRODUCT_HOME_BASIC_N: |
1549 | out.append("Home Basic Edition "); | 1549 | out.append("Home Basic Edition "); |
1550 | break; | 1550 | break; |
1551 | case PRODUCT_HOME_PREMIUM: | 1551 | case PRODUCT_HOME_PREMIUM: |
1552 | case PRODUCT_HOME_PREMIUM_E: | 1552 | case PRODUCT_HOME_PREMIUM_E: |
1553 | case PRODUCT_HOME_PREMIUM_N: | 1553 | case PRODUCT_HOME_PREMIUM_N: |
1554 | out.append("Home Premium Edition "); | 1554 | out.append("Home Premium Edition "); |
1555 | break; | 1555 | break; |
1556 | case PRODUCT_ENTERPRISE: | 1556 | case PRODUCT_ENTERPRISE: |
1557 | case PRODUCT_ENTERPRISE_E: | 1557 | case PRODUCT_ENTERPRISE_E: |
1558 | case PRODUCT_ENTERPRISE_N: | 1558 | case PRODUCT_ENTERPRISE_N: |
1559 | out.append("Enterprise Edition "); | 1559 | out.append("Enterprise Edition "); |
1560 | break; | 1560 | break; |
1561 | case PRODUCT_BUSINESS: | 1561 | case PRODUCT_BUSINESS: |
1562 | case PRODUCT_BUSINESS_N: | 1562 | case PRODUCT_BUSINESS_N: |
1563 | out.append("Business Edition "); | 1563 | out.append("Business Edition "); |
1564 | break; | 1564 | break; |
1565 | case PRODUCT_STARTER: | 1565 | case PRODUCT_STARTER: |
1566 | case PRODUCT_STARTER_E: | 1566 | case PRODUCT_STARTER_E: |
1567 | case PRODUCT_STARTER_N: | 1567 | case PRODUCT_STARTER_N: |
1568 | out.append("Starter Edition "); | 1568 | out.append("Starter Edition "); |
1569 | break; | 1569 | break; |
1570 | } | 1570 | } |
1571 | } | 1571 | } |
1572 | #ifdef VER_SUITE_ENTERPRISE | 1572 | #ifdef VER_SUITE_ENTERPRISE |
1573 | else | 1573 | else |
1574 | if (osvi.wProductType == VER_NT_WORKSTATION) | 1574 | if (osvi.wProductType == VER_NT_WORKSTATION) |
1575 | { | 1575 | { |
1576 | #ifndef __BORLANDC__ | 1576 | #ifndef __BORLANDC__ |
1577 | if( osvi.wSuiteMask & VER_SUITE_PERSONAL ) | 1577 | if( osvi.wSuiteMask & VER_SUITE_PERSONAL ) |
1578 | out.append("Personal "); | 1578 | out.append("Personal "); |
1579 | else | 1579 | else |
1580 | out.append("Professional "); | 1580 | out.append("Professional "); |
1581 | #endif | 1581 | #endif |
1582 | } | 1582 | } |
1583 | else if (osvi.wProductType == VER_NT_SERVER) | 1583 | else if (osvi.wProductType == VER_NT_SERVER) |
1584 | { | 1584 | { |
1585 | if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) | 1585 | if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) |
1586 | out.append("DataCenter Server "); | 1586 | out.append("DataCenter Server "); |
1587 | else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) | 1587 | else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) |
1588 | out.append("Advanced Server "); | 1588 | out.append("Advanced Server "); |
1589 | else | 1589 | else |
1590 | out.append("Server "); | 1590 | out.append("Server "); |
1591 | } | 1591 | } |
1592 | #endif | 1592 | #endif |
1593 | } | 1593 | } |
1594 | else | 1594 | else |
1595 | { | 1595 | { |
1596 | HKEY hKey; | 1596 | HKEY hKey; |
1597 | char szProductType[80]; | 1597 | char szProductType[80]; |
1598 | DWORD dwBufLen; | 1598 | DWORD dwBufLen; |
1599 | 1599 | ||
1600 | RegOpenKeyEx( HKEY_LOCAL_MACHINE, | 1600 | RegOpenKeyEx( HKEY_LOCAL_MACHINE, |
1601 | __TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), | 1601 | __TEXT("SYSTEM\\CurrentControlSet\\Control\\ProductOptions"), |
1602 | 0, KEY_QUERY_VALUE, &hKey ); | 1602 | 0, KEY_QUERY_VALUE, &hKey ); |
1603 | RegQueryValueEx( hKey, __TEXT("ProductType"), NULL, NULL, | 1603 | RegQueryValueEx( hKey, __TEXT("ProductType"), NULL, NULL, |
1604 | (LPBYTE) szProductType, &dwBufLen); | 1604 | (LPBYTE) szProductType, &dwBufLen); |
1605 | RegCloseKey( hKey ); | 1605 | RegCloseKey( hKey ); |
1606 | 1606 | ||
1607 | if (_strcmpi( "WINNT", szProductType) == 0 ) | 1607 | if (_strcmpi( "WINNT", szProductType) == 0 ) |
1608 | out.append("Professional "); | 1608 | out.append("Professional "); |
1609 | if (_strcmpi( "LANMANNT", szProductType) == 0) | 1609 | if (_strcmpi( "LANMANNT", szProductType) == 0) |
1610 | out.append("Server "); | 1610 | out.append("Server "); |
1611 | if (_strcmpi( "SERVERNT", szProductType) == 0) | 1611 | if (_strcmpi( "SERVERNT", szProductType) == 0) |
1612 | out.append("Advanced Server "); | 1612 | out.append("Advanced Server "); |
1613 | } | 1613 | } |
1614 | 1614 | ||
1615 | // Display version, service pack (if any), and build number. | 1615 | // Display version, service pack (if any), and build number. |
1616 | 1616 | ||
1617 | char tmp[255]; | 1617 | char tmp[255]; |
1618 | 1618 | ||
1619 | if (osvi.dwMajorVersion <= 4 ) | 1619 | if (osvi.dwMajorVersion <= 4 ) |
1620 | { | 1620 | { |
1621 | sprintf(tmp, "version %ld.%ld %s (Build %ld)", | 1621 | sprintf(tmp, "version %ld.%ld %s (Build %ld)", |
1622 | osvi.dwMajorVersion, | 1622 | osvi.dwMajorVersion, |
1623 | osvi.dwMinorVersion, | 1623 | osvi.dwMinorVersion, |
1624 | irr::core::stringc(osvi.szCSDVersion).c_str(), | 1624 | irr::core::stringc(osvi.szCSDVersion).c_str(), |
1625 | osvi.dwBuildNumber & 0xFFFF); | 1625 | osvi.dwBuildNumber & 0xFFFF); |
1626 | } | 1626 | } |
1627 | else | 1627 | else |
1628 | { | 1628 | { |
1629 | sprintf(tmp, "%s (Build %ld)", irr::core::stringc(osvi.szCSDVersion).c_str(), | 1629 | sprintf(tmp, "%s (Build %ld)", irr::core::stringc(osvi.szCSDVersion).c_str(), |
1630 | osvi.dwBuildNumber & 0xFFFF); | 1630 | osvi.dwBuildNumber & 0xFFFF); |
1631 | } | 1631 | } |
1632 | 1632 | ||
1633 | out.append(tmp); | 1633 | out.append(tmp); |
1634 | break; | 1634 | break; |
1635 | 1635 | ||
1636 | case VER_PLATFORM_WIN32_WINDOWS: | 1636 | case VER_PLATFORM_WIN32_WINDOWS: |
1637 | 1637 | ||
1638 | if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) | 1638 | if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) |
1639 | { | 1639 | { |
1640 | out.append("Microsoft Windows 95 "); | 1640 | out.append("Microsoft Windows 95 "); |
1641 | if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' ) | 1641 | if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' ) |
1642 | out.append("OSR2 " ); | 1642 | out.append("OSR2 " ); |
1643 | } | 1643 | } |
1644 | 1644 | ||
1645 | if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) | 1645 | if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) |
1646 | { | 1646 | { |
1647 | out.append("Microsoft Windows 98 "); | 1647 | out.append("Microsoft Windows 98 "); |
1648 | if ( osvi.szCSDVersion[1] == 'A' ) | 1648 | if ( osvi.szCSDVersion[1] == 'A' ) |
1649 | out.append( "SE " ); | 1649 | out.append( "SE " ); |
1650 | } | 1650 | } |
1651 | 1651 | ||
1652 | if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) | 1652 | if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) |
1653 | out.append("Microsoft Windows Me "); | 1653 | out.append("Microsoft Windows Me "); |
1654 | 1654 | ||
1655 | break; | 1655 | break; |
1656 | 1656 | ||
1657 | case VER_PLATFORM_WIN32s: | 1657 | case VER_PLATFORM_WIN32s: |
1658 | out.append("Microsoft Win32s "); | 1658 | out.append("Microsoft Win32s "); |
1659 | break; | 1659 | break; |
1660 | } | 1660 | } |
1661 | } | 1661 | } |
1662 | 1662 | ||
1663 | //! Notifies the device, that it has been resized | 1663 | //! Notifies the device, that it has been resized |
1664 | void CIrrDeviceWin32::OnResized() | 1664 | void CIrrDeviceWin32::OnResized() |
1665 | { | 1665 | { |
1666 | Resized = true; | 1666 | Resized = true; |
1667 | } | 1667 | } |
1668 | 1668 | ||
1669 | //! Sets if the window should be resizable in windowed mode. | 1669 | //! Sets if the window should be resizable in windowed mode. |
1670 | void CIrrDeviceWin32::setResizable(bool resize) | 1670 | void CIrrDeviceWin32::setResizable(bool resize) |
1671 | { | 1671 | { |
1672 | if (ExternalWindow || !getVideoDriver() || CreationParams.Fullscreen) | 1672 | if (ExternalWindow || !getVideoDriver() || CreationParams.Fullscreen) |
1673 | return; | 1673 | return; |
1674 | 1674 | ||
1675 | LONG_PTR style = WS_POPUP; | 1675 | LONG_PTR style = WS_POPUP; |
1676 | 1676 | ||
1677 | if (!resize) | 1677 | if (!resize) |
1678 | style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; | 1678 | style = WS_SYSMENU | WS_BORDER | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; |
1679 | else | 1679 | else |
1680 | style = WS_THICKFRAME | WS_SYSMENU | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; | 1680 | style = WS_THICKFRAME | WS_SYSMENU | WS_CAPTION | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; |
1681 | 1681 | ||
1682 | if (!SetWindowLongPtr(HWnd, GWL_STYLE, style)) | 1682 | if (!SetWindowLongPtr(HWnd, GWL_STYLE, style)) |
1683 | os::Printer::log("Could not change window style."); | 1683 | os::Printer::log("Could not change window style."); |
1684 | 1684 | ||
1685 | RECT clientSize; | 1685 | RECT clientSize; |
1686 | clientSize.top = 0; | 1686 | clientSize.top = 0; |
1687 | clientSize.left = 0; | 1687 | clientSize.left = 0; |
1688 | clientSize.right = getVideoDriver()->getScreenSize().Width; | 1688 | clientSize.right = getVideoDriver()->getScreenSize().Width; |
1689 | clientSize.bottom = getVideoDriver()->getScreenSize().Height; | 1689 | clientSize.bottom = getVideoDriver()->getScreenSize().Height; |
1690 | 1690 | ||
1691 | AdjustWindowRect(&clientSize, style, FALSE); | 1691 | AdjustWindowRect(&clientSize, style, FALSE); |
1692 | 1692 | ||
1693 | const s32 realWidth = clientSize.right - clientSize.left; | 1693 | const s32 realWidth = clientSize.right - clientSize.left; |
1694 | const s32 realHeight = clientSize.bottom - clientSize.top; | 1694 | const s32 realHeight = clientSize.bottom - clientSize.top; |
1695 | 1695 | ||
1696 | const s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; | 1696 | const s32 windowLeft = (GetSystemMetrics(SM_CXSCREEN) - realWidth) / 2; |
1697 | const s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; | 1697 | const s32 windowTop = (GetSystemMetrics(SM_CYSCREEN) - realHeight) / 2; |
1698 | 1698 | ||
1699 | SetWindowPos(HWnd, HWND_TOP, windowLeft, windowTop, realWidth, realHeight, | 1699 | SetWindowPos(HWnd, HWND_TOP, windowLeft, windowTop, realWidth, realHeight, |
1700 | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_SHOWWINDOW); | 1700 | SWP_FRAMECHANGED | SWP_NOMOVE | SWP_SHOWWINDOW); |
1701 | 1701 | ||
1702 | static_cast<CCursorControl*>(CursorControl)->updateBorderSize(CreationParams.Fullscreen, resize); | 1702 | static_cast<CCursorControl*>(CursorControl)->updateBorderSize(CreationParams.Fullscreen, resize); |
1703 | } | 1703 | } |
1704 | 1704 | ||
1705 | 1705 | ||
1706 | //! Minimizes the window. | 1706 | //! Minimizes the window. |
1707 | void CIrrDeviceWin32::minimizeWindow() | 1707 | void CIrrDeviceWin32::minimizeWindow() |
1708 | { | 1708 | { |
1709 | WINDOWPLACEMENT wndpl; | 1709 | WINDOWPLACEMENT wndpl; |
1710 | wndpl.length = sizeof(WINDOWPLACEMENT); | 1710 | wndpl.length = sizeof(WINDOWPLACEMENT); |
1711 | GetWindowPlacement(HWnd, &wndpl); | 1711 | GetWindowPlacement(HWnd, &wndpl); |
1712 | wndpl.showCmd = SW_SHOWMINNOACTIVE; | 1712 | wndpl.showCmd = SW_SHOWMINNOACTIVE; |
1713 | SetWindowPlacement(HWnd, &wndpl); | 1713 | SetWindowPlacement(HWnd, &wndpl); |
1714 | } | 1714 | } |
1715 | 1715 | ||
1716 | 1716 | ||
1717 | //! Maximizes the window. | 1717 | //! Maximizes the window. |
1718 | void CIrrDeviceWin32::maximizeWindow() | 1718 | void CIrrDeviceWin32::maximizeWindow() |
1719 | { | 1719 | { |
1720 | WINDOWPLACEMENT wndpl; | 1720 | WINDOWPLACEMENT wndpl; |
1721 | wndpl.length = sizeof(WINDOWPLACEMENT); | 1721 | wndpl.length = sizeof(WINDOWPLACEMENT); |
1722 | GetWindowPlacement(HWnd, &wndpl); | 1722 | GetWindowPlacement(HWnd, &wndpl); |
1723 | wndpl.showCmd = SW_SHOWMAXIMIZED; | 1723 | wndpl.showCmd = SW_SHOWMAXIMIZED; |
1724 | SetWindowPlacement(HWnd, &wndpl); | 1724 | SetWindowPlacement(HWnd, &wndpl); |
1725 | } | 1725 | } |
1726 | 1726 | ||
1727 | 1727 | ||
1728 | //! Restores the window to its original size. | 1728 | //! Restores the window to its original size. |
1729 | void CIrrDeviceWin32::restoreWindow() | 1729 | void CIrrDeviceWin32::restoreWindow() |
1730 | { | 1730 | { |
1731 | WINDOWPLACEMENT wndpl; | 1731 | WINDOWPLACEMENT wndpl; |
1732 | wndpl.length = sizeof(WINDOWPLACEMENT); | 1732 | wndpl.length = sizeof(WINDOWPLACEMENT); |
1733 | GetWindowPlacement(HWnd, &wndpl); | 1733 | GetWindowPlacement(HWnd, &wndpl); |
1734 | wndpl.showCmd = SW_SHOWNORMAL; | 1734 | wndpl.showCmd = SW_SHOWNORMAL; |
1735 | SetWindowPlacement(HWnd, &wndpl); | 1735 | SetWindowPlacement(HWnd, &wndpl); |
1736 | } | 1736 | } |
1737 | 1737 | ||
1738 | 1738 | ||
1739 | bool CIrrDeviceWin32::activateJoysticks(core::array<SJoystickInfo> & joystickInfo) | 1739 | bool CIrrDeviceWin32::activateJoysticks(core::array<SJoystickInfo> & joystickInfo) |
1740 | { | 1740 | { |
1741 | if (JoyControl) | 1741 | if (JoyControl) |
1742 | return JoyControl->activateJoysticks(joystickInfo); | 1742 | return JoyControl->activateJoysticks(joystickInfo); |
1743 | else | 1743 | else |
1744 | return false; | 1744 | return false; |
1745 | } | 1745 | } |
1746 | 1746 | ||
1747 | 1747 | ||
1748 | //! Set the current Gamma Value for the Display | 1748 | //! Set the current Gamma Value for the Display |
1749 | bool CIrrDeviceWin32::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ) | 1749 | bool CIrrDeviceWin32::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ) |
1750 | { | 1750 | { |
1751 | bool r; | 1751 | bool r; |
1752 | u16 ramp[3][256]; | 1752 | u16 ramp[3][256]; |
1753 | 1753 | ||
1754 | calculateGammaRamp( ramp[0], red, brightness, contrast ); | 1754 | calculateGammaRamp( ramp[0], red, brightness, contrast ); |
1755 | calculateGammaRamp( ramp[1], green, brightness, contrast ); | 1755 | calculateGammaRamp( ramp[1], green, brightness, contrast ); |
1756 | calculateGammaRamp( ramp[2], blue, brightness, contrast ); | 1756 | calculateGammaRamp( ramp[2], blue, brightness, contrast ); |
1757 | 1757 | ||
1758 | HDC dc = GetDC(0); | 1758 | HDC dc = GetDC(0); |
1759 | r = SetDeviceGammaRamp ( dc, ramp ) == TRUE; | 1759 | r = SetDeviceGammaRamp ( dc, ramp ) == TRUE; |
1760 | ReleaseDC(HWnd, dc); | 1760 | ReleaseDC(HWnd, dc); |
1761 | return r; | 1761 | return r; |
1762 | } | 1762 | } |
1763 | 1763 | ||
1764 | //! Get the current Gamma Value for the Display | 1764 | //! Get the current Gamma Value for the Display |
1765 | bool CIrrDeviceWin32::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) | 1765 | bool CIrrDeviceWin32::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) |
1766 | { | 1766 | { |
1767 | bool r; | 1767 | bool r; |
1768 | u16 ramp[3][256]; | 1768 | u16 ramp[3][256]; |
1769 | 1769 | ||
1770 | HDC dc = GetDC(0); | 1770 | HDC dc = GetDC(0); |
1771 | r = GetDeviceGammaRamp ( dc, ramp ) == TRUE; | 1771 | r = GetDeviceGammaRamp ( dc, ramp ) == TRUE; |
1772 | ReleaseDC(HWnd, dc); | 1772 | ReleaseDC(HWnd, dc); |
1773 | 1773 | ||
1774 | if ( r ) | 1774 | if ( r ) |
1775 | { | 1775 | { |
1776 | calculateGammaFromRamp(red, ramp[0]); | 1776 | calculateGammaFromRamp(red, ramp[0]); |
1777 | calculateGammaFromRamp(green, ramp[1]); | 1777 | calculateGammaFromRamp(green, ramp[1]); |
1778 | calculateGammaFromRamp(blue, ramp[2]); | 1778 | calculateGammaFromRamp(blue, ramp[2]); |
1779 | } | 1779 | } |
1780 | 1780 | ||
1781 | brightness = 0.f; | 1781 | brightness = 0.f; |
1782 | contrast = 0.f; | 1782 | contrast = 0.f; |
1783 | 1783 | ||
1784 | return r; | 1784 | return r; |
1785 | 1785 | ||
1786 | } | 1786 | } |
1787 | 1787 | ||
1788 | 1788 | ||
1789 | //! Process system events | 1789 | //! Process system events |
1790 | void CIrrDeviceWin32::handleSystemMessages() | 1790 | void CIrrDeviceWin32::handleSystemMessages() |
1791 | { | 1791 | { |
1792 | MSG msg; | 1792 | MSG msg; |
1793 | 1793 | ||
1794 | while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) | 1794 | while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) |
1795 | { | 1795 | { |
1796 | // No message translation because we don't use WM_CHAR and it would conflict with our | 1796 | // No message translation because we don't use WM_CHAR and it would conflict with our |
1797 | // deadkey handling. | 1797 | // deadkey handling. |
1798 | 1798 | ||
1799 | if (ExternalWindow && msg.hwnd == HWnd) | 1799 | if (ExternalWindow && msg.hwnd == HWnd) |
1800 | WndProc(HWnd, msg.message, msg.wParam, msg.lParam); | 1800 | WndProc(HWnd, msg.message, msg.wParam, msg.lParam); |
1801 | else | 1801 | else |
1802 | DispatchMessage(&msg); | 1802 | DispatchMessage(&msg); |
1803 | 1803 | ||
1804 | if (msg.message == WM_QUIT) | 1804 | if (msg.message == WM_QUIT) |
1805 | Close = true; | 1805 | Close = true; |
1806 | } | 1806 | } |
1807 | } | 1807 | } |
1808 | 1808 | ||
1809 | 1809 | ||
1810 | //! Remove all messages pending in the system message loop | 1810 | //! Remove all messages pending in the system message loop |
1811 | void CIrrDeviceWin32::clearSystemMessages() | 1811 | void CIrrDeviceWin32::clearSystemMessages() |
1812 | { | 1812 | { |
1813 | MSG msg; | 1813 | MSG msg; |
1814 | while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) | 1814 | while (PeekMessage(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)) |
1815 | {} | 1815 | {} |
1816 | while (PeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE)) | 1816 | while (PeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE)) |
1817 | {} | 1817 | {} |
1818 | } | 1818 | } |
1819 | 1819 | ||
1820 | // shows last error in a messagebox to help internal debugging. | 1820 | // shows last error in a messagebox to help internal debugging. |
1821 | void CIrrDeviceWin32::ReportLastWinApiError() | 1821 | void CIrrDeviceWin32::ReportLastWinApiError() |
1822 | { | 1822 | { |
1823 | // (based on code from ovidiucucu from http://www.codeguru.com/forum/showthread.php?t=318721) | 1823 | // (based on code from ovidiucucu from http://www.codeguru.com/forum/showthread.php?t=318721) |
1824 | LPCTSTR pszCaption = __TEXT("Windows SDK Error Report"); | 1824 | LPCTSTR pszCaption = __TEXT("Windows SDK Error Report"); |
1825 | DWORD dwError = GetLastError(); | 1825 | DWORD dwError = GetLastError(); |
1826 | 1826 | ||
1827 | if(NOERROR == dwError) | 1827 | if(NOERROR == dwError) |
1828 | { | 1828 | { |
1829 | MessageBox(NULL, __TEXT("No error"), pszCaption, MB_OK); | 1829 | MessageBox(NULL, __TEXT("No error"), pszCaption, MB_OK); |
1830 | } | 1830 | } |
1831 | else | 1831 | else |
1832 | { | 1832 | { |
1833 | const DWORD dwFormatControl = FORMAT_MESSAGE_ALLOCATE_BUFFER | | 1833 | const DWORD dwFormatControl = FORMAT_MESSAGE_ALLOCATE_BUFFER | |
1834 | FORMAT_MESSAGE_IGNORE_INSERTS | | 1834 | FORMAT_MESSAGE_IGNORE_INSERTS | |
1835 | FORMAT_MESSAGE_FROM_SYSTEM; | 1835 | FORMAT_MESSAGE_FROM_SYSTEM; |
1836 | 1836 | ||
1837 | LPVOID pTextBuffer = NULL; | 1837 | LPVOID pTextBuffer = NULL; |
1838 | DWORD dwCount = FormatMessage(dwFormatControl, | 1838 | DWORD dwCount = FormatMessage(dwFormatControl, |
1839 | NULL, | 1839 | NULL, |
1840 | dwError, | 1840 | dwError, |
1841 | 0, | 1841 | 0, |
1842 | (LPTSTR) &pTextBuffer, | 1842 | (LPTSTR) &pTextBuffer, |
1843 | 0, | 1843 | 0, |
1844 | NULL); | 1844 | NULL); |
1845 | if(0 != dwCount) | 1845 | if(0 != dwCount) |
1846 | { | 1846 | { |
1847 | MessageBox(NULL, (LPCTSTR)pTextBuffer, pszCaption, MB_OK|MB_ICONERROR); | 1847 | MessageBox(NULL, (LPCTSTR)pTextBuffer, pszCaption, MB_OK|MB_ICONERROR); |
1848 | LocalFree(pTextBuffer); | 1848 | LocalFree(pTextBuffer); |
1849 | } | 1849 | } |
1850 | else | 1850 | else |
1851 | { | 1851 | { |
1852 | MessageBox(NULL, __TEXT("Unknown error"), pszCaption, MB_OK|MB_ICONERROR); | 1852 | MessageBox(NULL, __TEXT("Unknown error"), pszCaption, MB_OK|MB_ICONERROR); |
1853 | } | 1853 | } |
1854 | } | 1854 | } |
1855 | } | 1855 | } |
1856 | 1856 | ||
1857 | // Convert an Irrlicht texture to a Windows cursor | 1857 | // Convert an Irrlicht texture to a Windows cursor |
1858 | // Based on http://www.codeguru.com/cpp/w-p/win32/cursors/article.php/c4529/ | 1858 | // Based on http://www.codeguru.com/cpp/w-p/win32/cursors/article.php/c4529/ |
1859 | HCURSOR CIrrDeviceWin32::TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot) | 1859 | HCURSOR CIrrDeviceWin32::TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot) |
1860 | { | 1860 | { |
1861 | // | 1861 | // |
1862 | // create the bitmaps needed for cursors from the texture | 1862 | // create the bitmaps needed for cursors from the texture |
1863 | 1863 | ||
1864 | HDC dc = GetDC(hwnd); | 1864 | HDC dc = GetDC(hwnd); |
1865 | HDC andDc = CreateCompatibleDC(dc); | 1865 | HDC andDc = CreateCompatibleDC(dc); |
1866 | HDC xorDc = CreateCompatibleDC(dc); | 1866 | HDC xorDc = CreateCompatibleDC(dc); |
1867 | HBITMAP andBitmap = CreateCompatibleBitmap(dc, sourceRect.getWidth(), sourceRect.getHeight()); | 1867 | HBITMAP andBitmap = CreateCompatibleBitmap(dc, sourceRect.getWidth(), sourceRect.getHeight()); |
1868 | HBITMAP xorBitmap = CreateCompatibleBitmap(dc, sourceRect.getWidth(), sourceRect.getHeight()); | 1868 | HBITMAP xorBitmap = CreateCompatibleBitmap(dc, sourceRect.getWidth(), sourceRect.getHeight()); |
1869 | 1869 | ||
1870 | HBITMAP oldAndBitmap = (HBITMAP)SelectObject(andDc, andBitmap); | 1870 | HBITMAP oldAndBitmap = (HBITMAP)SelectObject(andDc, andBitmap); |
1871 | HBITMAP oldXorBitmap = (HBITMAP)SelectObject(xorDc, xorBitmap); | 1871 | HBITMAP oldXorBitmap = (HBITMAP)SelectObject(xorDc, xorBitmap); |
1872 | 1872 | ||
1873 | 1873 | ||
1874 | video::ECOLOR_FORMAT format = tex->getColorFormat(); | 1874 | video::ECOLOR_FORMAT format = tex->getColorFormat(); |
1875 | u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8; | 1875 | u32 bytesPerPixel = video::IImage::getBitsPerPixelFromFormat(format) / 8; |
1876 | u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel; | 1876 | u32 bytesLeftGap = sourceRect.UpperLeftCorner.X * bytesPerPixel; |
1877 | u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel; | 1877 | u32 bytesRightGap = tex->getPitch() - sourceRect.LowerRightCorner.X * bytesPerPixel; |
1878 | const u8* data = (const u8*)tex->lock(video::ETLM_READ_ONLY, 0); | 1878 | const u8* data = (const u8*)tex->lock(video::ETLM_READ_ONLY, 0); |
1879 | data += sourceRect.UpperLeftCorner.Y*tex->getPitch(); | 1879 | data += sourceRect.UpperLeftCorner.Y*tex->getPitch(); |
1880 | for ( s32 y = 0; y < sourceRect.getHeight(); ++y ) | 1880 | for ( s32 y = 0; y < sourceRect.getHeight(); ++y ) |
1881 | { | 1881 | { |
1882 | data += bytesLeftGap; | 1882 | data += bytesLeftGap; |
1883 | for ( s32 x = 0; x < sourceRect.getWidth(); ++x ) | 1883 | for ( s32 x = 0; x < sourceRect.getWidth(); ++x ) |
1884 | { | 1884 | { |
1885 | video::SColor pixelCol; | 1885 | video::SColor pixelCol; |
1886 | pixelCol.setData((const void*)data, format); | 1886 | pixelCol.setData((const void*)data, format); |
1887 | data += bytesPerPixel; | 1887 | data += bytesPerPixel; |
1888 | 1888 | ||
1889 | if ( pixelCol.getAlpha() == 0 ) // transparent | 1889 | if ( pixelCol.getAlpha() == 0 ) // transparent |
1890 | { | 1890 | { |
1891 | SetPixel(andDc, x, y, RGB(255,255,255)); | 1891 | SetPixel(andDc, x, y, RGB(255,255,255)); |
1892 | SetPixel(xorDc, x, y, RGB(0,0,0)); | 1892 | SetPixel(xorDc, x, y, RGB(0,0,0)); |
1893 | } | 1893 | } |
1894 | else // color | 1894 | else // color |
1895 | { | 1895 | { |
1896 | SetPixel(andDc, x, y, RGB(0,0,0)); | 1896 | SetPixel(andDc, x, y, RGB(0,0,0)); |
1897 | SetPixel(xorDc, x, y, RGB(pixelCol.getRed(), pixelCol.getGreen(), pixelCol.getBlue())); | 1897 | SetPixel(xorDc, x, y, RGB(pixelCol.getRed(), pixelCol.getGreen(), pixelCol.getBlue())); |
1898 | } | 1898 | } |
1899 | } | 1899 | } |
1900 | data += bytesRightGap; | 1900 | data += bytesRightGap; |
1901 | } | 1901 | } |
1902 | tex->unlock(); | 1902 | tex->unlock(); |
1903 | 1903 | ||
1904 | SelectObject(andDc, oldAndBitmap); | 1904 | SelectObject(andDc, oldAndBitmap); |
1905 | SelectObject(xorDc, oldXorBitmap); | 1905 | SelectObject(xorDc, oldXorBitmap); |
1906 | 1906 | ||
1907 | DeleteDC(xorDc); | 1907 | DeleteDC(xorDc); |
1908 | DeleteDC(andDc); | 1908 | DeleteDC(andDc); |
1909 | 1909 | ||
1910 | ReleaseDC(hwnd, dc); | 1910 | ReleaseDC(hwnd, dc); |
1911 | 1911 | ||
1912 | // create the cursor | 1912 | // create the cursor |
1913 | 1913 | ||
1914 | ICONINFO iconinfo; | 1914 | ICONINFO iconinfo; |
1915 | iconinfo.fIcon = false; // type is cursor not icon | 1915 | iconinfo.fIcon = false; // type is cursor not icon |
1916 | iconinfo.xHotspot = hotspot.X; | 1916 | iconinfo.xHotspot = hotspot.X; |
1917 | iconinfo.yHotspot = hotspot.Y; | 1917 | iconinfo.yHotspot = hotspot.Y; |
1918 | iconinfo.hbmMask = andBitmap; | 1918 | iconinfo.hbmMask = andBitmap; |
1919 | iconinfo.hbmColor = xorBitmap; | 1919 | iconinfo.hbmColor = xorBitmap; |
1920 | 1920 | ||
1921 | HCURSOR cursor = CreateIconIndirect(&iconinfo); | 1921 | HCURSOR cursor = CreateIconIndirect(&iconinfo); |
1922 | 1922 | ||
1923 | DeleteObject(andBitmap); | 1923 | DeleteObject(andBitmap); |
1924 | DeleteObject(xorBitmap); | 1924 | DeleteObject(xorBitmap); |
1925 | 1925 | ||
1926 | return cursor; | 1926 | return cursor; |
1927 | } | 1927 | } |
1928 | 1928 | ||
1929 | 1929 | ||
1930 | CIrrDeviceWin32::CCursorControl::CCursorControl(CIrrDeviceWin32* device, const core::dimension2d<u32>& wsize, HWND hwnd, bool fullscreen) | 1930 | CIrrDeviceWin32::CCursorControl::CCursorControl(CIrrDeviceWin32* device, const core::dimension2d<u32>& wsize, HWND hwnd, bool fullscreen) |
1931 | : Device(device), WindowSize(wsize), InvWindowSize(0.0f, 0.0f), | 1931 | : Device(device), WindowSize(wsize), InvWindowSize(0.0f, 0.0f), |
1932 | HWnd(hwnd), BorderX(0), BorderY(0), | 1932 | HWnd(hwnd), BorderX(0), BorderY(0), |
1933 | UseReferenceRect(false), IsVisible(true) | 1933 | UseReferenceRect(false), IsVisible(true) |
1934 | , ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0) | 1934 | , ActiveIcon(gui::ECI_NORMAL), ActiveIconStartTime(0) |
1935 | { | 1935 | { |
1936 | if (WindowSize.Width!=0) | 1936 | if (WindowSize.Width!=0) |
1937 | InvWindowSize.Width = 1.0f / WindowSize.Width; | 1937 | InvWindowSize.Width = 1.0f / WindowSize.Width; |
1938 | 1938 | ||
1939 | if (WindowSize.Height!=0) | 1939 | if (WindowSize.Height!=0) |
1940 | InvWindowSize.Height = 1.0f / WindowSize.Height; | 1940 | InvWindowSize.Height = 1.0f / WindowSize.Height; |
1941 | 1941 | ||
1942 | updateBorderSize(fullscreen, false); | 1942 | updateBorderSize(fullscreen, false); |
1943 | initCursors(); | 1943 | initCursors(); |
1944 | } | 1944 | } |
1945 | 1945 | ||
1946 | CIrrDeviceWin32::CCursorControl::~CCursorControl() | 1946 | CIrrDeviceWin32::CCursorControl::~CCursorControl() |
1947 | { | 1947 | { |
1948 | for ( u32 i=0; i < Cursors.size(); ++i ) | 1948 | for ( u32 i=0; i < Cursors.size(); ++i ) |
1949 | { | 1949 | { |
1950 | for ( u32 f=0; f < Cursors[i].Frames.size(); ++f ) | 1950 | for ( u32 f=0; f < Cursors[i].Frames.size(); ++f ) |
1951 | { | 1951 | { |
1952 | DestroyCursor(Cursors[i].Frames[f].IconHW); | 1952 | DestroyCursor(Cursors[i].Frames[f].IconHW); |
1953 | } | 1953 | } |
1954 | } | 1954 | } |
1955 | } | 1955 | } |
1956 | 1956 | ||
1957 | 1957 | ||
1958 | void CIrrDeviceWin32::CCursorControl::initCursors() | 1958 | void CIrrDeviceWin32::CCursorControl::initCursors() |
1959 | { | 1959 | { |
1960 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_ARROW)) ); | 1960 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_ARROW)) ); |
1961 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_CROSS)) ); | 1961 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_CROSS)) ); |
1962 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_HAND)) ); | 1962 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_HAND)) ); |
1963 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_HELP)) ); | 1963 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_HELP)) ); |
1964 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_IBEAM)) ); | 1964 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_IBEAM)) ); |
1965 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_NO)) ); | 1965 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_NO)) ); |
1966 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_WAIT)) ); | 1966 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_WAIT)) ); |
1967 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZEALL)) ); | 1967 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZEALL)) ); |
1968 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENESW)) ); | 1968 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENESW)) ); |
1969 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENWSE)) ); | 1969 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENWSE)) ); |
1970 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENS)) ); | 1970 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZENS)) ); |
1971 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZEWE)) ); | 1971 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_SIZEWE)) ); |
1972 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_UPARROW)) ); | 1972 | Cursors.push_back( CursorW32(LoadCursor(NULL, IDC_UPARROW)) ); |
1973 | } | 1973 | } |
1974 | 1974 | ||
1975 | 1975 | ||
1976 | void CIrrDeviceWin32::CCursorControl::update() | 1976 | void CIrrDeviceWin32::CCursorControl::update() |
1977 | { | 1977 | { |
1978 | if ( !Cursors[ActiveIcon].Frames.empty() && Cursors[ActiveIcon].FrameTime ) | 1978 | if ( !Cursors[ActiveIcon].Frames.empty() && Cursors[ActiveIcon].FrameTime ) |
1979 | { | 1979 | { |
1980 | // update animated cursors. This could also be done by X11 in case someone wants to figure that out (this way was just easier to implement) | 1980 | // update animated cursors. This could also be done by X11 in case someone wants to figure that out (this way was just easier to implement) |
1981 | u32 now = Device->getTimer()->getRealTime(); | 1981 | u32 now = Device->getTimer()->getRealTime(); |
1982 | u32 frame = ((now - ActiveIconStartTime) / Cursors[ActiveIcon].FrameTime) % Cursors[ActiveIcon].Frames.size(); | 1982 | u32 frame = ((now - ActiveIconStartTime) / Cursors[ActiveIcon].FrameTime) % Cursors[ActiveIcon].Frames.size(); |
1983 | SetCursor( Cursors[ActiveIcon].Frames[frame].IconHW ); | 1983 | SetCursor( Cursors[ActiveIcon].Frames[frame].IconHW ); |
1984 | } | 1984 | } |
1985 | } | 1985 | } |
1986 | 1986 | ||
1987 | //! Sets the active cursor icon | 1987 | //! Sets the active cursor icon |
1988 | void CIrrDeviceWin32::CCursorControl::setActiveIcon(gui::ECURSOR_ICON iconId) | 1988 | void CIrrDeviceWin32::CCursorControl::setActiveIcon(gui::ECURSOR_ICON iconId) |
1989 | { | 1989 | { |
1990 | if ( iconId >= (s32)Cursors.size() ) | 1990 | if ( iconId >= (s32)Cursors.size() ) |
1991 | return; | 1991 | return; |
1992 | 1992 | ||
1993 | ActiveIcon = iconId; | 1993 | ActiveIcon = iconId; |
1994 | ActiveIconStartTime = Device->getTimer()->getRealTime(); | 1994 | ActiveIconStartTime = Device->getTimer()->getRealTime(); |
1995 | if ( Cursors[ActiveIcon].Frames.size() ) | 1995 | if ( Cursors[ActiveIcon].Frames.size() ) |
1996 | SetCursor( Cursors[ActiveIcon].Frames[0].IconHW ); | 1996 | SetCursor( Cursors[ActiveIcon].Frames[0].IconHW ); |
1997 | } | 1997 | } |
1998 | 1998 | ||
1999 | 1999 | ||
2000 | //! Add a custom sprite as cursor icon. | 2000 | //! Add a custom sprite as cursor icon. |
2001 | gui::ECURSOR_ICON CIrrDeviceWin32::CCursorControl::addIcon(const gui::SCursorSprite& icon) | 2001 | gui::ECURSOR_ICON CIrrDeviceWin32::CCursorControl::addIcon(const gui::SCursorSprite& icon) |
2002 | { | 2002 | { |
2003 | if ( icon.SpriteId >= 0 ) | 2003 | if ( icon.SpriteId >= 0 ) |
2004 | { | 2004 | { |
2005 | CursorW32 cW32; | 2005 | CursorW32 cW32; |
2006 | cW32.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime; | 2006 | cW32.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime; |
2007 | 2007 | ||
2008 | for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i ) | 2008 | for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i ) |
2009 | { | 2009 | { |
2010 | irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber; | 2010 | irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber; |
2011 | irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber; | 2011 | irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber; |
2012 | irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId]; | 2012 | irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId]; |
2013 | 2013 | ||
2014 | HCURSOR hc = Device->TextureToCursor(HWnd, icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot); | 2014 | HCURSOR hc = Device->TextureToCursor(HWnd, icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot); |
2015 | cW32.Frames.push_back( CursorFrameW32(hc) ); | 2015 | cW32.Frames.push_back( CursorFrameW32(hc) ); |
2016 | } | 2016 | } |
2017 | 2017 | ||
2018 | Cursors.push_back( cW32 ); | 2018 | Cursors.push_back( cW32 ); |
2019 | return (gui::ECURSOR_ICON)(Cursors.size() - 1); | 2019 | return (gui::ECURSOR_ICON)(Cursors.size() - 1); |
2020 | } | 2020 | } |
2021 | return gui::ECI_NORMAL; | 2021 | return gui::ECI_NORMAL; |
2022 | } | 2022 | } |
2023 | 2023 | ||
2024 | 2024 | ||
2025 | //! replace the given cursor icon. | 2025 | //! replace the given cursor icon. |
2026 | void CIrrDeviceWin32::CCursorControl::changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) | 2026 | void CIrrDeviceWin32::CCursorControl::changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) |
2027 | { | 2027 | { |
2028 | if ( iconId >= (s32)Cursors.size() ) | 2028 | if ( iconId >= (s32)Cursors.size() ) |
2029 | return; | 2029 | return; |
2030 | 2030 | ||
2031 | for ( u32 i=0; i < Cursors[iconId].Frames.size(); ++i ) | 2031 | for ( u32 i=0; i < Cursors[iconId].Frames.size(); ++i ) |
2032 | DestroyCursor(Cursors[iconId].Frames[i].IconHW); | 2032 | DestroyCursor(Cursors[iconId].Frames[i].IconHW); |
2033 | 2033 | ||
2034 | if ( icon.SpriteId >= 0 ) | 2034 | if ( icon.SpriteId >= 0 ) |
2035 | { | 2035 | { |
2036 | CursorW32 cW32; | 2036 | CursorW32 cW32; |
2037 | cW32.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime; | 2037 | cW32.FrameTime = icon.SpriteBank->getSprites()[icon.SpriteId].frameTime; |
2038 | for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i ) | 2038 | for ( u32 i=0; i < icon.SpriteBank->getSprites()[icon.SpriteId].Frames.size(); ++i ) |
2039 | { | 2039 | { |
2040 | irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber; | 2040 | irr::u32 texId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].textureNumber; |
2041 | irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber; | 2041 | irr::u32 rectId = icon.SpriteBank->getSprites()[icon.SpriteId].Frames[i].rectNumber; |
2042 | irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId]; | 2042 | irr::core::rect<s32> rectIcon = icon.SpriteBank->getPositions()[rectId]; |
2043 | 2043 | ||
2044 | HCURSOR hc = Device->TextureToCursor(HWnd, icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot); | 2044 | HCURSOR hc = Device->TextureToCursor(HWnd, icon.SpriteBank->getTexture(texId), rectIcon, icon.HotSpot); |
2045 | cW32.Frames.push_back( CursorFrameW32(hc) ); | 2045 | cW32.Frames.push_back( CursorFrameW32(hc) ); |
2046 | } | 2046 | } |
2047 | 2047 | ||
2048 | Cursors[iconId] = cW32; | 2048 | Cursors[iconId] = cW32; |
2049 | } | 2049 | } |
2050 | } | 2050 | } |
2051 | 2051 | ||
2052 | 2052 | ||
2053 | //! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work. | 2053 | //! Return a system-specific size which is supported for cursors. Larger icons will fail, smaller icons might work. |
2054 | core::dimension2di CIrrDeviceWin32::CCursorControl::getSupportedIconSize() const | 2054 | core::dimension2di CIrrDeviceWin32::CCursorControl::getSupportedIconSize() const |
2055 | { | 2055 | { |
2056 | core::dimension2di result; | 2056 | core::dimension2di result; |
2057 | 2057 | ||
2058 | result.Width = GetSystemMetrics(SM_CXCURSOR); | 2058 | result.Width = GetSystemMetrics(SM_CXCURSOR); |
2059 | result.Height = GetSystemMetrics(SM_CYCURSOR); | 2059 | result.Height = GetSystemMetrics(SM_CYCURSOR); |
2060 | 2060 | ||
2061 | return result; | 2061 | return result; |
2062 | } | 2062 | } |
2063 | 2063 | ||
2064 | 2064 | ||
2065 | 2065 | ||
2066 | } // end namespace | 2066 | } // end namespace |
2067 | 2067 | ||
2068 | #endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_ | 2068 | #endif // _IRR_COMPILE_WITH_WINDOWS_DEVICE_ |