aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceWin32.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceWin32.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CIrrDeviceWin32.cpp4136
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
35namespace irr 35namespace 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
56namespace irr 56namespace irr
57{ 57{
58struct SJoystickWin32Control 58struct 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
190void pollJoysticks() 190void 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
362bool activateJoysticks(core::array<SJoystickInfo> & joystickInfo) 362bool 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
442static unsigned int LocaleIdToCodepage(unsigned int lcid) 442static 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
600namespace 600namespace
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
613SEnvMapper* getEnvMapperFromHWnd(HWND hWnd) 613SEnvMapper* 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
624irr::CIrrDeviceWin32* getDeviceFromHWnd(HWND hWnd) 624irr::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
635LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 635LRESULT 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
908namespace irr 908namespace irr
909{ 909{
910 910
911//! constructor 911//! constructor
912CIrrDeviceWin32::CIrrDeviceWin32(const SIrrlichtCreationParameters& params) 912CIrrDeviceWin32::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
1062CIrrDeviceWin32::~CIrrDeviceWin32() 1062CIrrDeviceWin32::~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
1083void CIrrDeviceWin32::createDriver() 1083void 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
1167bool CIrrDeviceWin32::run() 1167bool 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
1187void CIrrDeviceWin32::yield() 1187void 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.
1193void CIrrDeviceWin32::sleep(u32 timeMs, bool pauseTimer) 1193void 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
1206void CIrrDeviceWin32::resizeIfNecessary() 1206void 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
1235void CIrrDeviceWin32::setWindowCaption(const wchar_t* text) 1235void 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
1247bool CIrrDeviceWin32::present(video::IImage* image, void* windowId, core::rect<s32>* src) 1247bool 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
1297void CIrrDeviceWin32::closeDevice() 1297void 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
1315bool CIrrDeviceWin32::isWindowActive() const 1315bool 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
1323bool CIrrDeviceWin32::isWindowFocused() const 1323bool 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
1332bool CIrrDeviceWin32::isWindowMinimized() const 1332bool 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
1345bool CIrrDeviceWin32::switchToFullScreen(bool reset) 1345bool 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
1411CIrrDeviceWin32::CCursorControl* CIrrDeviceWin32::getWin32CursorControl() 1411CIrrDeviceWin32::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.
1419video::IVideoModeList* CIrrDeviceWin32::getVideoModeList() 1419video::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
1444typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); 1444typedef 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
1479void CIrrDeviceWin32::getWindowsVersion(core::stringc& out) 1479void 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
1664void CIrrDeviceWin32::OnResized() 1664void 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.
1670void CIrrDeviceWin32::setResizable(bool resize) 1670void 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.
1707void CIrrDeviceWin32::minimizeWindow() 1707void 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.
1718void CIrrDeviceWin32::maximizeWindow() 1718void 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.
1729void CIrrDeviceWin32::restoreWindow() 1729void 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
1739bool CIrrDeviceWin32::activateJoysticks(core::array<SJoystickInfo> & joystickInfo) 1739bool 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
1749bool CIrrDeviceWin32::setGammaRamp( f32 red, f32 green, f32 blue, f32 brightness, f32 contrast ) 1749bool 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
1765bool CIrrDeviceWin32::getGammaRamp( f32 &red, f32 &green, f32 &blue, f32 &brightness, f32 &contrast ) 1765bool 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
1790void CIrrDeviceWin32::handleSystemMessages() 1790void 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
1811void CIrrDeviceWin32::clearSystemMessages() 1811void 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.
1821void CIrrDeviceWin32::ReportLastWinApiError() 1821void 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/
1859HCURSOR CIrrDeviceWin32::TextureToCursor(HWND hwnd, irr::video::ITexture * tex, const core::rect<s32>& sourceRect, const core::position2d<s32> &hotspot) 1859HCURSOR 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
1930CIrrDeviceWin32::CCursorControl::CCursorControl(CIrrDeviceWin32* device, const core::dimension2d<u32>& wsize, HWND hwnd, bool fullscreen) 1930CIrrDeviceWin32::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
1946CIrrDeviceWin32::CCursorControl::~CCursorControl() 1946CIrrDeviceWin32::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
1958void CIrrDeviceWin32::CCursorControl::initCursors() 1958void 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
1976void CIrrDeviceWin32::CCursorControl::update() 1976void 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
1988void CIrrDeviceWin32::CCursorControl::setActiveIcon(gui::ECURSOR_ICON iconId) 1988void 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.
2001gui::ECURSOR_ICON CIrrDeviceWin32::CCursorControl::addIcon(const gui::SCursorSprite& icon) 2001gui::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.
2026void CIrrDeviceWin32::CCursorControl::changeIcon(gui::ECURSOR_ICON iconId, const gui::SCursorSprite& icon) 2026void 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.
2054core::dimension2di CIrrDeviceWin32::CCursorControl::getSupportedIconSize() const 2054core::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_