Changeset 6140
- Timestamp:
- Nov 25, 2009, 12:09:02 AM (15 years ago)
- Location:
- code/branches/presentation2/src/libraries/core
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/presentation2/src/libraries/core/IOConsole.cc
r6122 r6140 32 32 #include <iomanip> 33 33 #include <iostream> 34 35 #include "util/Math.h" 34 36 #include "core/Game.h" 35 37 #include "core/input/InputBuffer.h" … … 456 458 // ################################## 457 459 460 #include <windows.h> 461 458 462 namespace orxonox 459 463 { … … 465 469 , promptString_("orxonox # ") 466 470 { 467 /*468 471 this->setTerminalMode(); 469 472 this->shell_->registerListener(this); … … 479 482 // Disable standard this->cout_ logging 480 483 OutputHandler::getInstance().disableCout(); 481 */ 484 // Redirect std::cout to an ostringstream 485 // (Other part is in the initialiser list) 486 std::cout.rdbuf(this->origCout_.rdbuf()); 487 488 // Make sure we make way for the status lines 489 this->update(Game::getInstance().getGameClock()); 482 490 } 483 491 484 492 IOConsole::~IOConsole() 485 493 { 486 // resetTerminalMode(); 494 // Empty all buffers 495 this->update(Game::getInstance().getGameClock()); 496 497 resetTerminalMode(); 487 498 this->shell_->destroy(); 488 499 489 /* 500 // Restore this->cout_ redirection 501 std::cout.rdbuf(this->cout_.rdbuf()); 490 502 // Enable standard this->cout_ logging again 491 503 OutputHandler::getInstance().enableCout(); 492 */493 504 } 494 505 495 506 void IOConsole::update(const Clock& time) 496 507 { 497 /* 498 unsigned char c = 0;499 while (std::cin.good())500 {501 c = std::cin.get();502 if ( std::cin.bad())508 while (true) 509 { 510 DWORD count; 511 INPUT_RECORD inrec; 512 PeekConsoleInput(this->stdInHandle_, &inrec, 1, &count); 513 if (count == 0) 503 514 break; 504 } 505 // Reset error flags in std::cin 506 std::cin.clear(); 507 508 // Determine terminal width and height 509 this->lastTerminalWidth_ = this->terminalWidth_; 510 this->lastTerminalHeight_ = this->terminalHeight_; 515 ReadConsoleInput(this->stdInHandle_, &inrec, 1, &count); 516 if (inrec.EventType == KEY_EVENT && inrec.Event.KeyEvent.bKeyDown) 517 { 518 // Process keyboard modifiers (Ctrl, Alt and Shift) 519 DWORD modifiersIn = inrec.Event.KeyEvent.dwControlKeyState; 520 int modifiersOut = 0; 521 if ((modifiersIn & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) != 0) 522 modifiersOut |= KeyboardModifier::Alt; 523 if ((modifiersIn & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0) 524 modifiersOut |= KeyboardModifier::Ctrl; 525 if ((modifiersIn & SHIFT_PRESSED) != 0) 526 modifiersOut |= KeyboardModifier::Shift; 527 528 // ASCII character (0 for special keys) 529 char asciiChar = inrec.Event.KeyEvent.uChar.AsciiChar; 530 531 // Process special keys and if not found, use Key::A as dummy (InputBuffer uses the ASCII text anyway) 532 switch (inrec.Event.KeyEvent.wVirtualKeyCode) 533 { 534 case VK_BACK: this->buffer_->buttonPressed(KeyEvent(KeyCode::Back, asciiChar, modifiersOut)); break; 535 case VK_TAB: this->buffer_->buttonPressed(KeyEvent(KeyCode::Back, asciiChar, modifiersOut)); break; 536 case VK_RETURN: this->buffer_->buttonPressed(KeyEvent(KeyCode::Back, asciiChar, modifiersOut)); break; 537 case VK_PAUSE: this->buffer_->buttonPressed(KeyEvent(KeyCode::Pause, asciiChar, modifiersOut)); break; 538 case VK_ESCAPE: this->buffer_->buttonPressed(KeyEvent(KeyCode::Escape, asciiChar, modifiersOut)); break; 539 case VK_SPACE: this->buffer_->buttonPressed(KeyEvent(KeyCode::Space, asciiChar, modifiersOut)); break; 540 case VK_PRIOR: this->buffer_->buttonPressed(KeyEvent(KeyCode::PageUp, asciiChar, modifiersOut)); break; 541 case VK_NEXT: this->buffer_->buttonPressed(KeyEvent(KeyCode::PageDown, asciiChar, modifiersOut)); break; 542 case VK_END: this->buffer_->buttonPressed(KeyEvent(KeyCode::End, asciiChar, modifiersOut)); break; 543 case VK_HOME: this->buffer_->buttonPressed(KeyEvent(KeyCode::Home, asciiChar, modifiersOut)); break; 544 case VK_LEFT: this->buffer_->buttonPressed(KeyEvent(KeyCode::Left, asciiChar, modifiersOut)); break; 545 case VK_UP: this->buffer_->buttonPressed(KeyEvent(KeyCode::Up, asciiChar, modifiersOut)); break; 546 case VK_RIGHT: this->buffer_->buttonPressed(KeyEvent(KeyCode::Right, asciiChar, modifiersOut)); break; 547 case VK_DOWN: this->buffer_->buttonPressed(KeyEvent(KeyCode::Down, asciiChar, modifiersOut)); break; 548 case VK_INSERT: this->buffer_->buttonPressed(KeyEvent(KeyCode::Insert, asciiChar, modifiersOut)); break; 549 case VK_DELETE: this->buffer_->buttonPressed(KeyEvent(KeyCode::Delete, asciiChar, modifiersOut)); break; 550 default: this->buffer_->buttonPressed(KeyEvent(KeyCode::A, asciiChar, modifiersOut)); 551 } 552 } 553 } 554 555 // Get info about cursor and terminal size 511 556 this->getTerminalSize(); 512 */ 557 558 // Refresh status line 559 this->printStatusLines(); 560 561 // Process output written to std::cout 562 if (!this->origCout_.str().empty()) 563 { 564 this->shell_->addOutputLine(this->origCout_.str()); 565 this->origCout_.str(""); 566 } 567 this->cout_.flush(); 513 568 } 514 569 515 570 void IOConsole::printLogText(const std::string& text) 516 571 { 572 std::string output = text; 573 int level = this->extractLogLevel(&output); 574 575 // Colour line 576 switch (level) 577 { 578 case 1: SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_RED | FOREGROUND_INTENSITY); break; 579 case 2: SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); break; 580 case 3: SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_BLUE | FOREGROUND_INTENSITY); break; 581 case 4: SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_GREEN); break; 582 default: break; 583 } 584 585 // Print output line 586 this->cout_ << output; 587 588 // Reset colour to white 589 SetConsoleTextAttribute(stdOutHandle_, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN); 517 590 } 518 591 519 592 void IOConsole::printInputLine() 520 593 { 594 this->moveCursorYAndHome(0); 595 this->clearCurrentLine(); 596 this->cout_ << this->promptString_ << this->shell_->getInput(); 597 this->moveCursorYAndHome(0); 598 this->moveCursor(this->promptString_.size() + this->buffer_->getCursorPosition(), 0); 521 599 } 522 600 523 601 void IOConsole::printStatusLines() 524 602 { 525 /*526 603 if (this->willPrintStatusLines()) 527 604 { 528 605 this->bStatusPrinted_ = true; 606 // Put cursor on home position, one line down the input line 607 this->moveCursorYAndHome(1); 608 this->cout_ << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, "; 609 this->cout_ << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms tick time"; 610 // Clear rest of the line 611 CONSOLE_SCREEN_BUFFER_INFO info; 612 GetConsoleScreenBufferInfo(this->stdOutHandle_, &info); 613 this->cout_ << std::string(info.dwSize.X - info.dwCursorPosition.X - 1, ' '); 614 // Restore cursor position 615 this->moveCursorYAndHome(-1); 616 this->moveCursor(this->promptString_.size() + this->buffer_->getCursorPosition(), 0); 529 617 } 530 618 else 531 619 this->bStatusPrinted_ = false; 532 */533 620 } 534 621 535 622 void IOConsole::setTerminalMode() 536 623 { 624 // Set the console mode to no-echo, raw input, and no window or mouse events 625 this->stdOutHandle_ = GetStdHandle(STD_OUTPUT_HANDLE); 626 this->stdInHandle_ = GetStdHandle(STD_INPUT_HANDLE); 627 if (this->stdInHandle_ == INVALID_HANDLE_VALUE 628 || !GetConsoleMode(this->stdInHandle_, &this->originalTerminalSettings_) 629 || !SetConsoleMode(this->stdInHandle_, 0)) 630 { 631 COUT(1) << "Error: Could not set Windows console settings" << std::endl; 632 return; 633 } 634 FlushConsoleInputBuffer(this->stdInHandle_); 537 635 } 538 636 539 637 void IOConsole::resetTerminalMode() 540 638 { 639 SetConsoleMode(this->stdInHandle_, this->originalTerminalSettings_); 640 } 641 642 //! Moves the console cursor around and inserts new lines when reaching the end. 643 //! Moving out on the right is just clamped though. 644 void IOConsole::moveCursor(int dx, int dy) 645 { 646 CONSOLE_SCREEN_BUFFER_INFO info; 647 GetConsoleScreenBufferInfo(this->stdOutHandle_, &info); 648 SHORT& x = info.dwCursorPosition.X; 649 x = clamp(x + dx, 0, info.dwSize.X - 1); 650 SHORT& y = info.dwCursorPosition.Y; 651 if (y + dy >= info.dwSize.Y) 652 { 653 // Insert new lines 654 this->cout_ << std::string(y + dy - info.dwSize.Y + 1, 'n'); 655 y = info.dwSize.Y - 1; 656 } 657 else if (y < 0) 658 y = 0; 659 else 660 y += dy; 661 SetConsoleCursorPosition(this->stdOutHandle_, info.dwCursorPosition); 662 } 663 664 void IOConsole::moveCursorYAndHome(int dy) 665 { 666 CONSOLE_SCREEN_BUFFER_INFO info; 667 GetConsoleScreenBufferInfo(this->stdOutHandle_, &info); 668 this->moveCursor(-info.dwCursorPosition.X, dy); 669 } 670 671 void IOConsole::clearCurrentLine() 672 { 673 CONSOLE_SCREEN_BUFFER_INFO info; 674 GetConsoleScreenBufferInfo(this->stdOutHandle_, &info); 675 info.dwCursorPosition.X = 0; 676 DWORD count; 677 FillConsoleOutputCharacter(this->stdOutHandle_, ' ', info.dwSize.X, info.dwCursorPosition, &count);; 541 678 } 542 679 543 680 void IOConsole::getTerminalSize() 544 681 { 682 CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo; 683 GetConsoleScreenBufferInfo(this->stdOutHandle_, &screenBufferInfo); 684 // dwSize is the maximum size. If you resize you will simply see scroll bars. 685 // And if you want to write outside these boundaries, you can't. 686 this->terminalWidth_ = screenBufferInfo.dwSize.X; 687 this->terminalHeight_ = screenBufferInfo.dwSize.Y; 545 688 } 546 689 … … 552 695 void IOConsole::onlyLastLineChanged() 553 696 { 697 this->moveCursorYAndHome(-1); 698 this->clearCurrentLine(); 699 this->printLogText(*(this->shell_->getNewestLineIterator())); 700 this->moveCursorYAndHome(1); 701 this->moveCursor(this->promptString_.size() + this->shell_->getInput().size(), 0); 702 this->cout_.flush(); 554 703 } 555 704 … … 557 706 void IOConsole::lineAdded() 558 707 { 708 // Move cursor to the beginning of the new (last) output line 709 this->moveCursorYAndHome(0); 710 // Print the new output lines 711 this->printLogText(*(this->shell_->getNewestLineIterator())); 712 // Move cursor down 713 this->moveCursorYAndHome(1); 714 // Print status and input lines 715 this->printInputLine(); 716 this->printStatusLines(); 717 this->cout_.flush(); 559 718 } 560 719 } -
code/branches/presentation2/src/libraries/core/IOConsole.h
r6105 r6140 41 41 #ifdef ORXONOX_PLATFORM_UNIX 42 42 struct termios; 43 #elif defined(ORXONOX_PLATFORM_WINDOWS) 44 #define WIN32_LEAN_AND_MEAN 45 #include <windows.h> 43 46 #endif 44 47 … … 91 94 #ifdef ORXONOX_PLATFORM_UNIX 92 95 termios* originalTerminalSettings_; 96 #elif defined(ORXONOX_PLATFORM_WINDOWS) 97 void moveCursor(int dx, int dy); 98 void moveCursorYAndHome(int dy); 99 void clearCurrentLine(); 100 101 DWORD originalTerminalSettings_; 102 HANDLE stdInHandle_; 103 HANDLE stdOutHandle_; 93 104 #endif 94 105
Note: See TracChangeset
for help on using the changeset viewer.