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.

OpenRaider.cpp 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. /*!
  2. * \file src/OpenRaider.cpp
  3. * \brief Main Game Object
  4. *
  5. * \author xythobuz
  6. */
  7. #include <cstdio>
  8. #include <cstring>
  9. #include <assert.h>
  10. #include <dirent.h>
  11. #include "WindowSDL.h"
  12. #include "config.h"
  13. #include "Console.h"
  14. #include "Game.h"
  15. #include "math/math.h"
  16. #include "Menu.h"
  17. #include "Sound.h"
  18. #include "TombRaider.h"
  19. #include "Window.h"
  20. #include "utils/strings.h"
  21. #include "utils/time.h"
  22. #include "OpenRaider.h"
  23. #define MAX_MS_PER_FRAME (1000 / MAXIMUM_FPS)
  24. OpenRaider::OpenRaider() {
  25. mInit = false;
  26. mRunning = false;
  27. mBaseDir = NULL;
  28. mPakDir = NULL;
  29. mAudioDir = NULL;
  30. mDataDir = NULL;
  31. mMapListFilled = false;
  32. mMenu = new Menu();
  33. mConsole = new Console();
  34. mSound = new Sound();
  35. mWindow = new WindowSDL();
  36. mGame = new Game();
  37. for (int i = 0; i < ActionEventCount; i++)
  38. keyBindings[i] = unknown;
  39. mCameraRotationDeltaX = OR_DEG_TO_RAD(1.0f);
  40. mCameraRotationDeltaY = OR_DEG_TO_RAD(1.0f);
  41. }
  42. OpenRaider::~OpenRaider() {
  43. if (mGame)
  44. delete mGame;
  45. if (mMenu)
  46. delete mMenu;
  47. if (mConsole)
  48. delete mConsole;
  49. if (mSound)
  50. delete mSound;
  51. if (mWindow)
  52. delete mWindow;
  53. if (mBaseDir)
  54. delete mBaseDir;
  55. if (mPakDir)
  56. delete mPakDir;
  57. if (mAudioDir)
  58. delete mAudioDir;
  59. if (mDataDir)
  60. delete mDataDir;
  61. while (mMapList.size() > 0) {
  62. delete [] mMapList.back();
  63. mMapList.pop_back();
  64. }
  65. }
  66. int OpenRaider::loadConfig(const char *config) {
  67. assert(config != NULL);
  68. assert(config[0] != '\0');
  69. char *configFile = fullPath(config, 0);
  70. mConsole->print("Loading config from \"%s\"...", configFile);
  71. FILE *f = fopen(configFile, "r");
  72. if (f == NULL) {
  73. mConsole->print("Could not open file!");
  74. return -1;
  75. }
  76. char buffer[256];
  77. while (fgets(buffer, 256, f) != NULL) {
  78. int error = command(buffer);
  79. if (error != 0) {
  80. mConsole->print("Error Code: %d", error);
  81. }
  82. }
  83. fclose(f);
  84. return 0;
  85. }
  86. int OpenRaider::command(const char *command) {
  87. assert(command != NULL);
  88. assert(command[0] != '\0');
  89. int returnValue = 0;
  90. char *cmd = bufferString("%s", command);
  91. size_t length = strlen(cmd);
  92. // Command ends at '\n' or # when a comment begins
  93. for (size_t i = 0; i < length; i++) {
  94. if (cmd[i] == '\n' || cmd[i] == '#') {
  95. cmd[i] = '\0';
  96. break;
  97. }
  98. }
  99. char *token = strtok(cmd, " \t");
  100. if (token != NULL) {
  101. // token is the command to execute
  102. // get arguments
  103. std::vector<char *> args;
  104. char *next;
  105. while ((next = strtok(NULL, " \t")) != NULL) {
  106. args.push_back(next);
  107. }
  108. // Execute
  109. returnValue = this->command(token, &args);
  110. }
  111. free(cmd);
  112. return returnValue;
  113. }
  114. int OpenRaider::command(const char *command, std::vector<char *> *args) {
  115. assert(command != NULL);
  116. assert(command[0] != '\0');
  117. assert(args != NULL);
  118. if (strcmp(command, "set") == 0) {
  119. if (args->size() != 2) {
  120. mConsole->print("Invalid use of set-command");
  121. return -2;
  122. } else {
  123. return set(args->at(0), args->at(1));
  124. }
  125. } else if (strcmp(command, "bind") == 0) {
  126. if (args->size() != 2) {
  127. mConsole->print("Invalid use of bind-command");
  128. return -3;
  129. } else {
  130. return bind(args->at(0), args->at(1));
  131. }
  132. } else if (strcmp(command, "quit") == 0) {
  133. exit(0);
  134. } else if (strcmp(command, "help") == 0) {
  135. if (args->size() == 0) {
  136. mConsole->print("Available commands:");
  137. mConsole->print(" load");
  138. mConsole->print(" set");
  139. mConsole->print(" bind");
  140. mConsole->print(" help");
  141. mConsole->print(" quit");
  142. mConsole->print("Use help COMMAND to get additional info");
  143. } else if (args->size() == 1) {
  144. return help(args->at(0));
  145. } else {
  146. mConsole->print("Invalid use of help-command");
  147. return -4;
  148. }
  149. } else if (strcmp(command, "load") == 0) {
  150. char *tmp = bufferString("%s/%s", mPakDir, args->at(0));
  151. int error = mGame->loadLevel(tmp);
  152. delete [] tmp;
  153. return error;
  154. } else {
  155. mConsole->print("Unknown command: %s ", command);
  156. return -1;
  157. }
  158. return 0;
  159. }
  160. int OpenRaider::help(const char *cmd) {
  161. if (strcmp(cmd, "set") == 0) {
  162. mConsole->print("set-Command Usage:");
  163. mConsole->print(" set VAR VAL");
  164. mConsole->print("Available Variables:");
  165. mConsole->print(" basedir STRING");
  166. mConsole->print(" pakdir STRING");
  167. mConsole->print(" audiodir STRING");
  168. mConsole->print(" datadir STRING");
  169. mConsole->print(" font STRING");
  170. mConsole->print(" gldriver STRING");
  171. mConsole->print(" size \"INTxINT\"");
  172. mConsole->print(" fullscreen BOOL");
  173. mConsole->print(" audio BOOL");
  174. mConsole->print(" volume BOOL");
  175. mConsole->print(" mouse_x FLOAT");
  176. mConsole->print(" mouse_y FLOAT");
  177. mConsole->print("Enclose STRINGs with \"\"!");
  178. mConsole->print("size expects a STRING in the specified format");
  179. } else if (strcmp(cmd, "bind") == 0) {
  180. mConsole->print("bind-Command Usage:");
  181. mConsole->print(" bind ACTION KEY");
  182. mConsole->print("Available Actions:");
  183. mConsole->print(" menu");
  184. mConsole->print(" console");
  185. mConsole->print(" forward");
  186. mConsole->print(" backward");
  187. mConsole->print(" left");
  188. mConsole->print(" right");
  189. mConsole->print(" jump");
  190. mConsole->print(" crouch");
  191. mConsole->print(" use");
  192. mConsole->print(" holster");
  193. mConsole->print("Key-Format:");
  194. mConsole->print(" 'a' or '1' for character/number keys");
  195. mConsole->print(" \"leftctrl\" for symbols and special keys");
  196. } else if (strcmp(cmd, "load") == 0) {
  197. mConsole->print("load-Command Usage:");
  198. mConsole->print(" load levelfile.name");
  199. } else {
  200. mConsole->print("No help available for %s", cmd);
  201. return -1;
  202. }
  203. return 0;
  204. }
  205. char *OpenRaider::expandDirectoryNames(const char *s) {
  206. const char *base = "$(basedir)";
  207. const char *pak = "$(pakdir)";
  208. const char *audio = "$(audiodir)";
  209. const char *data = "$(datadir)";
  210. if (mBaseDir != NULL) {
  211. if (strstr(s, base) != NULL) {
  212. return stringReplace(s, base, mBaseDir);
  213. }
  214. }
  215. if (mPakDir != NULL) {
  216. if (strstr(s, pak) != NULL) {
  217. return stringReplace(s, pak, mPakDir);
  218. }
  219. }
  220. if (mAudioDir != NULL) {
  221. if (strstr(s, audio) != NULL) {
  222. return stringReplace(s, audio, mAudioDir);
  223. }
  224. }
  225. if (mDataDir != NULL) {
  226. if (strstr(s, data) != NULL) {
  227. return stringReplace(s, data, mDataDir);
  228. }
  229. }
  230. return NULL;
  231. }
  232. #define CHANGE_DIR_WITH_EXPANSION(a) do { \
  233. char *quotes = stringRemoveQuotes(value); \
  234. char *tmp = expandDirectoryNames(quotes); \
  235. if (tmp == NULL) { \
  236. a = fullPath(quotes, 0); \
  237. } else { \
  238. a = fullPath(tmp, 0); \
  239. delete [] tmp; \
  240. } \
  241. delete [] quotes; \
  242. } while(false)
  243. int OpenRaider::set(const char *var, const char *value) {
  244. if (strcmp(var, "size") == 0) {
  245. // value has format like "\"1024x768\""
  246. unsigned int w = DEFAULT_WIDTH, h = DEFAULT_HEIGHT;
  247. if (sscanf(value, "\"%dx%d\"", &w, &h) != 2) {
  248. mConsole->print("set-size-Error: Invalid value (%s)", value);
  249. return -2;
  250. }
  251. mWindow->setSize(w, h);
  252. } else if (strcmp(var, "fullscreen") == 0) {
  253. bool fullscreen = false;
  254. if (readBool(value, &fullscreen) != 0) {
  255. mConsole->print("set-fullscreen-Error: Invalid value (%s)", value);
  256. return -3;
  257. }
  258. mWindow->setFullscreen(fullscreen);
  259. } else if (strcmp(var, "gldriver") == 0) {
  260. mWindow->setDriver(value);
  261. } else if (strcmp(var, "audio") == 0) {
  262. bool audio = false;
  263. if (readBool(value, &audio) != 0) {
  264. mConsole->print("set-audio-Error: Invalid value (%s)", value);
  265. return -4;
  266. }
  267. mSound->setEnabled(audio);
  268. } else if (strcmp(var, "volume") == 0) {
  269. float vol = 1.0f;
  270. if (sscanf(value, "%f", &vol) != 1) {
  271. mConsole->print("set-volume-Error: Invalid value (%s)", value);
  272. return -5;
  273. }
  274. mSound->setVolume(vol);
  275. } else if (strcmp(var, "mouse_x") == 0) {
  276. float sense = 1.0f;
  277. if (sscanf(value, "%f", &sense) != 1) {
  278. mConsole->print("set-mouse_x-Error: Invalid value (%s)", value);
  279. return -6;
  280. }
  281. mCameraRotationDeltaX = OR_DEG_TO_RAD(sense);
  282. } else if (strcmp(var, "mouse_y") == 0) {
  283. float sense = 1.0f;
  284. if (sscanf(value, "%f", &sense) != 1) {
  285. mConsole->print("set-mouse_y-Error: Invalid value (%s)", value);
  286. return -7;
  287. }
  288. mCameraRotationDeltaY = OR_DEG_TO_RAD(sense);
  289. } else if (strcmp(var, "basedir") == 0) {
  290. CHANGE_DIR_WITH_EXPANSION(mBaseDir);
  291. } else if (strcmp(var, "pakdir") == 0) {
  292. CHANGE_DIR_WITH_EXPANSION(mPakDir);
  293. } else if (strcmp(var, "audiodir") == 0) {
  294. CHANGE_DIR_WITH_EXPANSION(mAudioDir);
  295. } else if (strcmp(var, "datadir") == 0) {
  296. CHANGE_DIR_WITH_EXPANSION(mDataDir);
  297. } else if (strcmp(var, "font") == 0) {
  298. char *quotes = stringReplace(value, "\"", "");
  299. char *tmp = expandDirectoryNames(quotes);
  300. if (tmp == NULL) {
  301. mWindow->setFont(quotes);
  302. } else {
  303. mWindow->setFont(tmp);
  304. delete [] tmp;
  305. }
  306. delete [] quotes;
  307. } else {
  308. mConsole->print("set-Error: Unknown variable (%s = %s)", var, value);
  309. return -1;
  310. }
  311. return 0;
  312. }
  313. int OpenRaider::bind(const char *action, const char *key) {
  314. const char *tmp = action;
  315. if (action[0] == '+')
  316. tmp++;
  317. if (strcmp(tmp, "menu") == 0) {
  318. return bind(menuAction, key);
  319. } else if (strcmp(tmp, "console") == 0) {
  320. return bind(consoleAction, key);
  321. } else if (strcmp(tmp, "forward") == 0) {
  322. return bind(forwardAction, key);
  323. } else if (strcmp(tmp, "backward") == 0) {
  324. return bind(backwardAction, key);
  325. } else if (strcmp(tmp, "left") == 0) {
  326. return bind(leftAction, key);
  327. } else if (strcmp(tmp, "right") == 0) {
  328. return bind(rightAction, key);
  329. } else if (strcmp(tmp, "jump") == 0) {
  330. return bind(jumpAction, key);
  331. } else if (strcmp(tmp, "crouch") == 0) {
  332. return bind(crouchAction, key);
  333. } else if (strcmp(tmp, "use") == 0) {
  334. return bind(useAction, key);
  335. } else if (strcmp(tmp, "holster") == 0) {
  336. return bind(holsterAction, key);
  337. } else {
  338. mConsole->print("bind-Error: Unknown action (%s --> %s)", key, action);
  339. return -1;
  340. }
  341. }
  342. int OpenRaider::bind(ActionEvents action, const char *key) {
  343. assert(action != ActionEventCount);
  344. assert(key != NULL);
  345. assert(key[0] != '\0');
  346. size_t length = strlen(key);
  347. if ((key[0] == '\'') && (key[length - 1] == '\'') && (length == 3)) {
  348. // Literal character like w, a, s, d, 0, 1...
  349. char c = key[1];
  350. if (((c >= '0') && (c <= '9'))
  351. || ((c >= 'a') && (c <= 'z'))) {
  352. keyBindings[action] = (KeyboardButton)c;
  353. } else {
  354. mConsole->print("bind-\'\'-Error: Unknown key (%s)", key);
  355. return -1;
  356. }
  357. } else if ((key[0] == '\"') && (key[length - 1] == '\"')) {
  358. // Special characters like tilde, esc, quote...
  359. char *tmp = stringRemoveQuotes(key);
  360. if (strcmp(tmp, "quote") == 0) {
  361. keyBindings[action] = quote;
  362. } else if (strcmp(tmp, "backslash") == 0) {
  363. keyBindings[action] = quote;
  364. } else if (strcmp(tmp, "backspace") == 0) {
  365. keyBindings[action] = backspace;
  366. } else if (strcmp(tmp, "capslock") == 0) {
  367. keyBindings[action] = capslock;
  368. } else if (strcmp(tmp, "comma") == 0) {
  369. keyBindings[action] = comma;
  370. } else if (strcmp(tmp, "del") == 0) {
  371. keyBindings[action] = del;
  372. } else if (strcmp(tmp, "up") == 0) {
  373. keyBindings[action] = up;
  374. } else if (strcmp(tmp, "down") == 0) {
  375. keyBindings[action] = down;
  376. } else if (strcmp(tmp, "left") == 0) {
  377. keyBindings[action] = left;
  378. } else if (strcmp(tmp, "right") == 0) {
  379. keyBindings[action] = right;
  380. } else if (strcmp(tmp, "end") == 0) {
  381. keyBindings[action] = end;
  382. } else if (strcmp(tmp, "equals") == 0) {
  383. keyBindings[action] = equals;
  384. } else if (strcmp(tmp, "escape") == 0) {
  385. keyBindings[action] = escape;
  386. } else if (strcmp(tmp, "f1") == 0) {
  387. keyBindings[action] = f1;
  388. } else if (strcmp(tmp, "f2") == 0) {
  389. keyBindings[action] = f2;
  390. } else if (strcmp(tmp, "f3") == 0) {
  391. keyBindings[action] = f3;
  392. } else if (strcmp(tmp, "f4") == 0) {
  393. keyBindings[action] = f4;
  394. } else if (strcmp(tmp, "f5") == 0) {
  395. keyBindings[action] = f5;
  396. } else if (strcmp(tmp, "f6") == 0) {
  397. keyBindings[action] = f6;
  398. } else if (strcmp(tmp, "f7") == 0) {
  399. keyBindings[action] = f7;
  400. } else if (strcmp(tmp, "f8") == 0) {
  401. keyBindings[action] = f8;
  402. } else if (strcmp(tmp, "f9") == 0) {
  403. keyBindings[action] = f9;
  404. } else if (strcmp(tmp, "f10") == 0) {
  405. keyBindings[action] = f10;
  406. } else if (strcmp(tmp, "f11") == 0) {
  407. keyBindings[action] = f11;
  408. } else if (strcmp(tmp, "f12") == 0) {
  409. keyBindings[action] = f12;
  410. } else if (strcmp(tmp, "backquote") == 0) {
  411. keyBindings[action] = backquote;
  412. } else if (strcmp(tmp, "home") == 0) {
  413. keyBindings[action] = home;
  414. } else if (strcmp(tmp, "insert") == 0) {
  415. keyBindings[action] = insert;
  416. } else if (strcmp(tmp, "leftalt") == 0) {
  417. keyBindings[action] = leftalt;
  418. } else if (strcmp(tmp, "leftctrl") == 0) {
  419. keyBindings[action] = leftctrl;
  420. } else if (strcmp(tmp, "leftbracket") == 0) {
  421. keyBindings[action] = leftbracket;
  422. } else if (strcmp(tmp, "leftgui") == 0) {
  423. keyBindings[action] = leftgui;
  424. } else if (strcmp(tmp, "leftshift") == 0) {
  425. keyBindings[action] = leftshift;
  426. } else if (strcmp(tmp, "minus") == 0) {
  427. keyBindings[action] = minus;
  428. } else if (strcmp(tmp, "numlock") == 0) {
  429. keyBindings[action] = numlock;
  430. } else if (strcmp(tmp, "pagedown") == 0) {
  431. keyBindings[action] = pagedown;
  432. } else if (strcmp(tmp, "pageup") == 0) {
  433. keyBindings[action] = pageup;
  434. } else if (strcmp(tmp, "pause") == 0) {
  435. keyBindings[action] = pause;
  436. } else if (strcmp(tmp, "dot") == 0) {
  437. keyBindings[action] = dot;
  438. } else if (strcmp(tmp, "rightalt") == 0) {
  439. keyBindings[action] = rightalt;
  440. } else if (strcmp(tmp, "rightctrl") == 0) {
  441. keyBindings[action] = rightctrl;
  442. } else if (strcmp(tmp, "enter") == 0) {
  443. keyBindings[action] = enter;
  444. } else if (strcmp(tmp, "rightgui") == 0) {
  445. keyBindings[action] = rightgui;
  446. } else if (strcmp(tmp, "rightbracket") == 0) {
  447. keyBindings[action] = rightbracket;
  448. } else if (strcmp(tmp, "rightshift") == 0) {
  449. keyBindings[action] = rightshift;
  450. } else if (strcmp(tmp, "scrolllock") == 0) {
  451. keyBindings[action] = scrolllock;
  452. } else if (strcmp(tmp, "semicolon") == 0) {
  453. keyBindings[action] = semicolon;
  454. } else if (strcmp(tmp, "slash") == 0) {
  455. keyBindings[action] = slash;
  456. } else if (strcmp(tmp, "space") == 0) {
  457. keyBindings[action] = space;
  458. } else if (strcmp(tmp, "tab") == 0) {
  459. keyBindings[action] = tab;
  460. } else if (strcmp(tmp, "leftmouse") == 0) {
  461. keyBindings[action] = leftmouse;
  462. } else if (strcmp(tmp, "middlemouse") == 0) {
  463. keyBindings[action] = middlemouse;
  464. } else if (strcmp(tmp, "rightmouse") == 0) {
  465. keyBindings[action] = rightmouse;
  466. } else {
  467. mConsole->print("bind-\"\"-Error: Unknown key (%s)", key);
  468. delete [] tmp;
  469. return -2;
  470. }
  471. delete [] tmp;
  472. } else {
  473. mConsole->print("bind-Error: Unknown key (%s)", key);
  474. return -3;
  475. }
  476. return 0;
  477. }
  478. void OpenRaider::loadPakFolderRecursive(const char *dir) {
  479. struct dirent *ep;
  480. DIR *pakDir;
  481. pakDir = opendir(dir);
  482. if (pakDir != NULL) {
  483. while ((ep = readdir(pakDir)) != NULL) {
  484. if (ep->d_type == DT_DIR) {
  485. if ((strcmp(".", ep->d_name) != 0)
  486. && (strcmp("..", ep->d_name) != 0)) {
  487. char *tmp = bufferString("%s%s", dir, ep->d_name);
  488. char *next = fullPath(tmp, '/');
  489. loadPakFolderRecursive(next);
  490. delete next;
  491. delete tmp;
  492. }
  493. } else {
  494. char *fullPathMap = bufferString("%s%s", dir, ep->d_name);
  495. char *lowerPath = bufferString("%s", fullPathMap);
  496. for (char *p = lowerPath; *p; ++p) *p = (char)tolower(*p);
  497. // Check for valid extension
  498. if (stringEndsWith(lowerPath, ".phd")
  499. || stringEndsWith(lowerPath, ".tr2")
  500. || stringEndsWith(lowerPath, ".tr4")
  501. || stringEndsWith(lowerPath, ".trc")) {
  502. int error = TombRaider::checkMime(fullPathMap);
  503. if (error == 0) {
  504. // Just load relative filename
  505. mMapList.push_back(bufferString("%s", (fullPathMap + strlen(mPakDir) + 1)));
  506. } else {
  507. mConsole->print("Error: pak file '%s' %s",
  508. fullPathMap, (error == -1) ? "not found" : "invalid");
  509. }
  510. }
  511. delete [] lowerPath;
  512. delete [] fullPathMap;
  513. }
  514. }
  515. closedir(pakDir);
  516. } else {
  517. mConsole->print("Could not open PAK dir %s!", dir);
  518. }
  519. }
  520. void OpenRaider::fillMapList() {
  521. char *tmp = fullPath(mPakDir, '/');
  522. loadPakFolderRecursive(tmp);
  523. delete [] tmp;
  524. mMapListFilled = true;
  525. }
  526. int OpenRaider::initialize() {
  527. assert(mInit == false);
  528. assert(mRunning == false);
  529. // Initialize Windowing
  530. if (mWindow->initialize() != 0)
  531. return -1;
  532. // Initialize OpenGL
  533. if (mWindow->initializeGL() != 0)
  534. return -2;
  535. // Initialize window font
  536. if (mWindow->initializeFont() != 0)
  537. return -3;
  538. // Initialize sound
  539. if (mSound->initialize() != 0)
  540. return -4;
  541. // Initialize game engine
  542. if (mGame->initialize() != 0)
  543. return -5;
  544. mMenu->setVisible(true);
  545. mInit = true;
  546. return 0;
  547. }
  548. void OpenRaider::run() {
  549. assert(mInit == true);
  550. assert(mRunning == false);
  551. mRunning = true;
  552. while (mRunning) {
  553. clock_t startTime = systemTimerGet();
  554. // Get keyboard and mouse input
  555. mWindow->eventHandling();
  556. // Clear screen
  557. glClearColor(0.00f, 0.00f, 0.00f, 1.0f);
  558. glClear(GL_COLOR_BUFFER_BIT);
  559. // Draw game scene
  560. mGame->display();
  561. // Draw 2D overlays (console and menu)
  562. mWindow->glEnter2D();
  563. mConsole->display();
  564. mMenu->display();
  565. mWindow->glExit2D();
  566. // Put new frame on screen
  567. mWindow->swapBuffersGL();
  568. // Fill map list after first render pass,
  569. // so menu *loading screen* is visible
  570. if (!mMapListFilled)
  571. fillMapList();
  572. // Check time it took to compute the last frame
  573. // and delay for an appropriate amount of time
  574. clock_t stopTime = systemTimerGet();
  575. if (MAX_MS_PER_FRAME > (stopTime - startTime))
  576. mWindow->delay(MAX_MS_PER_FRAME - (stopTime - startTime));
  577. }
  578. }
  579. void OpenRaider::handleKeyboard(KeyboardButton key, bool pressed) {
  580. if ((keyBindings[menuAction] == key) && pressed) {
  581. mMenu->setVisible(!mMenu->isVisible());
  582. } else if (!mMenu->isVisible()) {
  583. if ((keyBindings[consoleAction] == key) && pressed) {
  584. mConsole->setVisible(!mConsole->isVisible());
  585. } else if (!mConsole->isVisible()) {
  586. for (int i = forwardAction; i < ActionEventCount; i++) {
  587. if (keyBindings[i] == key) {
  588. mGame->handleAction((ActionEvents)i, pressed);
  589. }
  590. }
  591. } else {
  592. mConsole->handleKeyboard(key, pressed);
  593. }
  594. } else {
  595. mMenu->handleKeyboard(key, pressed);
  596. }
  597. mWindow->setMousegrab(!(mMenu->isVisible() || mConsole->isVisible()));
  598. }
  599. void OpenRaider::handleText(char *text, bool notFinished) {
  600. if ((mConsole->isVisible()) && (!mMenu->isVisible())) {
  601. mConsole->handleText(text, notFinished);
  602. }
  603. }
  604. void OpenRaider::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) {
  605. if (mMenu->isVisible()) {
  606. mMenu->handleMouseClick(x, y, button, released);
  607. } else if (!mConsole->isVisible()) {
  608. for (int i = forwardAction; i < ActionEventCount; i++) {
  609. if (keyBindings[i] == button) {
  610. mGame->handleAction((ActionEvents)i, !released);
  611. }
  612. }
  613. }
  614. }
  615. void OpenRaider::handleMouseMotion(int xrel, int yrel) {
  616. if ((!mConsole->isVisible()) && (!mMenu->isVisible())) {
  617. mGame->handleMouseMotion(xrel, yrel);
  618. }
  619. }
  620. void OpenRaider::handleMouseScroll(int xrel, int yrel) {
  621. if ((mConsole->isVisible()) && (!mMenu->isVisible())) {
  622. mConsole->handleMouseScroll(xrel, yrel);
  623. }
  624. }