Open Source Tomb Raider Engine
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

Menu.cpp 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*!
  2. * \file src/Menu.cpp
  3. * \brief Menu 'overlay'
  4. *
  5. * \author xythobuz
  6. */
  7. #include <cctype>
  8. #include <cstring>
  9. #include "global.h"
  10. #include "Console.h"
  11. #include "OpenRaider.h"
  12. #include "utils/strings.h"
  13. #include "TombRaider.h"
  14. #include "Window.h"
  15. #include "Menu.h"
  16. // TODO
  17. // Going up to / leads to the current working directory
  18. Menu::Menu() {
  19. mVisible = false;
  20. mCursor = 0;
  21. mMin = 0;
  22. mapFolder = nullptr;
  23. mainText.text = bufferString("%s", VERSION);
  24. mainText.color[0] = BLUE[0];
  25. mainText.color[1] = BLUE[1];
  26. mainText.color[2] = BLUE[2];
  27. mainText.color[3] = BLUE[3];
  28. mainText.scale = 1.2f;
  29. mainText.y = 10;
  30. mainText.w = 0;
  31. mainText.h = 0;
  32. }
  33. Menu::~Menu() {
  34. delete [] mainText.text;
  35. mainText.text = nullptr;
  36. delete mapFolder;
  37. mapFolder = nullptr;
  38. }
  39. int Menu::initialize() {
  40. return initialize(Folder(getOpenRaider().mPakDir));
  41. }
  42. int Menu::initialize(Folder folder) {
  43. if (mapFolder != nullptr)
  44. delete mapFolder;
  45. mapFolder = new Folder(folder);
  46. mMin = mCursor = 0;
  47. mapFolder->executeRemoveFiles([](File &f) {
  48. // Filter files based on file name
  49. if ((f.getName().compare(f.getName().length() - 4, 4, ".phd") != 0)
  50. && (f.getName().compare(f.getName().length() - 4, 4, ".tr2") != 0)
  51. && (f.getName().compare(f.getName().length() - 4, 4, ".tr4") != 0)
  52. && (f.getName().compare(f.getName().length() - 4, 4, ".trc") != 0)) {
  53. return true; // delete file from list
  54. }
  55. // Check maps for validity
  56. int error = TombRaider::checkMime(f.getPath().c_str());
  57. if (error != 0) {
  58. getConsole().print("Error: pak file '%s' %s",
  59. f.getName().c_str(), (error == -1) ? "not found" : "invalid");
  60. return true; // delete file from list
  61. }
  62. return false; // keep file on list
  63. });
  64. if ((mapFolder->fileCount() + mapFolder->folderCount()) > 0)
  65. mCursor = 1; // Don't select ".." by default
  66. return 0;
  67. }
  68. void Menu::setVisible(bool visible) {
  69. mVisible = visible;
  70. }
  71. bool Menu::isVisible() {
  72. return mVisible;
  73. }
  74. void Menu::display() {
  75. if (!mVisible)
  76. return;
  77. // Draw half-transparent *overlay*
  78. glColor4f(0.0f, 0.0f, 0.0f, 0.75f);
  79. glDisable(GL_TEXTURE_2D);
  80. glRecti(0, 0, (GLint)getWindow().getWidth(), (GLint)getWindow().getHeight());
  81. glEnable(GL_TEXTURE_2D);
  82. // Draw heading text, using FontString so we can get the
  83. // width of the drawn text to center it
  84. mainText.x = (getWindow().getWidth() / 2) - ((unsigned int)(mainText.w / 2));
  85. getFont().writeString(mainText);
  86. // Estimate displayable number of items
  87. int items = (getWindow().getHeight() - 60) / 25;
  88. // Print list of "..", folders, files
  89. for (long i = mMin; (i < (mMin + items))
  90. && (i < (mapFolder->folderCount() + mapFolder->fileCount() + 1)); i++) {
  91. if (i == 0) {
  92. getFont().drawText(25, 50, 0.75f, (mCursor == i) ? RED : BLUE, "..");
  93. } else {
  94. getFont().drawText(25, (unsigned int)(50 + (25 * (i - mMin))), 0.75f,
  95. (mCursor == i) ? RED : BLUE, "%s",
  96. ((i - 1) < mapFolder->folderCount()) ?
  97. (mapFolder->getFolder(i - 1).getName() + "/").c_str()
  98. : mapFolder->getFile(i - 1 - mapFolder->folderCount()).getName().c_str());
  99. }
  100. }
  101. }
  102. void Menu::play() {
  103. if (mCursor == 0) {
  104. if (initialize(mapFolder->getParent().getPath()) != 0) {
  105. //! \todo Display something if an error occurs
  106. }
  107. } else if ((mCursor - 1) < mapFolder->folderCount()) {
  108. if (initialize(mapFolder->getFolder(mCursor - 1).getPath()) != 0) {
  109. //! \todo Display something if an error occurs
  110. }
  111. } else {
  112. char *tmp = bufferString("load %s",
  113. mapFolder->getFile((unsigned long)mCursor - 1 - mapFolder->folderCount()).getPath().c_str());
  114. if (getOpenRaider().command(tmp) == 0) {
  115. setVisible(false);
  116. } else {
  117. //! \todo Display something if an error occurs
  118. }
  119. delete [] tmp;
  120. }
  121. }
  122. void Menu::handleKeyboard(KeyboardButton key, bool pressed) {
  123. if (!pressed)
  124. return;
  125. assert(mapFolder != nullptr);
  126. int items = (getWindow().getHeight() - 60) / 25;
  127. if (key == upKey) {
  128. if (mCursor > 0)
  129. mCursor--;
  130. else
  131. mCursor = (long)(mapFolder->folderCount() + mapFolder->fileCount());
  132. } else if (key == downKey) {
  133. if (mCursor < (long)(mapFolder->folderCount() + mapFolder->fileCount()))
  134. mCursor++;
  135. else
  136. mCursor = 0;
  137. } else if (key == enterKey) {
  138. play();
  139. }
  140. if (mCursor > (mMin + items - 1)) {
  141. mMin = mCursor - items + 1;
  142. } else if (mCursor < mMin) {
  143. mMin = mCursor;
  144. }
  145. }
  146. void Menu::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) {
  147. int items = (getWindow().getHeight() - 60) / 25;
  148. if (released || (button != leftmouseKey))
  149. return;
  150. if ((y >= 50) && (y <= (unsigned int)(50 + (25 * items)))) {
  151. y -= 50;
  152. if (mCursor == (mMin + (y / 25)))
  153. play();
  154. else
  155. mCursor = mMin + (y / 25);
  156. }
  157. }
  158. void Menu::handleMouseScroll(int xrel, int yrel) {
  159. assert((xrel != 0) || (yrel != 0));
  160. assert(mapFolder != nullptr);
  161. int items = (getWindow().getHeight() - 60) / 25;
  162. if ((mapFolder->folderCount() + mapFolder->fileCount() + 1) > items) {
  163. if (yrel < 0) {
  164. if (mMin < (mapFolder->folderCount() + mapFolder->fileCount() + 1 - items))
  165. mMin++;
  166. } else if (yrel > 0) {
  167. if (mMin > 0)
  168. mMin--;
  169. }
  170. if (mCursor < mMin) {
  171. mCursor = mMin;
  172. } else if (mCursor > (mMin + items - 1)) {
  173. mCursor = mMin + items - 1;
  174. }
  175. }
  176. }