aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceConsole.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceConsole.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceConsole.cpp477
1 files changed, 477 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceConsole.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceConsole.cpp
new file mode 100644
index 0000000..53892ee
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CIrrDeviceConsole.cpp
@@ -0,0 +1,477 @@
1// Copyright (C) 2009-2012 Gaz Davidson
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CIrrDeviceConsole.h"
6
7#ifdef _IRR_COMPILE_WITH_CONSOLE_DEVICE_
8
9#include "os.h"
10#include "IGUISkin.h"
11#include "IGUIEnvironment.h"
12
13// to close the device on terminate signal
14irr::CIrrDeviceConsole *DeviceToClose;
15
16#ifdef _IRR_WINDOWS_NT_CONSOLE_
17// Callback for Windows
18BOOL WINAPI ConsoleHandler(DWORD CEvent)
19{
20 switch(CEvent)
21 {
22 case CTRL_C_EVENT:
23 irr::os::Printer::log("Closing console device", "CTRL+C");
24 break;
25 case CTRL_BREAK_EVENT:
26 irr::os::Printer::log("Closing console device", "CTRL+Break");
27 break;
28 case CTRL_CLOSE_EVENT:
29 irr::os::Printer::log("Closing console device", "User closed console");
30 break;
31 case CTRL_LOGOFF_EVENT:
32 irr::os::Printer::log("Closing console device", "User is logging off");
33 break;
34 case CTRL_SHUTDOWN_EVENT:
35 irr::os::Printer::log("Closing console device", "Computer shutting down");
36 break;
37 }
38 DeviceToClose->closeDevice();
39 return TRUE;
40}
41#elif defined(_IRR_POSIX_API_)
42// sigterm handler
43#include <signal.h>
44
45void sighandler(int sig)
46{
47 irr::core::stringc code = "Signal ";
48 code += sig;
49 code += " received";
50 irr::os::Printer::log("Closing console device", code.c_str());
51
52 DeviceToClose->closeDevice();
53}
54#endif
55
56namespace irr
57{
58
59const c8 ASCIIArtChars[] = " .,'~:;!+>=icopjtJY56SB8XDQKHNWM"; //MWNHKQDX8BS65YJtjpoci=+>!;:~',. ";
60const u16 ASCIIArtCharsCount = 32;
61
62//const c8 ASCIIArtChars[] = " \xb0\xb1\xf9\xb2\xdb";
63//const u16 ASCIIArtCharsCount = 5;
64
65//! constructor
66CIrrDeviceConsole::CIrrDeviceConsole(const SIrrlichtCreationParameters& params)
67 : CIrrDeviceStub(params), IsWindowFocused(true), ConsoleFont(0), OutFile(stdout)
68{
69 DeviceToClose = this;
70
71#ifdef _IRR_WINDOWS_NT_CONSOLE_
72 MouseButtonStates = 0;
73
74 WindowsSTDIn = GetStdHandle(STD_INPUT_HANDLE);
75 WindowsSTDOut = GetStdHandle(STD_OUTPUT_HANDLE);
76 PCOORD Dimensions = 0;
77
78 if (CreationParams.Fullscreen)
79 {
80// Some mingw versions lack this define, so avoid it in case it does not exist
81#if (_WIN32_WINNT >= 0x0501) && defined(CONSOLE_FULLSCREEN_MODE)
82 if (SetConsoleDisplayMode(WindowsSTDOut, CONSOLE_FULLSCREEN_MODE, Dimensions))
83 {
84 CreationParams.WindowSize.Width = Dimensions->X;
85 CreationParams.WindowSize.Width = Dimensions->Y;
86 }
87#endif
88 }
89 else
90 {
91 COORD ConsoleSize;
92 ConsoleSize.X = CreationParams.WindowSize.Width;
93 ConsoleSize.X = CreationParams.WindowSize.Height;
94 SetConsoleScreenBufferSize(WindowsSTDOut, ConsoleSize);
95 }
96
97 // catch windows close/break signals
98 SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE);
99
100#elif defined(_IRR_POSIX_API_)
101 // catch other signals
102 signal(SIGABRT, &sighandler);
103 signal(SIGTERM, &sighandler);
104 signal(SIGINT, &sighandler);
105
106 // set output stream
107 if (params.WindowId)
108 OutFile = (FILE*)(params.WindowId);
109#endif
110
111#ifdef _IRR_VT100_CONSOLE_
112 // reset terminal
113 fprintf(OutFile, "%cc", 27);
114 // disable line wrapping
115 fprintf(OutFile, "%c[7l", 27);
116#endif
117
118 switch (params.DriverType)
119 {
120 case video::EDT_SOFTWARE:
121 #ifdef _IRR_COMPILE_WITH_SOFTWARE_
122 VideoDriver = video::createSoftwareDriver(CreationParams.WindowSize, CreationParams.Fullscreen, FileSystem, this);
123 #else
124 os::Printer::log("Software driver was not compiled in.", ELL_ERROR);
125 #endif
126 break;
127
128 case video::EDT_BURNINGSVIDEO:
129 #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
130 VideoDriver = video::createBurningVideoDriver(CreationParams, FileSystem, this);
131 #else
132 os::Printer::log("Burning's Video driver was not compiled in.", ELL_ERROR);
133 #endif
134 break;
135
136 case video::EDT_DIRECT3D8:
137 case video::EDT_DIRECT3D9:
138 case video::EDT_OPENGL:
139 os::Printer::log("The console device cannot use hardware drivers yet.", ELL_ERROR);
140 break;
141 case video::EDT_NULL:
142 VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize);
143 break;
144 default:
145 break;
146 }
147
148 // set up output buffer
149 for (u32 y=0; y<CreationParams.WindowSize.Height; ++y)
150 {
151 core::stringc str;
152 str.reserve(CreationParams.WindowSize.Width);
153 for (u32 x=0; x<CreationParams.WindowSize.Width; ++x)
154 str += " ";
155 OutputBuffer.push_back(str);
156 }
157
158
159#ifdef _IRR_WINDOWS_NT_CONSOLE_
160 CursorControl = new CCursorControl(CreationParams.WindowSize);
161#endif
162
163 if (VideoDriver)
164 {
165 createGUIAndScene();
166#ifdef _IRR_USE_CONSOLE_FONT_
167 if (GUIEnvironment)
168 {
169 ConsoleFont = new gui::CGUIConsoleFont(this);
170 gui::IGUISkin *skin = GUIEnvironment->getSkin();
171 if (skin)
172 {
173 for (u32 i=0; i < gui::EGDF_COUNT; ++i)
174 skin->setFont(ConsoleFont, gui::EGUI_DEFAULT_FONT(i));
175 }
176 }
177#endif
178 }
179}
180
181//! destructor
182CIrrDeviceConsole::~CIrrDeviceConsole()
183{
184 // GUI and scene are dropped in the stub
185 if (CursorControl)
186 {
187 CursorControl->drop();
188 CursorControl = 0;
189 }
190 if (ConsoleFont)
191 {
192 ConsoleFont->drop();
193 ConsoleFont = 0;
194 }
195#ifdef _IRR_VT100_CONSOLE_
196 // reset terminal
197 fprintf(OutFile, "%cc", 27);
198#endif
199}
200
201//! runs the device. Returns false if device wants to be deleted
202bool CIrrDeviceConsole::run()
203{
204 // increment timer
205 os::Timer::tick();
206
207 // process Windows console input
208#ifdef _IRR_WINDOWS_NT_CONSOLE_
209
210 INPUT_RECORD in;
211 DWORD oldMode;
212 DWORD count, waste;
213
214 // get old input mode
215 GetConsoleMode(WindowsSTDIn, &oldMode);
216 SetConsoleMode(WindowsSTDIn, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT);
217
218 GetNumberOfConsoleInputEvents(WindowsSTDIn, &count);
219
220 // read keyboard and mouse input
221 while (count)
222 {
223 ReadConsoleInput(WindowsSTDIn, &in, 1, &waste );
224 switch(in.EventType)
225 {
226 case KEY_EVENT:
227 {
228 SEvent e;
229 e.EventType = EET_KEY_INPUT_EVENT;
230 e.KeyInput.PressedDown = (in.Event.KeyEvent.bKeyDown == TRUE);
231 e.KeyInput.Control = (in.Event.KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0;
232 e.KeyInput.Shift = (in.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) != 0;
233 e.KeyInput.Key = EKEY_CODE(in.Event.KeyEvent.wVirtualKeyCode);
234 e.KeyInput.Char = in.Event.KeyEvent.uChar.UnicodeChar;
235 postEventFromUser(e);
236 break;
237 }
238 case MOUSE_EVENT:
239 {
240 SEvent e;
241 e.EventType = EET_MOUSE_INPUT_EVENT;
242 e.MouseInput.X = in.Event.MouseEvent.dwMousePosition.X;
243 e.MouseInput.Y = in.Event.MouseEvent.dwMousePosition.Y;
244 e.MouseInput.Wheel = 0.f;
245 e.MouseInput.ButtonStates =
246 ( (in.Event.MouseEvent.dwButtonState & FROM_LEFT_1ST_BUTTON_PRESSED) ? EMBSM_LEFT : 0 ) |
247 ( (in.Event.MouseEvent.dwButtonState & RIGHTMOST_BUTTON_PRESSED) ? EMBSM_RIGHT : 0 ) |
248 ( (in.Event.MouseEvent.dwButtonState & FROM_LEFT_2ND_BUTTON_PRESSED) ? EMBSM_MIDDLE : 0 ) |
249 ( (in.Event.MouseEvent.dwButtonState & FROM_LEFT_3RD_BUTTON_PRESSED) ? EMBSM_EXTRA1 : 0 ) |
250 ( (in.Event.MouseEvent.dwButtonState & FROM_LEFT_4TH_BUTTON_PRESSED) ? EMBSM_EXTRA2 : 0 );
251
252 if (in.Event.MouseEvent.dwEventFlags & MOUSE_MOVED)
253 {
254 CursorControl->setPosition(core::position2di(e.MouseInput.X, e.MouseInput.Y));
255
256 // create mouse moved event
257 e.MouseInput.Event = EMIE_MOUSE_MOVED;
258 postEventFromUser(e);
259 }
260
261 if (in.Event.MouseEvent.dwEventFlags & MOUSE_WHEELED)
262 {
263 e.MouseInput.Event = EMIE_MOUSE_WHEEL;
264 e.MouseInput.Wheel = (in.Event.MouseEvent.dwButtonState & 0xFF000000) ? -1.0f : 1.0f;
265 postEventFromUser(e);
266 }
267
268 if ( (MouseButtonStates & EMBSM_LEFT) != (e.MouseInput.ButtonStates & EMBSM_LEFT) )
269 {
270 e.MouseInput.Event = (e.MouseInput.ButtonStates & EMBSM_LEFT) ? EMIE_LMOUSE_PRESSED_DOWN : EMIE_LMOUSE_LEFT_UP;
271 postEventFromUser(e);
272 }
273
274 if ( (MouseButtonStates & EMBSM_RIGHT) != (e.MouseInput.ButtonStates & EMBSM_RIGHT) )
275 {
276 e.MouseInput.Event = (e.MouseInput.ButtonStates & EMBSM_RIGHT) ? EMIE_RMOUSE_PRESSED_DOWN : EMIE_RMOUSE_LEFT_UP;
277 postEventFromUser(e);
278 }
279
280 if ( (MouseButtonStates & EMBSM_MIDDLE) != (e.MouseInput.ButtonStates & EMBSM_MIDDLE) )
281 {
282 e.MouseInput.Event = (e.MouseInput.ButtonStates & EMBSM_MIDDLE) ? EMIE_MMOUSE_PRESSED_DOWN : EMIE_MMOUSE_LEFT_UP;
283 postEventFromUser(e);
284 }
285
286 // save current button states
287 MouseButtonStates = e.MouseInput.ButtonStates;
288
289 break;
290 }
291 case WINDOW_BUFFER_SIZE_EVENT:
292 VideoDriver->OnResize(
293 core::dimension2d<u32>(in.Event.WindowBufferSizeEvent.dwSize.X,
294 in.Event.WindowBufferSizeEvent.dwSize.Y));
295 break;
296 case FOCUS_EVENT:
297 IsWindowFocused = (in.Event.FocusEvent.bSetFocus == TRUE);
298 break;
299 default:
300 break;
301 }
302 GetNumberOfConsoleInputEvents(WindowsSTDIn, &count);
303 }
304
305 // set input mode
306 SetConsoleMode(WindowsSTDIn, oldMode);
307#else
308 // todo: keyboard input from terminal in raw mode
309#endif
310
311 return !Close;
312}
313
314//! Cause the device to temporarily pause execution and let other processes to run
315// This should bring down processor usage without major performance loss for Irrlicht
316void CIrrDeviceConsole::yield()
317{
318#ifdef _IRR_WINDOWS_API_
319 Sleep(1);
320#else
321 struct timespec ts = {0,0};
322 nanosleep(&ts, NULL);
323#endif
324}
325
326//! Pause execution and let other processes to run for a specified amount of time.
327void CIrrDeviceConsole::sleep(u32 timeMs, bool pauseTimer)
328{
329 const bool wasStopped = Timer ? Timer->isStopped() : true;
330
331#ifdef _IRR_WINDOWS_API_
332 Sleep(timeMs);
333#else
334 struct timespec ts;
335 ts.tv_sec = (time_t) (timeMs / 1000);
336 ts.tv_nsec = (long) (timeMs % 1000) * 1000000;
337
338 if (pauseTimer && !wasStopped)
339 Timer->stop();
340
341 nanosleep(&ts, NULL);
342#endif
343
344 if (pauseTimer && !wasStopped)
345 Timer->start();
346}
347
348//! sets the caption of the window
349void CIrrDeviceConsole::setWindowCaption(const wchar_t* text)
350{
351#ifdef _IRR_WINDOWS_NT_CONSOLE_
352 SetConsoleTitleW(text);
353#endif
354}
355
356//! returns if window is active. if not, nothing need to be drawn
357bool CIrrDeviceConsole::isWindowActive() const
358{
359 // there is no window, but we always assume it is active
360 return true;
361}
362
363//! returns if window has focus
364bool CIrrDeviceConsole::isWindowFocused() const
365{
366 return IsWindowFocused;
367}
368
369//! returns if window is minimized
370bool CIrrDeviceConsole::isWindowMinimized() const
371{
372 return false;
373}
374
375//! presents a surface in the client area
376bool CIrrDeviceConsole::present(video::IImage* surface, void* windowId, core::rect<s32>* src)
377{
378
379 if (surface)
380 {
381 for (u32 y=0; y < surface->getDimension().Height; ++y)
382 {
383 for (u32 x=0; x< surface->getDimension().Width; ++x)
384 {
385 // get average pixel
386 u32 avg = surface->getPixel(x,y).getAverage() * (ASCIIArtCharsCount-1);
387 avg /= 255;
388 OutputBuffer[y] [x] = ASCIIArtChars[avg];
389 }
390 }
391 }
392#ifdef _IRR_USE_CONSOLE_FONT_
393 for (u32 i=0; i< Text.size(); ++i)
394 {
395 s32 y = Text[i].Pos.Y;
396
397 if ( y < (s32)OutputBuffer.size() && y > 0)
398 for (u32 c=0; c < Text[i].Text.size() && c + Text[i].Pos.X < OutputBuffer[y].size(); ++c)
399 //if (Text[i].Text[c] != ' ')
400 OutputBuffer[y] [c+Text[i].Pos.X] = Text[i].Text[c];
401 }
402 Text.clear();
403#endif
404
405 // draw output
406 for (u32 y=0; y<OutputBuffer.size(); ++y)
407 {
408 setTextCursorPos(0,y);
409 fprintf(OutFile, "%s", OutputBuffer[y].c_str());
410 }
411 return surface != 0;
412}
413
414//! notifies the device that it should close itself
415void CIrrDeviceConsole::closeDevice()
416{
417 // return false next time we run()
418 Close = true;
419}
420
421
422//! Sets if the window should be resizable in windowed mode.
423void CIrrDeviceConsole::setResizable(bool resize)
424{
425 // do nothing
426}
427
428
429//! Minimize the window.
430void CIrrDeviceConsole::minimizeWindow()
431{
432 // do nothing
433}
434
435
436//! Maximize window
437void CIrrDeviceConsole::maximizeWindow()
438{
439 // do nothing
440}
441
442
443//! Restore original window size
444void CIrrDeviceConsole::restoreWindow()
445{
446 // do nothing
447}
448
449
450void CIrrDeviceConsole::setTextCursorPos(s16 x, s16 y)
451{
452#ifdef _IRR_WINDOWS_NT_CONSOLE_
453 // move WinNT cursor
454 COORD Position;
455 Position.X = x;
456 Position.Y = y;
457 SetConsoleCursorPosition(WindowsSTDOut, Position);
458#elif defined(_IRR_VT100_CONSOLE_)
459 // send escape code
460 fprintf(OutFile, "%c[%d;%dH", 27, y, x);
461#else
462 // not implemented
463#endif
464}
465
466void CIrrDeviceConsole::addPostPresentText(s16 X, s16 Y, const wchar_t *text)
467{
468 SPostPresentText p;
469 p.Text = text;
470 p.Pos.X = X;
471 p.Pos.Y = Y;
472 Text.push_back(p);
473}
474
475} // end namespace irr
476
477#endif // _IRR_COMPILE_WITH_CONSOLE_DEVICE_