Open Source Tomb Raider Engine
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

OpenRaider.cpp 43KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198
  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 "WindowSDL.h"
  11. #include "config.h"
  12. #include "Console.h"
  13. #include "Game.h"
  14. #include "main.h"
  15. #include "math/math.h"
  16. #include "Menu.h"
  17. #include "Sound.h"
  18. #include "TombRaider.h"
  19. #include "utils/strings.h"
  20. #include "utils/time.h"
  21. #include "OpenRaider.h"
  22. OpenRaider::OpenRaider() {
  23. mRunning = false;
  24. mFPS = false;
  25. mBaseDir = NULL;
  26. mPakDir = NULL;
  27. mAudioDir = NULL;
  28. mDataDir = NULL;
  29. for (int i = 0; i < ActionEventCount; i++)
  30. keyBindings[i] = unknownKey;
  31. }
  32. OpenRaider::~OpenRaider() {
  33. if (mBaseDir)
  34. delete mBaseDir;
  35. if (mPakDir)
  36. delete mPakDir;
  37. if (mAudioDir)
  38. delete mAudioDir;
  39. if (mDataDir)
  40. delete mDataDir;
  41. }
  42. int OpenRaider::initialize() {
  43. // Initialize Windowing
  44. int error = getWindow().initialize();
  45. if (error != 0) {
  46. printf("Could not initialize Window (%d)!\n", error);
  47. return -1;
  48. }
  49. // Initialize OpenGL
  50. error = getWindow().initializeGL();
  51. if (error != 0) {
  52. printf("Could not initialize OpenGL (%d)!\n", error);
  53. return -2;
  54. }
  55. error = getWindow().initializeFont();
  56. if (error != 0) {
  57. printf("Could not initialize SDL-TTF (%d)!\n", error);
  58. return -3;
  59. }
  60. error = getSound().initialize();
  61. if (error != 0) {
  62. printf("Could not initialize Sound (%d)!\n", error);
  63. return -4;
  64. }
  65. // Initialize game engine
  66. error = getGame().initialize();
  67. if (error != 0) {
  68. printf("Could not initialize Game Engine (%d)!\n", error);
  69. return -5;
  70. }
  71. #ifdef DEBUG
  72. mFPS = true;
  73. #endif
  74. getMenu().setVisible(true);
  75. systemTimerReset();
  76. return 0;
  77. }
  78. int OpenRaider::loadConfig(const char *config) {
  79. assert(config != NULL);
  80. assert(config[0] != '\0');
  81. char *configFile = fullPath(config, 0);
  82. getConsole().print("Loading config from \"%s\"...", configFile);
  83. FILE *f = fopen(configFile, "r");
  84. if (f == NULL) {
  85. getConsole().print("Could not open file!");
  86. return -1;
  87. }
  88. char buffer[256];
  89. while (fgets(buffer, 256, f) != NULL) {
  90. int error = command(buffer);
  91. if (error != 0) {
  92. getConsole().print("Error Code: %d", error);
  93. }
  94. }
  95. fclose(f);
  96. return 0;
  97. }
  98. int OpenRaider::command(const char *command) {
  99. assert(command != NULL);
  100. assert(command[0] != '\0');
  101. int returnValue = 0;
  102. char *cmd = bufferString("%s", command);
  103. size_t length = strlen(cmd);
  104. // Command ends at '\n' or # when a comment begins
  105. for (size_t i = 0; i < length; i++) {
  106. if (cmd[i] == '\n' || cmd[i] == '#') {
  107. cmd[i] = '\0';
  108. break;
  109. }
  110. }
  111. char *strtokState;
  112. char *token = strtok_r(cmd, " \t", &strtokState);
  113. if (token != NULL) {
  114. // token is the command to execute
  115. // get arguments
  116. std::vector<char *> args;
  117. char *next;
  118. while ((next = strtok_r(NULL, " \t", &strtokState)) != NULL) {
  119. args.push_back(next);
  120. }
  121. // Execute
  122. returnValue = this->command(token, &args);
  123. }
  124. free(cmd);
  125. return returnValue;
  126. }
  127. int OpenRaider::command(const char *command, std::vector<char *> *args) {
  128. assert(command != NULL);
  129. assert(command[0] != '\0');
  130. assert(args != NULL);
  131. if (strcmp(command, "set") == 0) {
  132. if (args->size() != 2) {
  133. getConsole().print("Invalid use of set-command");
  134. return -1;
  135. } else {
  136. return set(args->at(0), args->at(1));
  137. }
  138. } else if (strcmp(command, "bind") == 0) {
  139. if (args->size() != 2) {
  140. getConsole().print("Invalid use of bind-command");
  141. return -2;
  142. } else {
  143. return bind(args->at(0), args->at(1));
  144. }
  145. } else if (strcmp(command, "quit") == 0) {
  146. exit(0);
  147. } else if (strcmp(command, "load") == 0) {
  148. if (!mRunning) {
  149. getConsole().print("Use load command interactively!");
  150. return -999;
  151. }
  152. char *tmp = bufferString("%s/%s", mPakDir, args->at(0));
  153. int error = getGame().loadLevel(tmp);
  154. delete [] tmp;
  155. return error;
  156. } else if (strcmp(command, "sshot") == 0) {
  157. if (!mRunning) {
  158. getConsole().print("Use sshot command interactively!");
  159. return -999;
  160. }
  161. char *filename = bufferString("%s/sshots/%s", mBaseDir, VERSION);
  162. bool console = (args->size() > 0) && (strcmp(args->at(0), "console") == 0);
  163. bool menu = (args->size() > 0) && (strcmp(args->at(0), "menu") == 0);
  164. if (!console) {
  165. getConsole().setVisible(false);
  166. if (menu)
  167. getMenu().setVisible(true);
  168. frame();
  169. frame(); // Double buffered
  170. }
  171. getRender().screenShot(filename);
  172. if (!console) {
  173. getConsole().setVisible(true);
  174. if (menu)
  175. getMenu().setVisible(false);
  176. }
  177. getConsole().print("Screenshot stored...");
  178. delete filename;
  179. } else if (strcmp(command, "mode") == 0) {
  180. if (args->size() > 0) {
  181. char *mode = args->at(0);
  182. if (strcmp(mode, "wireframe") == 0) {
  183. if (getGame().isLoaded()) {
  184. getRender().setMode(Render::modeWireframe);
  185. getConsole().print("Wireframe mode");
  186. } else {
  187. getConsole().print("Load a level to set this mode!");
  188. return -3;
  189. }
  190. } else if (strcmp(mode, "solid") == 0) {
  191. if (getGame().isLoaded()) {
  192. getRender().setMode(Render::modeSolid);
  193. getConsole().print("Solid mode");
  194. } else {
  195. getConsole().print("Load a level to set this mode!");
  196. return -4;
  197. }
  198. } else if (strcmp(mode, "texture") == 0) {
  199. if (getGame().isLoaded()) {
  200. getRender().setMode(Render::modeTexture);
  201. getConsole().print("Texture mode");
  202. } else {
  203. getConsole().print("Load a level to set this mode!");
  204. return -5;
  205. }
  206. } else if (strcmp(mode, "vertexlight") == 0) {
  207. if (getGame().isLoaded()) {
  208. getRender().setMode(Render::modeVertexLight);
  209. getConsole().print("Vertexlight mode");
  210. } else {
  211. getConsole().print("Load a level to set this mode!");
  212. return -6;
  213. }
  214. } else if (strcmp(mode, "titlescreen") == 0) {
  215. getRender().setMode(Render::modeLoadScreen);
  216. getConsole().print("Titlescreen mode");
  217. } else {
  218. getConsole().print("Invalid use of mode command (%s)!", mode);
  219. return -7;
  220. }
  221. } else {
  222. getConsole().print("Invalid use of mode command!");
  223. return -8;
  224. }
  225. } else if (strcmp(command, "move") == 0) {
  226. if (!mRunning) {
  227. getConsole().print("Use move command interactively!");
  228. return -999;
  229. }
  230. if (args->size() > 0) {
  231. if (getGame().isLoaded()) {
  232. char *move = args->at(0);
  233. if (strcmp(move, "walk") == 0) {
  234. getGame().mLara->moveType = worldMoveType_walk;
  235. getConsole().print("Lara is walking...");
  236. } else if (strcmp(move, "fly") == 0) {
  237. getGame().mLara->moveType = worldMoveType_fly;
  238. getConsole().print("Lara is flying...");
  239. } else if (strcmp(move, "noclip") == 0) {
  240. getGame().mLara->moveType = worldMoveType_noClipping;
  241. getConsole().print("Lara is noclipping...");
  242. } else {
  243. getConsole().print("Invalid use of move command (%s)!", move);
  244. return -9;
  245. }
  246. } else {
  247. getConsole().print("Load a level to change the movement type!");
  248. return -10;
  249. }
  250. } else {
  251. getConsole().print("Invalid use of move command!");
  252. return -11;
  253. }
  254. } else if (strcmp(command, "sound") == 0) {
  255. if ((!mRunning) || (!getGame().isLoaded())) {
  256. getConsole().print("Use sound command interactively!");
  257. return -999;
  258. }
  259. if (args->size() > 0) {
  260. getSound().play(atoi(args->at(0)));
  261. } else {
  262. getConsole().print("Invalid use of sound command!");
  263. return -12;
  264. }
  265. } else if (strcmp(command, "animate") == 0) {
  266. if ((!mRunning) || (!getGame().isLoaded())) {
  267. getConsole().print("Use animate command interactively!");
  268. return -999;
  269. }
  270. if (args->size() > 0) {
  271. char c = args->at(0)[0];
  272. if (c == 'n') {
  273. // Step all skeletal models to their next animation
  274. if (getRender().getFlags() & Render::fAnimateAllModels) {
  275. for (unsigned int i = 0; i < getRender().mModels.size(); i++) {
  276. SkeletalModel *m = getRender().mModels[i];
  277. if (m->getAnimation() < ((int)m->model->animation.size() - 1))
  278. m->setAnimation(m->getAnimation() + 1);
  279. else
  280. if (m->getAnimation() != 0)
  281. m->setAnimation(0);
  282. }
  283. } else {
  284. getConsole().print("Animations need to be enabled!");
  285. }
  286. } else if (c == 'p') {
  287. // Step all skeletal models to their previous animation
  288. if (getRender().getFlags() & Render::fAnimateAllModels) {
  289. for (unsigned int i = 0; i < getRender().mModels.size(); i++) {
  290. SkeletalModel *m = getRender().mModels[i];
  291. if (m->getAnimation() > 0)
  292. m->setAnimation(m->getAnimation() - 1);
  293. else
  294. if (m->model->animation.size() > 0)
  295. m->setAnimation(m->model->animation.size() - 1);
  296. }
  297. } else {
  298. getConsole().print("Animations need to be enabled!");
  299. }
  300. } else {
  301. // Enable or disable animating all skeletal models
  302. bool b;
  303. if (readBool(args->at(0), &b) < 0) {
  304. getConsole().print("Pass BOOL to animate command!");
  305. return -13;
  306. }
  307. if (b)
  308. getRender().setFlags(Render::fAnimateAllModels);
  309. else
  310. getRender().clearFlags(Render::fAnimateAllModels);
  311. getConsole().print(b ? "Animating all models" : "No longer animating all models");
  312. }
  313. } else {
  314. getConsole().print("Invalid use of animate command!");
  315. return -14;
  316. }
  317. } else if (strcmp(command, "light") == 0) {
  318. if (args->size() > 0) {
  319. bool b;
  320. if (readBool(args->at(0), &b) < 0) {
  321. getConsole().print("Pass BOOL to light command!");
  322. return -15;
  323. }
  324. if (b)
  325. getRender().setFlags(Render::fGL_Lights);
  326. else
  327. getRender().clearFlags(Render::fGL_Lights);
  328. getConsole().print("GL-Lights are now %s", b ? "on" : "off");
  329. } else {
  330. getConsole().print("Invalid use of light-command!");
  331. return -16;
  332. }
  333. } else if (strcmp(command, "fog") == 0) {
  334. if (args->size() > 0) {
  335. bool b;
  336. if (readBool(args->at(0), &b) < 0) {
  337. getConsole().print("Pass BOOL to fog command!");
  338. return -17;
  339. }
  340. if (b)
  341. getRender().setFlags(Render::fFog);
  342. else
  343. getRender().clearFlags(Render::fFog);
  344. getConsole().print("Fog is now %s", b ? "on" : "off");
  345. } else {
  346. getConsole().print("Invalid use of fog-command!");
  347. return -18;
  348. }
  349. } else if (strcmp(command, "hop") == 0) {
  350. if (args->size() > 0) {
  351. bool b;
  352. if (readBool(args->at(0), &b) < 0) {
  353. getConsole().print("Pass BOOL to hop command!");
  354. return -19;
  355. }
  356. if (b)
  357. getWorld().setFlag(World::fEnableHopping);
  358. else
  359. getWorld().clearFlag(World::fEnableHopping);
  360. getConsole().print("Room hopping is now %s", b ? "on" : "off");
  361. } else {
  362. getConsole().print("Invalid use of hop-command!");
  363. return -20;
  364. }
  365. } else if (strcmp(command, "viewmodel") == 0) {
  366. if ((!mRunning) || (!getGame().isLoaded())) {
  367. getConsole().print("Use viewmodel command interactively!");
  368. return -999;
  369. }
  370. if (getGame().mLara) {
  371. SkeletalModel *smdl = static_cast<SkeletalModel *>(getGame().mLara->tmpHook);
  372. skeletal_model_t *mdl = getWorld().getModel(atoi(args->at(0)));
  373. if (smdl)
  374. smdl->setModel(mdl);
  375. }
  376. //m_render.ViewModel(LARA, atoi(cmd));
  377. } else if (strcmp(command, "pos") == 0) {
  378. if (getGame().mLara) {
  379. getConsole().print("Position:");
  380. getConsole().print(" Room %i (0x%X)", getGame().mLara->room, getWorld().getRoomInfo(getGame().mLara->room));
  381. getConsole().print(" %.1fx %.1fy %.1fz", getGame().mLara->pos[0], getGame().mLara->pos[1], getGame().mLara->pos[2]);
  382. getConsole().print(" %.1f Yaw %.1f Pitch", OR_RAD_TO_DEG(getGame().mLara->angles[1]), OR_RAD_TO_DEG(getGame().mLara->angles[2]));
  383. } else {
  384. getConsole().print("Load a level to get Laras position!");
  385. return -21;
  386. }
  387. } else if (strcmp(command, "vmodel") == 0) {
  388. if (args->size() > 0) {
  389. bool b;
  390. if (readBool(args->at(0), &b) < 0) {
  391. getConsole().print("Pass BOOL to vmodel command!");
  392. return -22;
  393. }
  394. if (b)
  395. getRender().setFlags(Render::fViewModel);
  396. else
  397. getRender().clearFlags(Render::fViewModel);
  398. getConsole().print("Viewmodel is now %s", b ? "on" : "off");
  399. } else {
  400. getConsole().print("Invalid use of vmodel-command!");
  401. return -23;
  402. }
  403. } else if (strcmp(command, "ralpha") == 0) {
  404. if (args->size() > 0) {
  405. bool b;
  406. if (readBool(args->at(0), &b) < 0) {
  407. getConsole().print("Pass BOOL to ralpha command!");
  408. return -24;
  409. }
  410. if (b)
  411. getRender().setFlags(Render::fRoomAlpha);
  412. else
  413. getRender().clearFlags(Render::fRoomAlpha);
  414. getConsole().print("Room Alpha is now %s", b ? "on" : "off");
  415. } else {
  416. getConsole().print("Invalid use of ralpha-command!");
  417. return -25;
  418. }
  419. } else if (strcmp(command, "portal") == 0) {
  420. if (args->size() > 0) {
  421. bool b;
  422. if (readBool(args->at(0), &b) < 0) {
  423. getConsole().print("Pass BOOL to portal command!");
  424. return -26;
  425. }
  426. if (b)
  427. getRender().setFlags(Render::fPortals);
  428. else
  429. getRender().clearFlags(Render::fPortals);
  430. getConsole().print("Portals are now %s", b ? "on" : "off");
  431. } else {
  432. getConsole().print("Invalid use of portal-command!");
  433. return -27;
  434. }
  435. } else if (strcmp(command, "vis") == 0) {
  436. if (args->size() > 0) {
  437. bool b;
  438. if (readBool(args->at(0), &b) < 0) {
  439. getConsole().print("Pass BOOL to vis command!");
  440. return -28;
  441. }
  442. if (b)
  443. getRender().setFlags(Render::fUsePortals);
  444. else
  445. getRender().clearFlags(Render::fUsePortals);
  446. getConsole().print("Portals are now %s", b ? "on" : "off");
  447. } else {
  448. getConsole().print("Invalid use of vis-command!");
  449. return -29;
  450. }
  451. } else if (strcmp(command, "upf") == 0) {
  452. if (args->size() > 0) {
  453. bool b;
  454. if (readBool(args->at(0), &b) < 0) {
  455. getConsole().print("Pass BOOL to upf command!");
  456. return -30;
  457. }
  458. if (b)
  459. getRender().setFlags(Render::fUpdateRoomListPerFrame);
  460. else
  461. getRender().clearFlags(Render::fUpdateRoomListPerFrame);
  462. getConsole().print("URLPF is now %s", b ? "on" : "off");
  463. } else {
  464. getConsole().print("Invalid use of upf-command!");
  465. return -31;
  466. }
  467. } else if (strcmp(command, "sprite") == 0) {
  468. if (args->size() > 0) {
  469. bool b;
  470. if (readBool(args->at(0), &b) < 0) {
  471. getConsole().print("Pass BOOL to sprite command!");
  472. return -34;
  473. }
  474. if (b)
  475. getRender().setFlags(Render::fSprites);
  476. else
  477. getRender().clearFlags(Render::fSprites);
  478. getConsole().print("Sprites are now %s", b ? "on" : "off");
  479. } else {
  480. getConsole().print("Invalid use of sprite-command!");
  481. return -35;
  482. }
  483. } else if (strcmp(command, "roommodel") == 0) {
  484. if (args->size() > 0) {
  485. bool b;
  486. if (readBool(args->at(0), &b) < 0) {
  487. getConsole().print("Pass BOOL to roommodel command!");
  488. return -36;
  489. }
  490. if (b)
  491. getRender().setFlags(Render::fRoomModels);
  492. else
  493. getRender().clearFlags(Render::fRoomModels);
  494. getConsole().print("Roommodels are now %s", b ? "on" : "off");
  495. } else {
  496. getConsole().print("Invalid use of roommodel-command!");
  497. return -37;
  498. }
  499. } else if (strcmp(command, "entmodel") == 0) {
  500. if (args->size() > 0) {
  501. bool b;
  502. if (readBool(args->at(0), &b) < 0) {
  503. getConsole().print("Pass BOOL to entmodel command!");
  504. return -38;
  505. }
  506. if (b)
  507. getRender().setFlags(Render::fEntityModels);
  508. else
  509. getRender().clearFlags(Render::fEntityModels);
  510. getConsole().print("Entmodels are now %s", b ? "on" : "off");
  511. } else {
  512. getConsole().print("Invalid use of entmodel-command!");
  513. return -39;
  514. }
  515. } else if (strcmp(command, "oneroom") == 0) {
  516. if (args->size() > 0) {
  517. bool b;
  518. if (readBool(args->at(0), &b) < 0) {
  519. getConsole().print("Pass BOOL to oneroom command!");
  520. return -40;
  521. }
  522. if (b)
  523. getRender().setFlags(Render::fOneRoom);
  524. else
  525. getRender().clearFlags(Render::fOneRoom);
  526. getConsole().print("Rendering one room is now %s", b ? "on" : "off");
  527. } else {
  528. getConsole().print("Invalid use of oneroom-command!");
  529. return -41;
  530. }
  531. } else if (strcmp(command, "allrooms") == 0) {
  532. if (args->size() > 0) {
  533. bool b;
  534. if (readBool(args->at(0), &b) < 0) {
  535. getConsole().print("Pass BOOL to allrooms command!");
  536. return -42;
  537. }
  538. if (b)
  539. getRender().setFlags(Render::fAllRooms);
  540. else
  541. getRender().clearFlags(Render::fAllRooms);
  542. getConsole().print("Rendering all rooms is now %s", b ? "on" : "off");
  543. } else {
  544. getConsole().print("Invalid use of allrooms-command!");
  545. return -43;
  546. }
  547. } else if (strcmp(command, "ponytail") == 0) {
  548. if (args->size() > 0) {
  549. bool b;
  550. if (readBool(args->at(0), &b) < 0) {
  551. getConsole().print("Pass BOOL to ponytail command!");
  552. return -44;
  553. }
  554. if (b)
  555. getRender().setFlags(Render::fRenderPonytail);
  556. else
  557. getRender().clearFlags(Render::fRenderPonytail);
  558. getConsole().print("Ponytail is now %s", b ? "on" : "off");
  559. } else {
  560. getConsole().print("Invalid use of ponytail-command!");
  561. return -45;
  562. }
  563. } else if (strcmp(command, "pigtail") == 0) {
  564. if ((!mRunning) || (!getGame().isLoaded())) {
  565. getConsole().print("Use pigtail command interactively!");
  566. return -999;
  567. }
  568. if (args->size() > 0) {
  569. bool b;
  570. if (readBool(args->at(0), &b) < 0) {
  571. getConsole().print("Pass BOOL to pigtail command!");
  572. return -46;
  573. }
  574. SkeletalModel *tmp = static_cast<SkeletalModel *>(getGame().mLara->tmpHook);
  575. tmp->model->pigtails = b;
  576. if (b) {
  577. tmp->model->ponyOff -= 20;
  578. tmp->model->ponytail[1] -= 32;
  579. } else {
  580. tmp->model->ponyOff += 20;
  581. tmp->model->ponytail[1] += 32;
  582. }
  583. getConsole().print("Pigtail is now %s", b ? "on" : "off");
  584. } else {
  585. getConsole().print("Invalid use of pigtail-command!");
  586. return -47;
  587. }
  588. } else if (strcmp(command, "ponypos") == 0) {
  589. if ((!mRunning) || (!getGame().isLoaded())) {
  590. getConsole().print("Use ponypos command interactively!");
  591. return -999;
  592. }
  593. if (args->size() > 3) {
  594. SkeletalModel *tmp = static_cast<SkeletalModel *>(getGame().mLara->tmpHook);
  595. tmp->model->ponytail[0] = (float)atof(args->at(0));
  596. tmp->model->ponytail[1] = (float)atof(args->at(1));
  597. tmp->model->ponytail[2] = (float)atof(args->at(2));
  598. tmp->model->ponytailAngle = (float)atof(args->at(3));
  599. } else {
  600. getConsole().print("Invalid use of ponypos-command!");
  601. return -48;
  602. }
  603. } else if (strcmp(command, "help") == 0) {
  604. if (args->size() == 0) {
  605. getConsole().print("Available commands:");
  606. getConsole().print(" load - load a level");
  607. getConsole().print(" set - set a parameter");
  608. getConsole().print(" bind - bind a keyboard/mouse action");
  609. getConsole().print(" sshot - make a screenshot");
  610. getConsole().print(" move - [walk|fly|noclip]");
  611. getConsole().print(" sound - INT - Test play sound");
  612. getConsole().print(" mode - MODE - Render mode");
  613. getConsole().print(" animate - [BOOL|n|p] - Animate models");
  614. getConsole().print(" light - BOOL - GL Lights");
  615. getConsole().print(" fog - BOOL - GL Fog");
  616. getConsole().print(" hop - BOOL - Room hop");
  617. getConsole().print(" viewmodel - INT - Change Laras model");
  618. getConsole().print(" pos - Print position info");
  619. getConsole().print(" vmodel - BOOL - View Model");
  620. getConsole().print(" ralpha - BOOL - Room Alpha");
  621. getConsole().print(" portal - BOOL");
  622. getConsole().print(" vis - BOOL - Use Portals");
  623. getConsole().print(" upf - BOOL - Update Room List Per Frame");
  624. getConsole().print(" sprite - BOOL");
  625. getConsole().print(" roommodel - BOOL");
  626. getConsole().print(" entmodel - BOOL");
  627. getConsole().print(" oneroom - BOOL");
  628. getConsole().print(" allrooms - BOOL");
  629. getConsole().print(" ponytail - BOOL");
  630. getConsole().print(" pigtail - BOOL");
  631. getConsole().print(" ponypos - FLOAT FLOAT FLOAT FLOAT - x y z angle");
  632. getConsole().print(" help - print command help");
  633. getConsole().print(" quit - exit OpenRaider");
  634. getConsole().print("Use help COMMAND to get additional info");
  635. } else if (args->size() == 1) {
  636. return help(args->at(0));
  637. } else {
  638. getConsole().print("Invalid use of help-command");
  639. return -49;
  640. }
  641. } else {
  642. getConsole().print("Unknown command: %s ", command);
  643. return -50;
  644. }
  645. return 0;
  646. }
  647. int OpenRaider::help(const char *cmd) {
  648. assert(cmd != NULL);
  649. assert(cmd[0] != '\0');
  650. if (strcmp(cmd, "set") == 0) {
  651. getConsole().print("set-Command Usage:");
  652. getConsole().print(" set VAR VAL");
  653. getConsole().print("Available Variables:");
  654. getConsole().print(" basedir STRING");
  655. getConsole().print(" pakdir STRING");
  656. getConsole().print(" audiodir STRING");
  657. getConsole().print(" datadir STRING");
  658. getConsole().print(" font STRING");
  659. getConsole().print(" gldriver STRING");
  660. getConsole().print(" size \"INTxINT\"");
  661. getConsole().print(" fullscreen BOOL");
  662. getConsole().print(" audio BOOL");
  663. getConsole().print(" volume BOOL");
  664. getConsole().print(" mouse_x FLOAT");
  665. getConsole().print(" mouse_y FLOAT");
  666. getConsole().print(" fps BOOL");
  667. getConsole().print("Enclose STRINGs with \"\"!");
  668. getConsole().print("size expects a STRING in the specified format");
  669. } else if (strcmp(cmd, "bind") == 0) {
  670. getConsole().print("bind-Command Usage:");
  671. getConsole().print(" bind ACTION KEY");
  672. getConsole().print("Available Actions:");
  673. getConsole().print(" menu");
  674. getConsole().print(" console");
  675. getConsole().print(" forward");
  676. getConsole().print(" backward");
  677. getConsole().print(" left");
  678. getConsole().print(" right");
  679. getConsole().print(" jump");
  680. getConsole().print(" crouch");
  681. getConsole().print(" use");
  682. getConsole().print(" holster");
  683. getConsole().print("Key-Format:");
  684. getConsole().print(" 'a' or '1' for character/number keys");
  685. getConsole().print(" \"leftctrl\" for symbols and special keys");
  686. } else if (strcmp(cmd, "load") == 0) {
  687. getConsole().print("load-Command Usage:");
  688. getConsole().print(" load levelfile.name");
  689. } else if (strcmp(cmd, "game") == 0) {
  690. getConsole().print("Use \"game help\" for more info");
  691. } else if (strcmp(cmd, "sshot") == 0) {
  692. getConsole().print("sshot-Command Usage:");
  693. getConsole().print(" sshot [console|menu]");
  694. getConsole().print("Add console/menu to capture them too");
  695. } else if (strcmp(cmd, "sound") == 0) {
  696. getConsole().print("sound-Command Usage:");
  697. getConsole().print(" sound INT");
  698. getConsole().print("Where INT is a valid sound ID integer");
  699. } else if (strcmp(cmd, "move") == 0) {
  700. getConsole().print("move-Command Usage:");
  701. getConsole().print(" move COMMAND");
  702. getConsole().print("Where COMMAND is one of the following:");
  703. getConsole().print(" walk");
  704. getConsole().print(" fly");
  705. getConsole().print(" noclip");
  706. } else if (strcmp(cmd, "mode") == 0) {
  707. getConsole().print("mode-Command Usage:");
  708. getConsole().print(" mode MODE");
  709. getConsole().print("Where MODE is one of the following:");
  710. getConsole().print(" wireframe");
  711. getConsole().print(" solid");
  712. getConsole().print(" texture");
  713. getConsole().print(" vertexlight");
  714. getConsole().print(" titlescreen");
  715. } else if (strcmp(cmd, "animate") == 0) {
  716. getConsole().print("animate-Command Usage:");
  717. getConsole().print(" animate [n|p|BOOL]");
  718. getConsole().print("Where the commands have the following meaning:");
  719. getConsole().print(" BOOL to (de)activate animating all models");
  720. getConsole().print(" n to step all models to their next animation");
  721. getConsole().print(" p to step all models to their previous animation");
  722. } else {
  723. getConsole().print("No help available for %s", cmd);
  724. return -1;
  725. }
  726. return 0;
  727. }
  728. char *OpenRaider::expandDirectoryNames(const char *s) {
  729. assert(s != NULL);
  730. assert(s[0] != '\0');
  731. if (mBaseDir != NULL) {
  732. const char *base = "$(basedir)";
  733. if (strstr(s, base) != NULL) {
  734. return stringReplace(s, base, mBaseDir);
  735. }
  736. }
  737. if (mPakDir != NULL) {
  738. const char *pak = "$(pakdir)";
  739. if (strstr(s, pak) != NULL) {
  740. return stringReplace(s, pak, mPakDir);
  741. }
  742. }
  743. if (mAudioDir != NULL) {
  744. const char *audio = "$(audiodir)";
  745. if (strstr(s, audio) != NULL) {
  746. return stringReplace(s, audio, mAudioDir);
  747. }
  748. }
  749. if (mDataDir != NULL) {
  750. const char *data = "$(datadir)";
  751. if (strstr(s, data) != NULL) {
  752. return stringReplace(s, data, mDataDir);
  753. }
  754. }
  755. return NULL;
  756. }
  757. #define CHANGE_DIR_WITH_EXPANSION(a) do { \
  758. char *quotes = stringRemoveQuotes(value); \
  759. char *tmp = expandDirectoryNames(quotes); \
  760. if (tmp == NULL) { \
  761. a = fullPath(quotes, 0); \
  762. } else { \
  763. a = fullPath(tmp, 0); \
  764. delete [] tmp; \
  765. } \
  766. delete [] quotes; \
  767. } while(false)
  768. int OpenRaider::set(const char *var, const char *value) {
  769. assert(var != NULL);
  770. assert(var[0] != '\0');
  771. assert(value != NULL);
  772. assert(value[0] != '\0');
  773. if (strcmp(var, "size") == 0) {
  774. // value has format like "\"1024x768\""
  775. unsigned int w = DEFAULT_WIDTH, h = DEFAULT_HEIGHT;
  776. if (sscanf(value, "\"%5dx%5d\"", &w, &h) != 2) {
  777. getConsole().print("set-size-Error: Invalid value (%s)", value);
  778. return -2;
  779. }
  780. getWindow().setSize(w, h);
  781. } else if (strcmp(var, "fullscreen") == 0) {
  782. bool fullscreen = false;
  783. if (readBool(value, &fullscreen) != 0) {
  784. getConsole().print("set-fullscreen-Error: Invalid value (%s)", value);
  785. return -3;
  786. }
  787. getWindow().setFullscreen(fullscreen);
  788. } else if (strcmp(var, "gldriver") == 0) {
  789. getWindow().setDriver(value);
  790. } else if (strcmp(var, "audio") == 0) {
  791. bool audio = false;
  792. if (readBool(value, &audio) != 0) {
  793. getConsole().print("set-audio-Error: Invalid value (%s)", value);
  794. return -4;
  795. }
  796. getSound().setEnabled(audio);
  797. } else if (strcmp(var, "volume") == 0) {
  798. float vol = 1.0f;
  799. if (sscanf(value, "%5f", &vol) != 1) {
  800. getConsole().print("set-volume-Error: Invalid value (%s)", value);
  801. return -5;
  802. }
  803. getSound().setVolume(vol);
  804. } else if (strcmp(var, "mouse_x") == 0) {
  805. float sense = 1.0f;
  806. if (sscanf(value, "%5f", &sense) != 1) {
  807. getConsole().print("set-mouse_x-Error: Invalid value (%s)", value);
  808. return -6;
  809. }
  810. getCamera().setSensitivityX(OR_DEG_TO_RAD(sense));
  811. } else if (strcmp(var, "mouse_y") == 0) {
  812. float sense = 1.0f;
  813. if (sscanf(value, "%5f", &sense) != 1) {
  814. getConsole().print("set-mouse_y-Error: Invalid value (%s)", value);
  815. return -7;
  816. }
  817. getCamera().setSensitivityY(OR_DEG_TO_RAD(sense));
  818. } else if (strcmp(var, "fps") == 0) {
  819. bool fps = false;
  820. if (readBool(value, &fps) != 0) {
  821. getConsole().print("set-fps-Error: Invalid value (%s)", value);
  822. return -8;
  823. }
  824. mFPS = fps;
  825. } else if (strcmp(var, "basedir") == 0) {
  826. CHANGE_DIR_WITH_EXPANSION(mBaseDir);
  827. } else if (strcmp(var, "pakdir") == 0) {
  828. CHANGE_DIR_WITH_EXPANSION(mPakDir);
  829. } else if (strcmp(var, "audiodir") == 0) {
  830. CHANGE_DIR_WITH_EXPANSION(mAudioDir);
  831. } else if (strcmp(var, "datadir") == 0) {
  832. CHANGE_DIR_WITH_EXPANSION(mDataDir);
  833. } else if (strcmp(var, "font") == 0) {
  834. char *quotes = stringReplace(value, "\"", "");
  835. char *tmp = expandDirectoryNames(quotes);
  836. if (tmp == NULL) {
  837. getWindow().setFont(quotes);
  838. } else {
  839. getWindow().setFont(tmp);
  840. delete [] tmp;
  841. }
  842. delete [] quotes;
  843. } else {
  844. getConsole().print("set-Error: Unknown variable (%s = %s)", var, value);
  845. return -1;
  846. }
  847. return 0;
  848. }
  849. int OpenRaider::bind(const char *action, const char *key) {
  850. assert(action != NULL);
  851. assert(action[0] != '\0');
  852. assert(key != NULL);
  853. assert(key[0] != '\0');
  854. const char *tmp = action;
  855. if (action[0] == '+')
  856. tmp++;
  857. if (strcmp(tmp, "menu") == 0) {
  858. return bind(menuAction, key);
  859. } else if (strcmp(tmp, "console") == 0) {
  860. return bind(consoleAction, key);
  861. } else if (strcmp(tmp, "forward") == 0) {
  862. return bind(forwardAction, key);
  863. } else if (strcmp(tmp, "backward") == 0) {
  864. return bind(backwardAction, key);
  865. } else if (strcmp(tmp, "left") == 0) {
  866. return bind(leftAction, key);
  867. } else if (strcmp(tmp, "right") == 0) {
  868. return bind(rightAction, key);
  869. } else if (strcmp(tmp, "jump") == 0) {
  870. return bind(jumpAction, key);
  871. } else if (strcmp(tmp, "crouch") == 0) {
  872. return bind(crouchAction, key);
  873. } else if (strcmp(tmp, "use") == 0) {
  874. return bind(useAction, key);
  875. } else if (strcmp(tmp, "holster") == 0) {
  876. return bind(holsterAction, key);
  877. } else {
  878. getConsole().print("bind-Error: Unknown action (%s --> %s)", key, action);
  879. return -1;
  880. }
  881. }
  882. int OpenRaider::bind(ActionEvents action, const char *key) {
  883. assert(action < ActionEventCount);
  884. assert(key != NULL);
  885. assert(key[0] != '\0');
  886. size_t length = strlen(key);
  887. if ((key[0] == '\'') && (key[length - 1] == '\'') && (length == 3)) {
  888. // Literal character like w, a, s, d, 0, 1...
  889. char c = key[1];
  890. if (((c >= '0') && (c <= '9'))
  891. || ((c >= 'a') && (c <= 'z'))) {
  892. keyBindings[action] = (KeyboardButton)c;
  893. } else {
  894. getConsole().print("bind-\'\'-Error: Unknown key (%s)", key);
  895. return -1;
  896. }
  897. } else if ((key[0] == '\"') && (key[length - 1] == '\"')) {
  898. // Special characters like tilde, esc, quote...
  899. char *tmp = stringRemoveQuotes(key);
  900. if (strcmp(tmp, "quote") == 0) {
  901. keyBindings[action] = quoteKey;
  902. } else if (strcmp(tmp, "backslash") == 0) {
  903. keyBindings[action] = backslashKey;
  904. } else if (strcmp(tmp, "backspace") == 0) {
  905. keyBindings[action] = backspaceKey;
  906. } else if (strcmp(tmp, "capslock") == 0) {
  907. keyBindings[action] = capslockKey;
  908. } else if (strcmp(tmp, "comma") == 0) {
  909. keyBindings[action] = commaKey;
  910. } else if (strcmp(tmp, "del") == 0) {
  911. keyBindings[action] = delKey;
  912. } else if (strcmp(tmp, "up") == 0) {
  913. keyBindings[action] = upKey;
  914. } else if (strcmp(tmp, "down") == 0) {
  915. keyBindings[action] = downKey;
  916. } else if (strcmp(tmp, "left") == 0) {
  917. keyBindings[action] = leftKey;
  918. } else if (strcmp(tmp, "right") == 0) {
  919. keyBindings[action] = rightKey;
  920. } else if (strcmp(tmp, "end") == 0) {
  921. keyBindings[action] = endKey;
  922. } else if (strcmp(tmp, "equals") == 0) {
  923. keyBindings[action] = equalsKey;
  924. } else if (strcmp(tmp, "escape") == 0) {
  925. keyBindings[action] = escapeKey;
  926. } else if (strcmp(tmp, "f1") == 0) {
  927. keyBindings[action] = f1Key;
  928. } else if (strcmp(tmp, "f2") == 0) {
  929. keyBindings[action] = f2Key;
  930. } else if (strcmp(tmp, "f3") == 0) {
  931. keyBindings[action] = f3Key;
  932. } else if (strcmp(tmp, "f4") == 0) {
  933. keyBindings[action] = f4Key;
  934. } else if (strcmp(tmp, "f5") == 0) {
  935. keyBindings[action] = f5Key;
  936. } else if (strcmp(tmp, "f6") == 0) {
  937. keyBindings[action] = f6Key;
  938. } else if (strcmp(tmp, "f7") == 0) {
  939. keyBindings[action] = f7Key;
  940. } else if (strcmp(tmp, "f8") == 0) {
  941. keyBindings[action] = f8Key;
  942. } else if (strcmp(tmp, "f9") == 0) {
  943. keyBindings[action] = f9Key;
  944. } else if (strcmp(tmp, "f10") == 0) {
  945. keyBindings[action] = f10Key;
  946. } else if (strcmp(tmp, "f11") == 0) {
  947. keyBindings[action] = f11Key;
  948. } else if (strcmp(tmp, "f12") == 0) {
  949. keyBindings[action] = f12Key;
  950. } else if (strcmp(tmp, "backquote") == 0) {
  951. keyBindings[action] = backquoteKey;
  952. } else if (strcmp(tmp, "home") == 0) {
  953. keyBindings[action] = homeKey;
  954. } else if (strcmp(tmp, "insert") == 0) {
  955. keyBindings[action] = insertKey;
  956. } else if (strcmp(tmp, "leftalt") == 0) {
  957. keyBindings[action] = leftaltKey;
  958. } else if (strcmp(tmp, "leftctrl") == 0) {
  959. keyBindings[action] = leftctrlKey;
  960. } else if (strcmp(tmp, "leftbracket") == 0) {
  961. keyBindings[action] = leftbracketKey;
  962. } else if (strcmp(tmp, "leftgui") == 0) {
  963. keyBindings[action] = leftguiKey;
  964. } else if (strcmp(tmp, "leftshift") == 0) {
  965. keyBindings[action] = leftshiftKey;
  966. } else if (strcmp(tmp, "minus") == 0) {
  967. keyBindings[action] = minusKey;
  968. } else if (strcmp(tmp, "numlock") == 0) {
  969. keyBindings[action] = numlockKey;
  970. } else if (strcmp(tmp, "pagedown") == 0) {
  971. keyBindings[action] = pagedownKey;
  972. } else if (strcmp(tmp, "pageup") == 0) {
  973. keyBindings[action] = pageupKey;
  974. } else if (strcmp(tmp, "pause") == 0) {
  975. keyBindings[action] = pauseKey;
  976. } else if (strcmp(tmp, "dot") == 0) {
  977. keyBindings[action] = dotKey;
  978. } else if (strcmp(tmp, "rightalt") == 0) {
  979. keyBindings[action] = rightaltKey;
  980. } else if (strcmp(tmp, "rightctrl") == 0) {
  981. keyBindings[action] = rightctrlKey;
  982. } else if (strcmp(tmp, "enter") == 0) {
  983. keyBindings[action] = enterKey;
  984. } else if (strcmp(tmp, "rightgui") == 0) {
  985. keyBindings[action] = rightguiKey;
  986. } else if (strcmp(tmp, "rightbracket") == 0) {
  987. keyBindings[action] = rightbracketKey;
  988. } else if (strcmp(tmp, "rightshift") == 0) {
  989. keyBindings[action] = rightshiftKey;
  990. } else if (strcmp(tmp, "scrolllock") == 0) {
  991. keyBindings[action] = scrolllockKey;
  992. } else if (strcmp(tmp, "semicolon") == 0) {
  993. keyBindings[action] = semicolonKey;
  994. } else if (strcmp(tmp, "slash") == 0) {
  995. keyBindings[action] = slashKey;
  996. } else if (strcmp(tmp, "space") == 0) {
  997. keyBindings[action] = spaceKey;
  998. } else if (strcmp(tmp, "tab") == 0) {
  999. keyBindings[action] = tabKey;
  1000. } else if (strcmp(tmp, "leftmouse") == 0) {
  1001. keyBindings[action] = leftmouseKey;
  1002. } else if (strcmp(tmp, "middlemouse") == 0) {
  1003. keyBindings[action] = middlemouseKey;
  1004. } else if (strcmp(tmp, "rightmouse") == 0) {
  1005. keyBindings[action] = rightmouseKey;
  1006. } else {
  1007. getConsole().print("bind-\"\"-Error: Unknown key (%s)", key);
  1008. delete [] tmp;
  1009. return -2;
  1010. }
  1011. delete [] tmp;
  1012. } else {
  1013. getConsole().print("bind-Error: Unknown key (%s)", key);
  1014. return -3;
  1015. }
  1016. return 0;
  1017. }
  1018. void OpenRaider::run() {
  1019. assert(mRunning == false);
  1020. mRunning = true;
  1021. while (mRunning) {
  1022. frame();
  1023. }
  1024. }
  1025. void OpenRaider::frame() {
  1026. assert(mRunning == true);
  1027. static clock_t fpsSum = 0, fpsCount = 0;
  1028. static int fps = 0;
  1029. clock_t startTime = systemTimerGet();
  1030. // Get keyboard and mouse input
  1031. getWindow().eventHandling();
  1032. // Clear screen
  1033. glClearColor(0.00f, 0.00f, 0.00f, 1.0f);
  1034. glClear(GL_COLOR_BUFFER_BIT);
  1035. // Draw game scene
  1036. getRender().display();
  1037. // Draw 2D overlays (console and menu)
  1038. getWindow().glEnter2D();
  1039. getConsole().display();
  1040. getMenu().display();
  1041. // Draw FPS counter
  1042. if (mFPS)
  1043. getWindow().drawText(10, getWindow().mHeight - 20, 0.5f, OR_BLUE, "%dFPS", fps);
  1044. #ifdef DEBUG
  1045. // Draw debug infos
  1046. if (getGame().isLoaded()) {
  1047. for (int i = 0; i < 3; i++) {
  1048. getWindow().drawText(10, getWindow().mHeight - ((4 - i) * 20), 0.5f, OR_BLUE, "%.2f (%.2f)",
  1049. getGame().mLara->pos[i] / 256.0f, getGame().mLara->angles[i]);
  1050. }
  1051. }
  1052. #endif
  1053. getWindow().glExit2D();
  1054. // Put new frame on screen
  1055. getWindow().swapBuffersGL();
  1056. // Calculate FPS display value
  1057. fpsCount++;
  1058. fpsSum += (systemTimerGet() - startTime);
  1059. if (fpsSum >= 500) {
  1060. // Update every 500ms
  1061. fps = (int)((float)fpsCount * (1000.0f / (float)fpsSum));
  1062. fpsCount = fpsSum = 0;
  1063. }
  1064. }
  1065. void OpenRaider::handleKeyboard(KeyboardButton key, bool pressed) {
  1066. assert(key < unknownKey);
  1067. assert(mRunning == true);
  1068. if ((keyBindings[menuAction] == key) && pressed) {
  1069. getMenu().setVisible(!getMenu().isVisible());
  1070. } else if (!getMenu().isVisible()) {
  1071. if ((keyBindings[consoleAction] == key) && pressed) {
  1072. getConsole().setVisible(!getConsole().isVisible());
  1073. } else if (!getConsole().isVisible()) {
  1074. for (int i = forwardAction; i < ActionEventCount; i++) {
  1075. if (keyBindings[i] == key) {
  1076. getGame().handleAction((ActionEvents)i, pressed);
  1077. }
  1078. }
  1079. } else {
  1080. getConsole().handleKeyboard(key, pressed);
  1081. }
  1082. } else {
  1083. getMenu().handleKeyboard(key, pressed);
  1084. }
  1085. getWindow().setMousegrab(!(getMenu().isVisible() || getConsole().isVisible()));
  1086. }
  1087. void OpenRaider::handleText(char *text, bool notFinished) {
  1088. assert(text != NULL);
  1089. assert(text[0] != '\0');
  1090. assert(mRunning == true);
  1091. if ((getConsole().isVisible()) && (!getMenu().isVisible())) {
  1092. getConsole().handleText(text, notFinished);
  1093. }
  1094. }
  1095. void OpenRaider::handleMouseClick(unsigned int x, unsigned int y, KeyboardButton button, bool released) {
  1096. assert(button < unknownKey);
  1097. assert(mRunning == true);
  1098. if (getMenu().isVisible()) {
  1099. getMenu().handleMouseClick(x, y, button, released);
  1100. } else if (!getConsole().isVisible()) {
  1101. for (int i = forwardAction; i < ActionEventCount; i++) {
  1102. if (keyBindings[i] == button) {
  1103. getGame().handleAction((ActionEvents)i, !released);
  1104. }
  1105. }
  1106. }
  1107. }
  1108. void OpenRaider::handleMouseMotion(int xrel, int yrel) {
  1109. assert((xrel != 0) || (yrel != 0));
  1110. assert(mRunning == true);
  1111. if ((!getConsole().isVisible()) && (!getMenu().isVisible())) {
  1112. getGame().handleMouseMotion(xrel, yrel);
  1113. }
  1114. }
  1115. void OpenRaider::handleMouseScroll(int xrel, int yrel) {
  1116. assert((xrel != 0) || (yrel != 0));
  1117. assert(mRunning == true);
  1118. if ((getConsole().isVisible()) && (!getMenu().isVisible())) {
  1119. getConsole().handleMouseScroll(xrel, yrel);
  1120. }
  1121. }