aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.cpp405
1 files changed, 405 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.cpp
new file mode 100644
index 0000000..e3af6c2
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceFB.cpp
@@ -0,0 +1,405 @@
1// Copyright (C) 2002-2007 Nikolaus Gebhardt
2// Copyright (C) 2007-2012 Christian Stehno
3// This file is part of the "Irrlicht Engine".
4// For conditions of distribution and use, see copyright notice in irrlicht.h
5
6#include "CIrrDeviceFB.h"
7
8#ifdef _IRR_COMPILE_WITH_FB_DEVICE_
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <sys/ioctl.h>
16#include <fcntl.h>
17#include <sys/mman.h>
18#include <sys/utsname.h>
19#include <time.h>
20#include <errno.h>
21
22#include "IEventReceiver.h"
23#include "os.h"
24#include "CTimer.h"
25#include "irrString.h"
26#include "Keycodes.h"
27#include "COSOperator.h"
28#include "CColorConverter.h"
29#include "SIrrCreationParameters.h"
30
31#include <linux/input.h>
32
33namespace irr
34{
35
36//! constructor
37CIrrDeviceFB::CIrrDeviceFB(const SIrrlichtCreationParameters& params)
38 : CIrrDeviceStub(params), Framebuffer(-1), EventDevice(-1), SoftwareImage(0),
39 Pitch(0), FBColorFormat(video::ECF_A8R8G8B8), Close(false)
40{
41 #ifdef _DEBUG
42 setDebugName("CIrrDeviceFB");
43 #endif
44
45 // print version, distribution etc.
46 // thx to LynxLuna for pointing me to the uname function
47 core::stringc linuxversion;
48 struct utsname FBInfo;
49 uname(&FBInfo);
50
51 linuxversion += FBInfo.sysname;
52 linuxversion += " ";
53 linuxversion += FBInfo.release;
54 linuxversion += " ";
55 linuxversion += FBInfo.version;
56 linuxversion += " ";
57 linuxversion += FBInfo.machine;
58
59 Operator = new COSOperator(linuxversion);
60 os::Printer::log(linuxversion.c_str(), ELL_INFORMATION);
61
62 // create window
63 if (params.DriverType != video::EDT_NULL)
64 {
65 // create the window, only if we do not use the null device
66 if (!createWindow(params.WindowSize, params.Bits))
67 return;
68 }
69
70 // create cursor control
71 CursorControl = new CCursorControl(this, params.DriverType == video::EDT_NULL);
72
73 // create driver
74 createDriver();
75
76 if (!VideoDriver)
77 return;
78
79 createGUIAndScene();
80}
81
82
83
84//! destructor
85CIrrDeviceFB::~CIrrDeviceFB()
86{
87 if (SoftwareImage)
88 munmap(SoftwareImage, CreationParams.WindowSize.Height*Pitch);
89 // go back to previous format
90 if (ioctl(Framebuffer, FBIOPUT_VSCREENINFO, &oldscreeninfo) <0)
91 perror("Restoring old fb mode");
92
93 if (KeyboardDevice != -1)
94 if (ioctl(KeyboardDevice, KDSETMODE, &KeyboardMode) <0)
95 perror("Restoring keyboard mode");
96 if (EventDevice != -1)
97 close(EventDevice);
98 if (KeyboardDevice != -1)
99 close(KeyboardDevice);
100 if (Framebuffer != -1)
101 close(Framebuffer);
102}
103
104
105bool CIrrDeviceFB::createWindow(const core::dimension2d<u32>& windowSize, u32 bits)
106{
107 char buf[256];
108 CreationParams.WindowSize.Width = windowSize.Width;
109 CreationParams.WindowSize.Height = windowSize.Height;
110
111 KeyboardDevice = open("/dev/tty", O_RDWR);
112 if (KeyboardDevice == -1)
113 perror("Open keyboard");
114 if (ioctl(KeyboardDevice, KDGETMODE, &KeyboardMode) <0)
115 perror("Read keyboard mode");
116 if (ioctl(KeyboardDevice, KDSETMODE, KD_GRAPHICS) <0)
117 perror("Set keyboard mode");
118
119 Framebuffer=open("/dev/fb/0", O_RDWR);
120 if (Framebuffer == -1)
121 {
122 Framebuffer=open("/dev/fb0", O_RDWR);
123 if (Framebuffer == -1)
124 {
125 perror("Open framebuffer");
126 return false;
127 }
128 }
129 EventDevice = open("/dev/input/event0", O_RDONLY | O_NONBLOCK);
130 if (EventDevice == -1)
131 perror("Open event device");
132
133 // make format settings
134 ioctl(Framebuffer, FBIOGET_FSCREENINFO, &fbfixscreeninfo);
135 ioctl(Framebuffer, FBIOGET_VSCREENINFO, &oldscreeninfo);
136snprintf(buf, 256, "Original resolution: %d x %d\nARGB%d%d%d%d\n",oldscreeninfo.xres,oldscreeninfo.yres,
137 oldscreeninfo.transp.length,oldscreeninfo.red.length,oldscreeninfo.green.length,oldscreeninfo.blue.length);
138 os::Printer::log(buf);
139 memcpy(&fbscreeninfo, &oldscreeninfo, sizeof(struct fb_var_screeninfo));
140 if (CreationParams.DriverType != video::EDT_NULL)
141 {
142 fbscreeninfo.xres = fbscreeninfo.xres_virtual = CreationParams.WindowSize.Width;
143 fbscreeninfo.yres = fbscreeninfo.yres_virtual = CreationParams.WindowSize.Height;
144 fbscreeninfo.bits_per_pixel = 16;
145 fbscreeninfo.red.offset = 10;
146 fbscreeninfo.red.length = 5;
147 fbscreeninfo.green.offset = 5;
148 fbscreeninfo.green.length = 5;
149 fbscreeninfo.blue.offset = 0;
150 fbscreeninfo.blue.length = 5;
151 fbscreeninfo.transp.offset = 15;
152 fbscreeninfo.transp.length = 1;
153 ioctl(Framebuffer, FBIOPUT_VSCREENINFO, &fbscreeninfo);
154 ioctl(Framebuffer, FBIOGET_VSCREENINFO, &fbscreeninfo);
155
156snprintf(buf, 256, "New resolution: %d x %d (%d x %d)\nARGB%d%d%d%d\n",fbscreeninfo.xres,fbscreeninfo.yres,fbscreeninfo.xres_virtual,fbscreeninfo.yres_virtual,
157 fbscreeninfo.transp.length,fbscreeninfo.red.length,fbscreeninfo.green.length,fbscreeninfo.blue.length);
158 os::Printer::log(buf);
159
160 CreationParams.WindowSize.Width = fbscreeninfo.xres;
161 CreationParams.WindowSize.Height = fbscreeninfo.yres;
162 CreationParams.Bits = fbscreeninfo.bits_per_pixel;
163 Pitch = fbfixscreeninfo.line_length;
164 if (fbscreeninfo.bits_per_pixel == 16)
165 {
166 if (fbscreeninfo.transp.length == 0)
167 FBColorFormat = video::ECF_R5G6B5;
168 else
169 FBColorFormat = video::ECF_A1R5G5B5;
170 }
171 else
172 {
173 if (fbscreeninfo.transp.length == 0)
174 FBColorFormat = video::ECF_R8G8B8;
175 else
176 FBColorFormat = video::ECF_A8R8G8B8;
177 }
178 if (MAP_FAILED==(SoftwareImage=(u8*)mmap(0, CreationParams.WindowSize.Height*Pitch, PROT_READ|PROT_WRITE, MAP_SHARED, Framebuffer, 0)))
179 {
180 perror("mmap render target");
181 return false;
182 }
183 }
184 return true;
185}
186
187
188//! create the driver
189void CIrrDeviceFB::createDriver()
190{
191 switch(CreationParams.DriverType)
192 {
193 case video::EDT_SOFTWARE:
194 #ifdef _IRR_COMPILE_WITH_SOFTWARE_
195 VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this);
196 #else
197 os::Printer::log("No Software driver support compiled in.", ELL_WARNING);
198 #endif
199 break;
200
201 case video::EDT_BURNINGSVIDEO:
202 #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
203 VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this);
204 #else
205 os::Printer::log("Burning's video driver was not compiled in.", ELL_WARNING);
206 #endif
207 break;
208
209 case video::EDT_OPENGL:
210 case video::EDT_DIRECT3D8:
211 case video::EDT_DIRECT3D9:
212 os::Printer::log("This driver is not available in FB. Try Software renderer.",
213 ELL_WARNING);
214 break;
215
216 default:
217 VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);
218 break;
219 }
220}
221
222
223//! runs the device. Returns false if device wants to be deleted
224bool CIrrDeviceFB::run()
225{
226 os::Timer::tick();
227
228 struct input_event ev;
229 if (EventDevice>=0)
230 {
231 if ((read(EventDevice, &ev, sizeof(input_event)) < 0) &&
232 errno != EAGAIN)
233 perror("Read input event");
234 if (ev.type == EV_KEY)
235 {
236 irr::SEvent irrevent;
237 irrevent.EventType = irr::EET_KEY_INPUT_EVENT;
238 irrevent.KeyInput.PressedDown = true;
239
240 switch (ev.code)
241 {
242 case KEY_RIGHTCTRL:
243 case KEY_LEFTCTRL:
244 irrevent.KeyInput.Control = true;
245 break;
246 case KEY_RIGHTSHIFT:
247 case KEY_LEFTSHIFT:
248 irrevent.KeyInput.Shift = true;
249 break;
250 case KEY_ESC:
251 irrevent.KeyInput.Key = (EKEY_CODE)0x1B;
252 break;
253 case KEY_SPACE:
254 irrevent.KeyInput.Key = (EKEY_CODE)0x20;
255 break;
256 case KEY_UP:
257 irrevent.KeyInput.Key = (EKEY_CODE)0x26;
258 break;
259 case KEY_LEFT:
260 irrevent.KeyInput.Key = (EKEY_CODE)0x25;
261 break;
262 case KEY_RIGHT:
263 irrevent.KeyInput.Key = (EKEY_CODE)0x27;
264 break;
265 case KEY_DOWN:
266 irrevent.KeyInput.Key = (EKEY_CODE)0x28;
267 break;
268 default:
269 irrevent.KeyInput.Key = (EKEY_CODE)0;
270 break;
271 }
272 postEventFromUser(irrevent);
273 }
274 }
275
276 return !Close;
277}
278
279
280//! Pause the current process for the minimum time allowed only to allow other processes to execute
281void CIrrDeviceFB::yield()
282{
283 struct timespec ts = {0,0};
284 nanosleep(&ts, NULL);
285}
286
287
288//! Pause execution and let other processes to run for a specified amount of time.
289void CIrrDeviceFB::sleep(u32 timeMs, bool pauseTimer=false)
290{
291 bool wasStopped = Timer ? Timer->isStopped() : true;
292
293 struct timespec ts;
294 ts.tv_sec = (time_t) (timeMs / 1000);
295 ts.tv_nsec = (long) (timeMs % 1000) * 1000000;
296
297 if (pauseTimer && !wasStopped)
298 Timer->stop();
299
300 nanosleep(&ts, NULL);
301
302 if (pauseTimer && !wasStopped)
303 Timer->start();
304}
305
306
307//! presents a surface in the client area
308bool CIrrDeviceFB::present(video::IImage* image, void* windowId, core::rect<s32>* src )
309{
310 // this is only necessary for software drivers.
311 if (CreationParams.DriverType != video::EDT_SOFTWARE && CreationParams.DriverType != video::EDT_BURNINGSVIDEO)
312 return false;
313
314 if (!SoftwareImage)
315 return false;
316
317 u8* destData = SoftwareImage;
318 u32 srcwidth = (u32)image->getDimension().Width;
319 u32 srcheight = (u32)image->getDimension().Height;
320 // clip images
321 srcheight = core::min_(srcheight, CreationParams.WindowSize.Height);
322 srcwidth = core::min_(srcwidth, CreationParams.WindowSize.Width);
323
324 u8* srcdata = (u8*)image->lock();
325 for (u32 y=0; y<srcheight; ++y)
326 {
327 video::CColorConverter::convert_viaFormat(srcdata, image->getColorFormat(), srcwidth, destData, FBColorFormat);
328 srcdata+=image->getPitch();
329 destData+=Pitch;
330 }
331 image->unlock();
332 msync(SoftwareImage,CreationParams.WindowSize.Width*CreationParams.WindowSize.Height,MS_ASYNC);
333 return true;
334}
335
336
337//! notifies the device that it should close itself
338void CIrrDeviceFB::closeDevice()
339{
340 Close = true;
341}
342
343
344//! returns if window is active. if not, nothing need to be drawn
345bool CIrrDeviceFB::isWindowActive() const
346{
347 return true;
348}
349
350
351//! returns if window has focus
352bool CIrrDeviceFB::isWindowFocused() const
353{
354 return true;
355}
356
357
358//! returns if window is minimized
359bool CIrrDeviceFB::isWindowMinimized() const
360{
361 return false;
362}
363
364
365//! sets the caption of the window
366void CIrrDeviceFB::setWindowCaption(const wchar_t* text)
367{
368}
369
370
371//! Sets if the window should be resizeable in windowed mode.
372void CIrrDeviceFB::setResizable(bool resize)
373{
374}
375
376
377//! Minimizes window
378void CIrrDeviceFB::minimizeWindow()
379{
380}
381
382
383//! Maximizes window
384void CIrrDeviceFB::maximizeWindow()
385{
386}
387
388
389//! Restores original window size
390void CIrrDeviceFB::restoreWindow()
391{
392}
393
394
395//! Returns the type of this device
396E_DEVICE_TYPE CIrrDeviceFB::getType() const
397{
398 return EIDT_FRAMEBUFFER;
399}
400
401
402} // end namespace irr
403
404#endif // _IRR_USE_FB_DEVICE_
405