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.

Menu.cpp 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*!
  2. * \file src/Menu.cpp
  3. * \brief Main Menu
  4. *
  5. * \author xythobuz
  6. */
  7. #include "imgui/imgui.h"
  8. #include "global.h"
  9. #include "Console.h"
  10. #include "Game.h"
  11. #include "Log.h"
  12. #include "RunTime.h"
  13. #include "UI.h"
  14. #include "TextureManager.h"
  15. #include "system/Font.h"
  16. #include "system/Window.h"
  17. #include "utils/random.h"
  18. #include "utils/strings.h"
  19. #include "Menu.h"
  20. const glm::vec4 Menu::textColor(0.5f, 0.7f, 1.0f, 1.0f);
  21. const glm::vec4 Menu::selectedColor(1.0f, 0.0f, 0.0f, 1.0f);
  22. bool Menu::visible = false;
  23. Folder* Menu::mapFolder = nullptr;
  24. std::vector<Script> Menu::scripts;
  25. std::vector<Folder> Menu::paths;
  26. std::vector<int> Menu::images;
  27. int Menu::initialize() {
  28. shutdown();
  29. mapFolder = new Folder(RunTime::getPakDir());
  30. std::vector<File> files;
  31. mapFolder->findRecursiveFilesEndingWith(files, "tombpc.dat");
  32. for (auto& f : files) {
  33. scripts.emplace_back();
  34. auto s = scripts.size() - 1;
  35. images.push_back(-1);
  36. auto i = images.size() - 1;
  37. std::string path = convertPathDelimiter(removeLastPathElement(f.getPath()));
  38. paths.emplace_back(path);
  39. auto p = paths.size() - 1;
  40. if (scripts.at(s).load(f.getPath()) != 0) {
  41. Log::get(LOG_ERROR) << "Invalid Script: \"" << f.getPath()
  42. << "\"!" << Log::endl;
  43. scripts.pop_back();
  44. } else {
  45. // Load one of the pictures of this level
  46. std::vector<File> texFiles;
  47. paths.at(p).findRecursiveFilesEndingWith(texFiles, ".pcx");
  48. paths.at(p).findRecursiveFilesEndingWith(texFiles, ".bmp");
  49. paths.at(p).findRecursiveFilesEndingWith(texFiles, ".png");
  50. paths.at(p).findRecursiveFilesEndingWith(texFiles, ".tga");
  51. paths.at(p).findRecursiveFilesEndingWith(texFiles, ".jpg");
  52. if (texFiles.size() > 0) {
  53. int which = randomInteger(texFiles.size() - 1);
  54. images.at(i) = TextureManager::loadImage(texFiles.at(which).getPath(),
  55. TextureStorage::SYSTEM);
  56. }
  57. }
  58. }
  59. return 0;
  60. }
  61. void Menu::shutdown() {
  62. if (mapFolder != nullptr) {
  63. delete mapFolder;
  64. mapFolder = nullptr;
  65. }
  66. scripts.clear();
  67. paths.clear();
  68. images.clear(); //! \fixme free texture slots
  69. }
  70. void Menu::display() {
  71. if (!visible)
  72. return;
  73. glm::vec2 size = Window::getSize();
  74. if (!ImGui::Begin("Menu", nullptr, ImVec2(size.x, size.y), -1.0f, ImGuiWindowFlags_NoTitleBar
  75. | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse
  76. | ImGuiWindowFlags_NoSavedSettings)) {
  77. ImGui::End();
  78. return;
  79. }
  80. ImGui::SetWindowPos(ImVec2(0, 0));
  81. ImGui::SetWindowSize(ImVec2(size.x, size.y));
  82. // Draw heading with version string
  83. auto headingSize = ImGui::CalcTextSize(VERSION);
  84. headingSize.x *= 3.0f; headingSize.y *= 3.0f;
  85. ImGui::SetWindowFontScale(3.0f);
  86. ImGui::SameLine(0, (size.x / 2) - (headingSize.x / 2));
  87. ImGui::TextColored(textColor, VERSION);
  88. ImGui::SetWindowFontScale(1.0f);
  89. static ImGuiFs::Dialog* dialog = nullptr;
  90. const bool browseButtonPressed = ImGui::Button("Select Level File");
  91. if (browseButtonPressed) {
  92. if (dialog != nullptr)
  93. delete dialog;
  94. dialog = new ImGuiFs::Dialog();
  95. }
  96. if (dialog) {
  97. dialog->chooseFileDialog(browseButtonPressed, RunTime::getPakDir().c_str(),
  98. ".phd;.psx;.tub;.tr2", nullptr, ImVec2(400, 300), ImGui::GetMousePos());
  99. std::string selectedFile = dialog->getChosenPath();
  100. if (selectedFile.length() > 0) {
  101. Game::loadLevel(selectedFile);
  102. delete dialog;
  103. dialog = nullptr;
  104. }
  105. }
  106. ImGui::SameLine();
  107. if (ImGui::Button("Toggle Console")) {
  108. Console::setVisible(!Console::isVisible());
  109. }
  110. ImGui::SameLine();
  111. if (ImGui::Button("Toggle Debug Window")) {
  112. UI::setVisible(!UI::isVisible());
  113. }
  114. ImGui::Separator();
  115. // Set up columns for game list
  116. ImGui::Columns(3, "menuscripts");
  117. static bool offsets = false;
  118. if (!offsets) {
  119. ImGui::SetColumnOffset(1, 140.0f);
  120. ImGui::SetColumnOffset(2, size.x - 200.0f);
  121. offsets = true;
  122. }
  123. // List found games
  124. for (int i = 0; i < scripts.size(); i++) {
  125. ImGui::PushID(i);
  126. Script& s = scripts.at(i);
  127. if (images.at(i) >= 0) {
  128. auto bm = TextureManager::getBufferManager(images.at(i), TextureStorage::SYSTEM);
  129. ImGui::Image(bm, ImVec2(128, 128));
  130. }
  131. ImGui::NextColumn();
  132. ImGui::TextWrapped("Language: %s", s.getLanguage().c_str());
  133. ImGui::TextWrapped("Description: %s", s.getDescription().c_str());
  134. if (ImGui::TreeNode("", "%d Levels", s.levelCount())) {
  135. for (int l = 0; l < s.levelCount(); l++) {
  136. ImGui::PushID(l);
  137. ImGui::Bullet();
  138. ImGui::TextWrapped("%s (%s)", s.getLevelName(l).c_str(), s.getLevelFilename(l).c_str());
  139. ImGui::SameLine();
  140. if (ImGui::Button("Play level")) {
  141. std::vector<File> levelFiles;
  142. paths.at(i).findRecursiveFilesEndingWith(levelFiles,
  143. getLastPathElement(s.getLevelFilename(l)));
  144. if (levelFiles.size() == 0) {
  145. Log::get(LOG_ERROR) << "Could not find level \""
  146. << getLastPathElement(s.getLevelFilename(l))
  147. << "\"!" << Log::endl;
  148. } else {
  149. Game::loadLevel(levelFiles.at(0).getPath());
  150. }
  151. }
  152. ImGui::PopID();
  153. }
  154. ImGui::TreePop();
  155. }
  156. if (ImGui::TreeNode("", "%d Cut-Scenes", s.cutsceneCount())) {
  157. for (int c = 0; c < s.cutsceneCount(); c++) {
  158. ImGui::Bullet();
  159. ImGui::TextWrapped("%s", s.getCutsceneFilename(c).c_str());
  160. }
  161. ImGui::TreePop();
  162. }
  163. if (ImGui::TreeNode("", "%d Videos", s.videoCount())) {
  164. for (int v = 0; v < s.videoCount(); v++) {
  165. ImGui::Bullet();
  166. ImGui::TextWrapped("%s", s.getVideoFilename(v).c_str());
  167. }
  168. ImGui::TreePop();
  169. }
  170. if (ImGui::TreeNode("", "%d Pictures", s.pictureCount())) {
  171. for (int p = 0; p < s.pictureCount(); p++) {
  172. ImGui::Bullet();
  173. ImGui::TextWrapped("%s", s.getPictureFilename(p).c_str());
  174. }
  175. ImGui::TreePop();
  176. }
  177. if (ImGui::TreeNode("", "%d Titles", s.titleCount())) {
  178. for (int t = 0; t < s.titleCount(); t++) {
  179. ImGui::Bullet();
  180. ImGui::TextWrapped("%s", s.getTitleFilename(t).c_str());
  181. }
  182. ImGui::TreePop();
  183. }
  184. ImGui::NextColumn();
  185. ImGui::TextWrapped("Real Gameplay not yet implemented!");
  186. ImGui::NextColumn();
  187. if (i < (scripts.size() - 1))
  188. ImGui::Separator();
  189. ImGui::PopID();
  190. }
  191. ImGui::Columns(1);
  192. if (scripts.size() == 0) {
  193. ImGui::TextWrapped("OpenRaiders built-in TombRaider-Script detection mechanism could not find any suitable TR2/TR3 script files (called \"TOMBPC.DAT\") in your PAK folder \"%s\"! Use the \"Select Level File\" Button to load a single level without starting the entire game.",
  194. RunTime::getPakDir().c_str());
  195. }
  196. ImGui::End();
  197. }