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

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