Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

OpenRaider.cpp 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /*!
  2. * \file src/OpenRaider.cpp
  3. * \brief Main Game Object
  4. *
  5. * \author xythobuz
  6. */
  7. #include <cstdio>
  8. #include <cstring>
  9. #include <fstream>
  10. #include <iomanip>
  11. #include <sstream>
  12. #include "global.h"
  13. #include "commands/CommandAnimate.h"
  14. #include "commands/CommandBind.h"
  15. #include "commands/CommandEngine.h"
  16. #include "commands/CommandGame.h"
  17. #include "commands/CommandMove.h"
  18. #include "commands/CommandRender.h"
  19. #include "commands/CommandSet.h"
  20. #include "commands/CommandSound.h"
  21. #include "Console.h"
  22. #include "Font.h"
  23. #include "Game.h"
  24. #include "Menu.h"
  25. #include "Render.h"
  26. #include "Sound.h"
  27. #include "TextureManager.h"
  28. #include "TombRaider.h"
  29. #include "utils/strings.h"
  30. #include "utils/time.h"
  31. #include "Window.h"
  32. #include "OpenRaider.h"
  33. OpenRaider::OpenRaider() {
  34. mRunning = false;
  35. mFPS = false;
  36. mBaseDir = NULL;
  37. mPakDir = NULL;
  38. mAudioDir = NULL;
  39. mDataDir = NULL;
  40. for (int i = 0; i < ActionEventCount; i++)
  41. keyBindings[i] = unknownKey;
  42. commands.push_back(std::shared_ptr<Command>(new CommandLoad()));
  43. commands.push_back(std::shared_ptr<Command>(new CommandBind()));
  44. commands.push_back(std::shared_ptr<Command>(new CommandSet()));
  45. commands.push_back(std::shared_ptr<Command>(new CommandScreenshot()));
  46. commands.push_back(std::shared_ptr<Command>(new CommandAnimate()));
  47. commands.push_back(std::shared_ptr<Command>(new CommandMove()));
  48. commands.push_back(std::shared_ptr<Command>(new CommandMode()));
  49. commands.push_back(std::shared_ptr<Command>(new CommandRenderflag()));
  50. commands.push_back(std::shared_ptr<Command>(new CommandSound()));
  51. commands.push_back(std::shared_ptr<Command>(new CommandPos()));
  52. commands.push_back(std::shared_ptr<Command>(new CommandViewmodel()));
  53. commands.push_back(std::shared_ptr<Command>(new CommandPigtail()));
  54. commands.push_back(std::shared_ptr<Command>(new CommandPonypos()));
  55. commands.push_back(std::shared_ptr<Command>(new CommandQuit()));
  56. }
  57. OpenRaider::~OpenRaider() {
  58. delete mBaseDir;
  59. mBaseDir = NULL;
  60. delete mPakDir;
  61. mPakDir = NULL;
  62. delete mAudioDir;
  63. mAudioDir = NULL;
  64. delete mDataDir;
  65. mDataDir = NULL;
  66. }
  67. int OpenRaider::loadConfig(const char *config) {
  68. assert(config != NULL);
  69. assert(config[0] != '\0');
  70. char *configFile = fullPath(config, 0);
  71. getConsole() << "Loading config from \"" << configFile << "\"..." << Console::endl;
  72. std::ifstream file(configFile);
  73. if (!file) {
  74. getConsole() << "Could not open file!" << Console::endl;
  75. return -1;
  76. }
  77. for (std::string line; std::getline(file, line);) {
  78. if (line.length() == 0)
  79. continue;
  80. int error = command(line);
  81. if (error != 0)
  82. getConsole() << "Error Code: " << error << Console::endl;
  83. }
  84. file.close();
  85. return 0;
  86. }
  87. int OpenRaider::command(std::string c) {
  88. // Remove comment, if any
  89. size_t comment = c.find_first_of('#');
  90. if (comment != std::string::npos)
  91. c.erase(comment);
  92. // Execute command
  93. std::stringstream command(c);
  94. std::string cmd;
  95. command >> cmd;
  96. command >> std::boolalpha >> std::ws;
  97. if (cmd.length() == 0)
  98. return 0;
  99. // Print help
  100. if (cmd.compare("help") == 0) {
  101. std::string arg;
  102. command >> arg;
  103. if (arg.length() == 0) {
  104. // List all available commands
  105. getConsole() << "Available commands:" << Console::endl;
  106. getConsole() << std::right << std::setw(11);
  107. getConsole() << "help" << " - print command help" << Console::endl;
  108. for (auto &x : commands) {
  109. if (x) {
  110. getConsole() << std::right << std::setw(11);
  111. getConsole() << x->name() << " - " << x->brief() << Console::endl;
  112. }
  113. }
  114. getConsole() << "Use help COMMAND to get additional info" << Console::endl;
  115. getConsole() << "Pass BOOLs as true or false" << Console::endl;
  116. return 0;
  117. } else {
  118. // Show help for a specific command
  119. for (auto &x : commands) {
  120. if (x) {
  121. if (x->name().compare(arg) == 0) {
  122. x->printHelp();
  123. return 0;
  124. }
  125. }
  126. }
  127. getConsole() << "Unknown command: \"" << arg << "\"" << Console::endl;
  128. return -1;
  129. }
  130. }
  131. // Execute command
  132. for (auto &x : commands) {
  133. if (x) {
  134. if (x->name().compare(cmd) == 0) {
  135. return x->execute(command);
  136. }
  137. }
  138. }
  139. getConsole() << "Unknown command: \"" << cmd << "\"" << Console::endl;
  140. return -1;
  141. }
  142. int OpenRaider::initialize() {
  143. // Initialize Windowing
  144. int error = getWindow().initialize();
  145. if (error != 0) {
  146. printf("Could not initialize Window (%d)!\n", error);
  147. return -1;
  148. }
  149. // Initialize OpenGL
  150. error = getWindow().initializeGL();
  151. if (error != 0) {
  152. printf("Could not initialize OpenGL (%d)!\n", error);
  153. return -2;
  154. }
  155. // Initialize Font
  156. error = getFont().initialize();
  157. if (error != 0) {
  158. printf("Could not initialize Font (%d)!\n", error);
  159. return -3;
  160. }
  161. // Initialize Sound
  162. error = getSound().initialize();
  163. if (error != 0) {
  164. printf("Could not initialize Sound (%d)!\n", error);
  165. return -4;
  166. }
  167. // Initialize Texture Manager
  168. error = getTextureManager().initialize();
  169. if (error != 0) {
  170. printf("Could not initialize Textures (%d)!\n", error);
  171. return -5;
  172. }
  173. // Initialize game engine
  174. error = getGame().initialize();
  175. if (error != 0) {
  176. printf("Could not initialize Game (%d)!\n", error);
  177. return -6;
  178. }
  179. // Initialize main menu
  180. error = getMenu().initialize();
  181. if (error != 0) {
  182. printf("Could not initialize Menu (%d)!\n", error);
  183. return -7;
  184. }
  185. #ifdef DEBUG
  186. mFPS = true;
  187. #endif
  188. getMenu().setVisible(true);
  189. systemTimerReset();
  190. return 0;
  191. }
  192. void OpenRaider::run() {
  193. assert(mRunning == false);
  194. mRunning = true;
  195. while (mRunning)
  196. frame();
  197. }
  198. void OpenRaider::frame() {
  199. assert(mRunning == true);
  200. static clock_t fpsSum = 0, fpsCount = 0;
  201. static int fps = 0;
  202. clock_t startTime = systemTimerGet();
  203. // Get keyboard and mouse input
  204. getWindow().eventHandling();
  205. // Draw game scene
  206. getRender().display();
  207. // Draw 2D overlays (console and menu)
  208. getWindow().glEnter2D();
  209. getConsole().display();
  210. getMenu().display();
  211. // Draw FPS counter
  212. if (mFPS) {
  213. std::ostringstream fpsText;
  214. fpsText << fps << "FPS";
  215. getFont().drawText(10, getWindow().getHeight() - 20, 0.5f, BLUE, fpsText.str());
  216. }
  217. #ifdef DEBUG
  218. // Draw debug infos
  219. if (getGame().isLoaded() && (!getMenu().isVisible())) {
  220. for (int i = 0; i < 3; i++) {
  221. std::ostringstream axis;
  222. axis << getGame().getLara().getPos(i) / 256.0f << " (" << getGame().getLara().getAngle(i) << ")";
  223. getFont().drawText(10, getWindow().getHeight() - ((4 - i) * 20), 0.5f, BLUE, axis.str());
  224. }
  225. }
  226. #endif
  227. getWindow().glExit2D();
  228. // Put new frame on screen
  229. getWindow().swapBuffersGL();
  230. // Calculate FPS display value
  231. fpsCount++;
  232. fpsSum += (systemTimerGet() - startTime);
  233. if (fpsSum >= 250) {
  234. // Update every 250ms
  235. fps = (int)((float)fpsCount * (1000.0f / (float)fpsSum));
  236. fpsCount = fpsSum = 0;
  237. }
  238. }
  239. void OpenRaider::handleKeyboard(KeyboardButton key, bool pressed) {
  240. assert(key < unknownKey);
  241. assert(mRunning == true);
  242. if ((keyBindings[menuAction] == key) && pressed) {
  243. getMenu().setVisible(!getMenu().isVisible());
  244. } else if (!getMenu().isVisible()) {
  245. if ((keyBindings[consoleAction] == key) && pressed) {
  246. getConsole().setVisible(!getConsole().isVisible());
  247. } else if (!getConsole().isVisible()) {
  248. for (int i = forwardAction; i < ActionEventCount; i++) {
  249. if (keyBindings[i] == key) {
  250. getGame().handleAction((ActionEvents)i, !pressed);
  251. }
  252. }
  253. } else {
  254. getConsole().handleKeyboard(key, pressed);
  255. }
  256. } else {
  257. getMenu().handleKeyboard(key, pressed);
  258. }
  259. bool mousegrab = !(getMenu().isVisible() || getConsole().isVisible());
  260. if (mousegrab != getWindow().getMousegrab())
  261. getWindow().setMousegrab(mousegrab);
  262. }
  263. void OpenRaider::handleText(char *text, bool notFinished) {
  264. assert(text != NULL);
  265. assert(text[0] != '\0');
  266. assert(mRunning == true);
  267. if ((getConsole().isVisible()) && (!getMenu().isVisible())) {
  268. getConsole().handleText(text, notFinished);
  269. }
  270. bool mousegrab = !(getMenu().isVisible() || getConsole().isVisible());
  271. if (mousegrab != getWindow().getMousegrab())
  272. getWindow().setMousegrab(mousegrab);
  273. }
  274. void OpenRaider::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) {
  275. assert(button < unknownKey);
  276. assert(mRunning == true);
  277. if (getMenu().isVisible()) {
  278. getMenu().handleMouseClick(x, y, button, released);
  279. } else if (!getConsole().isVisible()) {
  280. for (int i = forwardAction; i < ActionEventCount; i++) {
  281. if (keyBindings[i] == button) {
  282. getGame().handleAction((ActionEvents)i, released);
  283. }
  284. }
  285. }
  286. bool mousegrab = !(getMenu().isVisible() || getConsole().isVisible());
  287. if (mousegrab != getWindow().getMousegrab())
  288. getWindow().setMousegrab(mousegrab);
  289. }
  290. void OpenRaider::handleMouseMotion(int xrel, int yrel) {
  291. assert((xrel != 0) || (yrel != 0));
  292. assert(mRunning == true);
  293. if ((!getConsole().isVisible()) && (!getMenu().isVisible())) {
  294. getGame().handleMouseMotion(xrel, yrel);
  295. }
  296. bool mousegrab = !(getMenu().isVisible() || getConsole().isVisible());
  297. if (mousegrab != getWindow().getMousegrab())
  298. getWindow().setMousegrab(mousegrab);
  299. }
  300. void OpenRaider::handleMouseScroll(int xrel, int yrel) {
  301. assert((xrel != 0) || (yrel != 0));
  302. assert(mRunning == true);
  303. if (getMenu().isVisible()) {
  304. getMenu().handleMouseScroll(xrel, yrel);
  305. } else if (getConsole().isVisible()) {
  306. getConsole().handleMouseScroll(xrel, yrel);
  307. }
  308. bool mousegrab = !(getMenu().isVisible() || getConsole().isVisible());
  309. if (mousegrab != getWindow().getMousegrab())
  310. getWindow().setMousegrab(mousegrab);
  311. }