Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Console.cpp 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*!
  2. * \file src/Console.cpp
  3. * \brief Console 'overlay'
  4. *
  5. * \author xythobuz
  6. */
  7. #ifdef __APPLE__
  8. #include <OpenGL/gl.h>
  9. #elif defined WIN32
  10. #include <gl/glew.h>
  11. #include <gl/wglew.h>
  12. #else
  13. #include <GL/gl.h>
  14. #endif
  15. #include "config.h"
  16. #include "global.h"
  17. #include "Console.h"
  18. #include "main.h"
  19. #include "utils/strings.h"
  20. #include "utils/time.h"
  21. #define INPUT_BUFFER_SIZE 255
  22. Console::Console() {
  23. mVisible = false;
  24. mInputBuffer = new char[INPUT_BUFFER_SIZE + 1];
  25. mInputBuffer[INPUT_BUFFER_SIZE] = '\0';
  26. mInputBufferPointer = 0;
  27. mPartialInput = NULL;
  28. mHistoryPointer = 0;
  29. mUnfinishedInput = NULL;
  30. mLineOffset = 0;
  31. }
  32. Console::~Console() {
  33. if (mInputBuffer)
  34. delete [] mInputBuffer;
  35. if (mPartialInput)
  36. delete [] mPartialInput;
  37. if (mUnfinishedInput)
  38. delete [] mUnfinishedInput;
  39. while (mHistory.size() > 0) {
  40. char *tmp = mHistory.back();
  41. if (tmp != NULL)
  42. delete [] tmp;
  43. mHistory.pop_back();
  44. }
  45. while (mCommandHistory.size() > 0) {
  46. char *tmp = mCommandHistory.back();
  47. if (tmp != NULL)
  48. delete [] tmp;
  49. mCommandHistory.pop_back();
  50. }
  51. }
  52. void Console::setVisible(bool visible) {
  53. mVisible = visible;
  54. getWindow().setTextInput(mVisible);
  55. }
  56. bool Console::isVisible() {
  57. return mVisible;
  58. }
  59. void Console::print(const char *s, ...) {
  60. va_list args;
  61. va_start(args, s);
  62. char *tmp = bufferString(s, args);
  63. va_end(args);
  64. if (tmp != NULL) {
  65. mHistory.push_back(tmp);
  66. #ifdef DEBUG
  67. printf("%s\n", tmp);
  68. #endif
  69. }
  70. }
  71. #define LINE_GEOMETRY(window) unsigned int firstLine = 35; \
  72. unsigned int lastLine = (window.mHeight / 2) - 55; \
  73. unsigned int inputLine = (window.mHeight / 2) - 30; \
  74. unsigned int lineSteps = 20; \
  75. unsigned int lineCount = (lastLine - firstLine + lineSteps) / lineSteps; \
  76. while (((lineCount * lineSteps) + firstLine) < inputLine) { \
  77. lineSteps++; \
  78. lineCount = (lastLine - firstLine + lineSteps) / lineSteps; \
  79. }
  80. void Console::display() {
  81. if (mVisible) {
  82. // Calculate line drawing geometry
  83. // Depends on window height, so recalculate every time
  84. LINE_GEOMETRY(getWindow());
  85. // Draw half-transparent *overlay*
  86. glColor4f(0.0f, 0.0f, 0.0f, 0.75f);
  87. glDisable(GL_TEXTURE_2D);
  88. glRecti(0, 0, getWindow().mWidth, getWindow().mHeight / 2);
  89. glEnable(GL_TEXTURE_2D);
  90. int scrollIndicator;
  91. if (mHistory.size() > lineCount) {
  92. scrollIndicator = (mHistory.size() - lineCount - mLineOffset) * 100 / (mHistory.size() - lineCount);
  93. } else {
  94. scrollIndicator = 100;
  95. }
  96. getWindow().drawText(10, 10, 0.70f, OR_BLUE,
  97. "%s uptime %lus scroll %d%%", VERSION, systemTimerGet() / 1000, scrollIndicator);
  98. // Draw output log
  99. int end = lineCount;
  100. int drawOffset = 0;
  101. int historyOffset = 0;
  102. if (mHistory.size() < lineCount) {
  103. end = mHistory.size();
  104. drawOffset = lineCount - mHistory.size();
  105. } else if (lineCount < mHistory.size()) {
  106. historyOffset = mHistory.size() - lineCount;
  107. }
  108. for (int i = 0; i < end; i++) {
  109. getWindow().drawText(10, ((i + drawOffset) * lineSteps) + firstLine,
  110. 0.75f, OR_BLUE, "%s", mHistory[i + historyOffset - mLineOffset]);
  111. }
  112. // Draw current input
  113. if ((mInputBufferPointer > 0) && (mInputBuffer[0] != '\0')) {
  114. getWindow().drawText(10, inputLine, 0.75f, OR_BLUE, "> %s", mInputBuffer);
  115. } else {
  116. getWindow().drawText(10, inputLine, 0.75f, OR_BLUE, ">");
  117. }
  118. //! \todo display the current mPartialInput. The UTF-8 segfaults SDL-TTF, somehow?
  119. }
  120. }
  121. void Console::handleKeyboard(KeyboardButton key, bool pressed) {
  122. if (pressed && (key == enterKey)) {
  123. // Execute entered command
  124. if ((mInputBufferPointer > 0) && (mInputBuffer[0] != '\0')) {
  125. print("> %s", mInputBuffer);
  126. mCommandHistory.push_back(bufferString("%s", mInputBuffer));
  127. int error = getOpenRaider().command(mInputBuffer);
  128. if (error != 0) {
  129. print("Error Code: %d", error);
  130. }
  131. } else {
  132. print("> ");
  133. }
  134. // Clear partial and input buffer
  135. mInputBufferPointer = 0;
  136. mInputBuffer[0] = '\0';
  137. if (mPartialInput != NULL) {
  138. delete [] mPartialInput;
  139. mPartialInput = NULL;
  140. }
  141. mHistoryPointer = 0;
  142. }
  143. //! \fixme only deleting the last byte is not valid for non-ASCII UTF-8 strings
  144. if (pressed && (key == backspaceKey)) {
  145. if (mInputBufferPointer > 0) {
  146. mInputBufferPointer--;
  147. mInputBuffer[mInputBufferPointer] = '\0';
  148. }
  149. }
  150. if (pressed && ((key == upKey) || (key == downKey))) {
  151. moveInHistory(key == upKey);
  152. }
  153. }
  154. void Console::moveInHistory(bool up) {
  155. if (mCommandHistory.size() == 0)
  156. return;
  157. if (up) {
  158. if (mHistoryPointer < mCommandHistory.size()) {
  159. mHistoryPointer++;
  160. if (mHistoryPointer == 1) {
  161. mUnfinishedInput = bufferString("%s", mInputBuffer);
  162. }
  163. } else {
  164. return;
  165. }
  166. } else {
  167. if (mHistoryPointer > 0)
  168. mHistoryPointer--;
  169. else
  170. return;
  171. }
  172. if ((mHistoryPointer > 0) && (mHistoryPointer <= mCommandHistory.size())) {
  173. strcpy(mInputBuffer, mCommandHistory[mCommandHistory.size() - mHistoryPointer]);
  174. mInputBufferPointer = strlen(mInputBuffer);
  175. } else {
  176. if (mUnfinishedInput != NULL) {
  177. strcpy(mInputBuffer, mUnfinishedInput);
  178. mInputBufferPointer = strlen(mInputBuffer);
  179. delete [] mUnfinishedInput;
  180. mUnfinishedInput = NULL;
  181. } else {
  182. mInputBuffer[0] = '\0';
  183. mInputBufferPointer = 0;
  184. }
  185. }
  186. }
  187. void Console::handleText(char *text, bool notFinished) {
  188. //printf("Text: %s (%s)\n", text, (notFinished ? "not finished" : "finished"));
  189. // Always scroll to bottom when text input is received
  190. mLineOffset = 0;
  191. if (!notFinished) {
  192. // Finished entering character
  193. // delete previous partial character, if present
  194. if (mPartialInput != NULL) {
  195. delete [] mPartialInput;
  196. }
  197. //! \fixme Temporary hack filtering the console activation key
  198. if (text[0] == '`')
  199. return;
  200. // Append new input to buffer
  201. size_t length = strlen(text);
  202. if (length > 0) {
  203. if (((INPUT_BUFFER_SIZE - mInputBufferPointer) < length)) {
  204. printf("Console input buffer overflowed! (> %d)\n", INPUT_BUFFER_SIZE);
  205. return;
  206. }
  207. strcpy((mInputBuffer + mInputBufferPointer), text);
  208. mInputBufferPointer += length;
  209. mInputBuffer[mInputBufferPointer] = '\0';
  210. }
  211. } else {
  212. // Partial character received
  213. mPartialInput = bufferString("%s", text);
  214. }
  215. }
  216. void Console::handleMouseScroll(int xrel, int yrel) {
  217. LINE_GEOMETRY(getWindow());
  218. if (mHistory.size() > lineCount) {
  219. if (yrel > 0) {
  220. if (mLineOffset < (mHistory.size() - lineCount)) {
  221. mLineOffset++;
  222. }
  223. } else if (yrel < 0) {
  224. if (mLineOffset > 0) {
  225. mLineOffset--;
  226. }
  227. }
  228. }
  229. }