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.

Command.cpp 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. /*!
  2. * \file src/Command.cpp
  3. * \brief OpenRaider command implementation
  4. *
  5. * \author xythobuz
  6. */
  7. #include <fstream>
  8. #include "WindowSDL.h"
  9. #include "global.h"
  10. #include "Console.h"
  11. #include "Entity.h"
  12. #include "Game.h"
  13. #include "math/math.h"
  14. #include "Menu.h"
  15. #include "Sound.h"
  16. #include "TombRaider.h"
  17. #include "utils/strings.h"
  18. #include "utils/time.h"
  19. #include "OpenRaider.h"
  20. int OpenRaider::loadConfig(const char *config) {
  21. assert(config != NULL);
  22. assert(config[0] != '\0');
  23. char *configFile = fullPath(config, 0);
  24. getConsole().print("Loading config from \"%s\"...", configFile);
  25. std::ifstream file(configFile);
  26. if (!file) {
  27. getConsole().print("Could not open file!");
  28. return -1;
  29. }
  30. for (std::string line; std::getline(file, line);) {
  31. if (line.length() == 0)
  32. continue;
  33. int error = command(line);
  34. if (error != 0)
  35. getConsole().print("Error Code: %d", error);
  36. }
  37. file.close();
  38. return 0;
  39. }
  40. int OpenRaider::command(std::string &command) {
  41. // Remove comment, if any
  42. size_t comment = command.find_first_of('#');
  43. if (comment != std::string::npos)
  44. command.erase(comment);
  45. // Execute command
  46. std::stringstream stream(command);
  47. return this->command(stream);
  48. }
  49. int OpenRaider::command(const char *command) {
  50. std::string tmp(command);
  51. return this->command(tmp);
  52. }
  53. int OpenRaider::command(std::stringstream &command) {
  54. std::string cmd;
  55. command >> cmd;
  56. if (cmd.length() == 0)
  57. return 0;
  58. if (cmd.compare("set") == 0) {
  59. return set(command);
  60. } else if (cmd.compare("bind") == 0) {
  61. std::string a, b;
  62. if (!(command >> a >> b)) {
  63. getConsole().print("Invalid use of bind-command");
  64. return -1;
  65. } else {
  66. return bind(a.c_str(), b.c_str());
  67. }
  68. } else if (cmd.compare("quit") == 0) {
  69. exit(0);
  70. } else if (cmd.compare("load") == 0) {
  71. if (!mRunning) {
  72. getConsole().print("Use load command interactively!");
  73. return -999;
  74. }
  75. std::string temp;
  76. command >> temp;
  77. char *tmp = bufferString("%s/%s", mPakDir, temp.c_str());
  78. int error = getGame().loadLevel(tmp);
  79. delete [] tmp;
  80. return error;
  81. } else if (cmd.compare("help") == 0) {
  82. std::string tmp;
  83. if (!(command >> tmp)) {
  84. getConsole().print("Available commands:");
  85. getConsole().print(" load - load a level");
  86. getConsole().print(" set - set a parameter");
  87. getConsole().print(" bind - bind a keyboard/mouse action");
  88. /*
  89. getConsole().print(" sshot - make a screenshot");
  90. getConsole().print(" move - [walk|fly|noclip]");
  91. getConsole().print(" sound - INT - Test play sound");
  92. getConsole().print(" mode - MODE - Render mode");
  93. getConsole().print(" animate - [BOOL|n|p] - Animate models");
  94. getConsole().print(" light - BOOL - GL Lights");
  95. getConsole().print(" fog - BOOL - GL Fog");
  96. getConsole().print(" viewmodel - INT - Change Laras model");
  97. getConsole().print(" pos - Print position info");
  98. getConsole().print(" vmodel - BOOL - View Model");
  99. getConsole().print(" ralpha - BOOL - Room Alpha");
  100. getConsole().print(" vis - BOOL - Use Portals");
  101. getConsole().print(" upf - BOOL - Update Room List Per Frame");
  102. getConsole().print(" entmodel - BOOL");
  103. getConsole().print(" oneroom - BOOL");
  104. getConsole().print(" allrooms - BOOL");
  105. getConsole().print(" ponytail - BOOL");
  106. getConsole().print(" pigtail - BOOL");
  107. getConsole().print(" ponypos - FLOAT FLOAT FLOAT FLOAT - x y z angle");
  108. */
  109. getConsole().print(" help - print command help");
  110. getConsole().print(" quit - exit OpenRaider");
  111. getConsole().print("Use help COMMAND to get additional info");
  112. } else {
  113. return help(tmp);
  114. }
  115. /*
  116. } else if (cmd.compare("mode") == 0) {
  117. std::string mode;
  118. command >> mode;
  119. if (!getGame().isLoaded()) {
  120. getConsole().print("Load a level to set the mode!");
  121. return -1;
  122. }
  123. if (mode.compare("wireframe") == 0) {
  124. getRender().setMode(Render::modeWireframe);
  125. getConsole().print("Wireframe mode");
  126. } else if (mode.compare("solid") == 0) {
  127. getRender().setMode(Render::modeSolid);
  128. getConsole().print("Solid mode");
  129. } else if (mode.compare("texture") == 0) {
  130. getRender().setMode(Render::modeTexture);
  131. getConsole().print("Texture mode");
  132. } else if (mode.compare("vertexlight") == 0) {
  133. getRender().setMode(Render::modeVertexLight);
  134. getConsole().print("Vertexlight mode");
  135. } else if (mode.compare("titlescreen") == 0) {
  136. getRender().setMode(Render::modeLoadScreen);
  137. getConsole().print("Titlescreen mode");
  138. } else {
  139. getConsole().print("Invalid use of mode command (%s)!", mode.c_str());
  140. return -1;
  141. }
  142. } else if (cmd.compare("light") == 0) {
  143. if (args->size() > 0) {
  144. bool b;
  145. if (readBool(args->at(0), &b) < 0) {
  146. getConsole().print("Pass BOOL to light command!");
  147. return -15;
  148. }
  149. if (b)
  150. getRender().setFlags(Render::fGL_Lights);
  151. else
  152. getRender().clearFlags(Render::fGL_Lights);
  153. getConsole().print("GL-Lights are now %s", b ? "on" : "off");
  154. } else {
  155. getConsole().print("Invalid use of light-command!");
  156. return -16;
  157. }
  158. } else if (cmd.compare("fog") == 0) {
  159. if (args->size() > 0) {
  160. bool b;
  161. if (readBool(args->at(0), &b) < 0) {
  162. getConsole().print("Pass BOOL to fog command!");
  163. return -17;
  164. }
  165. if (b)
  166. getRender().setFlags(Render::fFog);
  167. else
  168. getRender().clearFlags(Render::fFog);
  169. getConsole().print("Fog is now %s", b ? "on" : "off");
  170. } else {
  171. getConsole().print("Invalid use of fog-command!");
  172. return -18;
  173. }
  174. } else if (cmd.compare("vmodel") == 0) {
  175. if (args->size() > 0) {
  176. bool b;
  177. if (readBool(args->at(0), &b) < 0) {
  178. getConsole().print("Pass BOOL to vmodel command!");
  179. return -22;
  180. }
  181. if (b)
  182. getRender().setFlags(Render::fViewModel);
  183. else
  184. getRender().clearFlags(Render::fViewModel);
  185. getConsole().print("Viewmodel is now %s", b ? "on" : "off");
  186. } else {
  187. getConsole().print("Invalid use of vmodel-command!");
  188. return -23;
  189. }
  190. } else if (cmd.compare("ralpha") == 0) {
  191. if (args->size() > 0) {
  192. bool b;
  193. if (readBool(args->at(0), &b) < 0) {
  194. getConsole().print("Pass BOOL to ralpha command!");
  195. return -24;
  196. }
  197. if (b)
  198. getRender().setFlags(Render::fRoomAlpha);
  199. else
  200. getRender().clearFlags(Render::fRoomAlpha);
  201. getConsole().print("Room Alpha is now %s", b ? "on" : "off");
  202. } else {
  203. getConsole().print("Invalid use of ralpha-command!");
  204. return -25;
  205. }
  206. } else if (cmd.compare("vis") == 0) {
  207. if (args->size() > 0) {
  208. bool b;
  209. if (readBool(args->at(0), &b) < 0) {
  210. getConsole().print("Pass BOOL to vis command!");
  211. return -28;
  212. }
  213. if (b)
  214. getRender().setFlags(Render::fUsePortals);
  215. else
  216. getRender().clearFlags(Render::fUsePortals);
  217. getConsole().print("Portals are now %s", b ? "on" : "off");
  218. } else {
  219. getConsole().print("Invalid use of vis-command!");
  220. return -29;
  221. }
  222. } else if (cmd.compare("upf") == 0) {
  223. if (args->size() > 0) {
  224. bool b;
  225. if (readBool(args->at(0), &b) < 0) {
  226. getConsole().print("Pass BOOL to upf command!");
  227. return -30;
  228. }
  229. if (b)
  230. getRender().setFlags(Render::fUpdateRoomListPerFrame);
  231. else
  232. getRender().clearFlags(Render::fUpdateRoomListPerFrame);
  233. getConsole().print("URLPF is now %s", b ? "on" : "off");
  234. } else {
  235. getConsole().print("Invalid use of upf-command!");
  236. return -31;
  237. }
  238. } else if (cmd.compare("entmodel") == 0) {
  239. if (args->size() > 0) {
  240. bool b;
  241. if (readBool(args->at(0), &b) < 0) {
  242. getConsole().print("Pass BOOL to entmodel command!");
  243. return -38;
  244. }
  245. if (b)
  246. getRender().setFlags(Render::fEntityModels);
  247. else
  248. getRender().clearFlags(Render::fEntityModels);
  249. getConsole().print("Entmodels are now %s", b ? "on" : "off");
  250. } else {
  251. getConsole().print("Invalid use of entmodel-command!");
  252. return -39;
  253. }
  254. } else if (cmd.compare("oneroom") == 0) {
  255. if (args->size() > 0) {
  256. bool b;
  257. if (readBool(args->at(0), &b) < 0) {
  258. getConsole().print("Pass BOOL to oneroom command!");
  259. return -40;
  260. }
  261. if (b)
  262. getRender().setFlags(Render::fOneRoom);
  263. else
  264. getRender().clearFlags(Render::fOneRoom);
  265. getConsole().print("Rendering one room is now %s", b ? "on" : "off");
  266. } else {
  267. getConsole().print("Invalid use of oneroom-command!");
  268. return -41;
  269. }
  270. } else if (cmd.compare("allrooms") == 0) {
  271. if (args->size() > 0) {
  272. bool b;
  273. if (readBool(args->at(0), &b) < 0) {
  274. getConsole().print("Pass BOOL to allrooms command!");
  275. return -42;
  276. }
  277. if (b)
  278. getRender().setFlags(Render::fAllRooms);
  279. else
  280. getRender().clearFlags(Render::fAllRooms);
  281. getConsole().print("Rendering all rooms is now %s", b ? "on" : "off");
  282. } else {
  283. getConsole().print("Invalid use of allrooms-command!");
  284. return -43;
  285. }
  286. } else if (cmd.compare("ponytail") == 0) {
  287. if (args->size() > 0) {
  288. bool b;
  289. if (readBool(args->at(0), &b) < 0) {
  290. getConsole().print("Pass BOOL to ponytail command!");
  291. return -44;
  292. }
  293. if (b)
  294. getRender().setFlags(Render::fRenderPonytail);
  295. else
  296. getRender().clearFlags(Render::fRenderPonytail);
  297. getConsole().print("Ponytail is now %s", b ? "on" : "off");
  298. } else {
  299. getConsole().print("Invalid use of ponytail-command!");
  300. return -45;
  301. }
  302. } else if (cmd.compare("sshot") == 0) {
  303. if (!mRunning) {
  304. getConsole().print("Use sshot command interactively!");
  305. return -999;
  306. }
  307. char *filename = bufferString("%s/sshots/%s", mBaseDir, VERSION);
  308. bool console = (args->size() > 0) && (strcmp(args->at(0), "console") == 0);
  309. bool menu = (args->size() > 0) && (strcmp(args->at(0), "menu") == 0);
  310. if (!console) {
  311. getConsole().setVisible(false);
  312. if (menu)
  313. getMenu().setVisible(true);
  314. frame();
  315. frame(); // Double buffered
  316. }
  317. getRender().screenShot(filename);
  318. if (!console) {
  319. getConsole().setVisible(true);
  320. if (menu)
  321. getMenu().setVisible(false);
  322. }
  323. getConsole().print("Screenshot stored...");
  324. delete filename;
  325. } else if (cmd.compare("move") == 0) {
  326. if (!mRunning) {
  327. getConsole().print("Use move command interactively!");
  328. return -999;
  329. }
  330. if (args->size() > 0) {
  331. if (getGame().isLoaded()) {
  332. char *move = args->at(0);
  333. if (strcmp(move, "walk") == 0) {
  334. getGame().getLara().setMoveType(Entity::MoveTypeWalk);
  335. getConsole().print("Lara is walking...");
  336. } else if (strcmp(move, "fly") == 0) {
  337. getGame().getLara().setMoveType(Entity::MoveTypeFly);
  338. getConsole().print("Lara is flying...");
  339. } else if (strcmp(move, "noclip") == 0) {
  340. getGame().getLara().setMoveType(Entity::MoveTypeNoClipping);
  341. getConsole().print("Lara is noclipping...");
  342. } else {
  343. getConsole().print("Invalid use of move command (%s)!", move);
  344. return -9;
  345. }
  346. } else {
  347. getConsole().print("Load a level to change the movement type!");
  348. return -10;
  349. }
  350. } else {
  351. getConsole().print("Invalid use of move command!");
  352. return -11;
  353. }
  354. } else if (cmd.compare("sound") == 0) {
  355. if ((!mRunning) || (!getGame().isLoaded())) {
  356. getConsole().print("Use sound command interactively!");
  357. return -999;
  358. }
  359. if (args->size() > 0) {
  360. getSound().play(atoi(args->at(0)));
  361. } else {
  362. getConsole().print("Invalid use of sound command!");
  363. return -12;
  364. }
  365. } else if (cmd.compare("animate") == 0) {
  366. if ((!mRunning) || (!getGame().isLoaded())) {
  367. getConsole().print("Use animate command interactively!");
  368. return -999;
  369. }
  370. if (args->size() > 0) {
  371. char c = args->at(0)[0];
  372. if (c == 'n') {
  373. // Step all skeletal models to their next animation
  374. if (getRender().getFlags() & Render::fAnimateAllModels) {
  375. for (unsigned int i = 0; i < getWorld().sizeEntity(); i++) {
  376. Entity &e = getWorld().getEntity(i);
  377. SkeletalModel &m = e.getModel();
  378. if (e.getAnimation() < (m.size() - 1))
  379. e.setAnimation(e.getAnimation() + 1);
  380. else
  381. e.setAnimation(0);
  382. }
  383. } else {
  384. getConsole().print("Animations need to be enabled!");
  385. }
  386. } else if (c == 'p') {
  387. // Step all skeletal models to their previous animation
  388. if (getRender().getFlags() & Render::fAnimateAllModels) {
  389. for (unsigned int i = 0; i < getWorld().sizeEntity(); i++) {
  390. Entity &e = getWorld().getEntity(i);
  391. SkeletalModel &m = e.getModel();
  392. if (e.getAnimation() > 0)
  393. e.setAnimation(e.getAnimation() - 1);
  394. else
  395. if (m.size() > 0)
  396. e.setAnimation(m.size() - 1);
  397. }
  398. } else {
  399. getConsole().print("Animations need to be enabled!");
  400. }
  401. } else {
  402. // Enable or disable animating all skeletal models
  403. bool b;
  404. if (readBool(args->at(0), &b) < 0) {
  405. getConsole().print("Pass BOOL to animate command!");
  406. return -13;
  407. }
  408. if (b)
  409. getRender().setFlags(Render::fAnimateAllModels);
  410. else
  411. getRender().clearFlags(Render::fAnimateAllModels);
  412. getConsole().print(b ? "Animating all models" : "No longer animating all models");
  413. }
  414. } else {
  415. getConsole().print("Invalid use of animate command!");
  416. return -14;
  417. }
  418. } else if (cmd.compare("viewmodel") == 0) {
  419. if ((!mRunning) || (!getGame().isLoaded())) {
  420. getConsole().print("Use viewmodel command interactively!");
  421. return -999;
  422. }
  423. unsigned int n = atoi(args->at(0));
  424. if (n < getWorld().sizeSkeletalModel())
  425. getGame().getLara().setSkeletalModel(n);
  426. else {
  427. getConsole().print("Invalid SkeletalModel index!");
  428. return -66;
  429. }
  430. } else if (cmd.compare("pos") == 0) {
  431. if ((!mRunning) || (!getGame().isLoaded())) {
  432. getConsole().print("Use pos command interactively!");
  433. return -21;
  434. }
  435. getGame().getLara().print();
  436. } else if (cmd.compare("pigtail") == 0) {
  437. if ((!mRunning) || (!getGame().isLoaded())) {
  438. getConsole().print("Use pigtail command interactively!");
  439. return -999;
  440. }
  441. if (args->size() > 0) {
  442. bool b;
  443. if (readBool(args->at(0), &b) < 0) {
  444. getConsole().print("Pass BOOL to pigtail command!");
  445. return -46;
  446. }
  447. SkeletalModel &tmp = getGame().getLara().getModel();
  448. tmp.setPigTail(b);
  449. getConsole().print("Pigtail is now %s", b ? "on" : "off");
  450. } else {
  451. getConsole().print("Invalid use of pigtail-command!");
  452. return -47;
  453. }
  454. } else if (cmd.compare("ponypos") == 0) {
  455. if ((!mRunning) || (!getGame().isLoaded())) {
  456. getConsole().print("Use ponypos command interactively!");
  457. return -999;
  458. }
  459. if (args->size() > 3) {
  460. SkeletalModel &tmp = getGame().getLara().getModel();
  461. tmp.setPonyPos((float)atof(args->at(0)), (float)atof(args->at(1)),
  462. (float)atof(args->at(2)), (float)atof(args->at(3)));
  463. } else {
  464. getConsole().print("Invalid use of ponypos-command!");
  465. return -48;
  466. }
  467. */
  468. } else {
  469. getConsole().print("Unknown command: %s", cmd.c_str());
  470. return -50;
  471. }
  472. return 0;
  473. }
  474. int OpenRaider::help(std::string &cmd) {
  475. if (cmd.compare("set") == 0) {
  476. getConsole().print("set-Command Usage:");
  477. getConsole().print(" set VAR VAL");
  478. getConsole().print("Available Variables:");
  479. getConsole().print(" basedir STRING");
  480. getConsole().print(" pakdir STRING");
  481. getConsole().print(" audiodir STRING");
  482. getConsole().print(" datadir STRING");
  483. getConsole().print(" font STRING");
  484. getConsole().print(" gldriver STRING");
  485. getConsole().print(" size INT INT");
  486. getConsole().print(" fullscreen BOOL");
  487. getConsole().print(" audio BOOL");
  488. getConsole().print(" volume BOOL");
  489. getConsole().print(" mouse_x FLOAT");
  490. getConsole().print(" mouse_y FLOAT");
  491. getConsole().print(" fps BOOL");
  492. getConsole().print("Enclose STRINGs with \"\"!");
  493. } else if (cmd.compare("bind") == 0) {
  494. getConsole().print("bind-Command Usage:");
  495. getConsole().print(" bind ACTION KEY");
  496. getConsole().print("Available Actions:");
  497. getConsole().print(" menu");
  498. getConsole().print(" console");
  499. getConsole().print(" forward");
  500. getConsole().print(" backward");
  501. getConsole().print(" left");
  502. getConsole().print(" right");
  503. getConsole().print(" jump");
  504. getConsole().print(" crouch");
  505. getConsole().print(" use");
  506. getConsole().print(" holster");
  507. getConsole().print("Key-Format:");
  508. getConsole().print(" 'a' or '1' for character/number keys");
  509. getConsole().print(" \"leftctrl\" for symbols and special keys");
  510. } else if (cmd.compare("load") == 0) {
  511. getConsole().print("load-Command Usage:");
  512. getConsole().print(" load levelfile.name");
  513. /*
  514. } else if (cmd.compare("game") == 0) {
  515. getConsole().print("Use \"game help\" for more info");
  516. } else if (cmd.compare("sshot") == 0) {
  517. getConsole().print("sshot-Command Usage:");
  518. getConsole().print(" sshot [console|menu]");
  519. getConsole().print("Add console/menu to capture them too");
  520. } else if (cmd.compare("sound") == 0) {
  521. getConsole().print("sound-Command Usage:");
  522. getConsole().print(" sound INT");
  523. getConsole().print("Where INT is a valid sound ID integer");
  524. } else if (cmd.compare("move") == 0) {
  525. getConsole().print("move-Command Usage:");
  526. getConsole().print(" move COMMAND");
  527. getConsole().print("Where COMMAND is one of the following:");
  528. getConsole().print(" walk");
  529. getConsole().print(" fly");
  530. getConsole().print(" noclip");
  531. } else if (cmd.compare("mode") == 0) {
  532. getConsole().print("mode-Command Usage:");
  533. getConsole().print(" mode MODE");
  534. getConsole().print("Where MODE is one of the following:");
  535. getConsole().print(" wireframe");
  536. getConsole().print(" solid");
  537. getConsole().print(" texture");
  538. getConsole().print(" vertexlight");
  539. getConsole().print(" titlescreen");
  540. } else if (cmd.compare("animate") == 0) {
  541. getConsole().print("animate-Command Usage:");
  542. getConsole().print(" animate [n|p|BOOL]");
  543. getConsole().print("Where the commands have the following meaning:");
  544. getConsole().print(" BOOL to (de)activate animating all models");
  545. getConsole().print(" n to step all models to their next animation");
  546. getConsole().print(" p to step all models to their previous animation");
  547. */
  548. } else {
  549. getConsole().print("No help available for %s", cmd.c_str());
  550. return -1;
  551. }
  552. return 0;
  553. }
  554. char *OpenRaider::expandDirectoryNames(const char *s) {
  555. assert(s != NULL);
  556. assert(s[0] != '\0');
  557. if (mBaseDir != NULL) {
  558. const char *base = "$(basedir)";
  559. if (strstr(s, base) != NULL) {
  560. return stringReplace(s, base, mBaseDir);
  561. }
  562. }
  563. if (mPakDir != NULL) {
  564. const char *pak = "$(pakdir)";
  565. if (strstr(s, pak) != NULL) {
  566. return stringReplace(s, pak, mPakDir);
  567. }
  568. }
  569. if (mAudioDir != NULL) {
  570. const char *audio = "$(audiodir)";
  571. if (strstr(s, audio) != NULL) {
  572. return stringReplace(s, audio, mAudioDir);
  573. }
  574. }
  575. if (mDataDir != NULL) {
  576. const char *data = "$(datadir)";
  577. if (strstr(s, data) != NULL) {
  578. return stringReplace(s, data, mDataDir);
  579. }
  580. }
  581. return NULL;
  582. }
  583. #define CHANGE_DIR_WITH_EXPANSION(a) do { \
  584. std::string temp; \
  585. command >> temp; \
  586. const char *value = temp.c_str(); \
  587. char *quotes = stringRemoveQuotes(value); \
  588. char *tmp = expandDirectoryNames(quotes); \
  589. if (tmp == NULL) { \
  590. a = fullPath(quotes, 0); \
  591. } else { \
  592. a = fullPath(tmp, 0); \
  593. delete [] tmp; \
  594. } \
  595. delete [] quotes; \
  596. } while(false)
  597. int OpenRaider::set(std::stringstream &command) {
  598. std::string var;
  599. command >> var >> std::boolalpha;
  600. if (var.compare("size") == 0) {
  601. unsigned int w = DEFAULT_WIDTH, h = DEFAULT_HEIGHT;
  602. if (!(command >> w >> h)) {
  603. getConsole().print("set-size-Error: Invalid value(s)");
  604. return -2;
  605. }
  606. getWindow().setSize(w, h);
  607. } else if (var.compare("fullscreen") == 0) {
  608. bool fullscreen = false;
  609. if (!(command >> fullscreen)) {
  610. getConsole().print("set-fullscreen-Error: Invalid value");
  611. return -3;
  612. }
  613. getWindow().setFullscreen(fullscreen);
  614. } else if (var.compare("gldriver") == 0) {
  615. std::string driver;
  616. command >> driver;
  617. getWindow().setDriver(driver.c_str());
  618. } else if (var.compare("audio") == 0) {
  619. bool audio = false;
  620. if (!(command >> audio)) {
  621. getConsole().print("set-audio-Error: Invalid value");
  622. return -4;
  623. }
  624. getSound().setEnabled(audio);
  625. } else if (var.compare("volume") == 0) {
  626. float vol = 1.0f;
  627. if (!(command >> vol)) {
  628. getConsole().print("set-volume-Error: Invalid value");
  629. return -5;
  630. }
  631. getSound().setVolume(vol);
  632. } else if (var.compare("mouse_x") == 0) {
  633. float sense = 1.0f;
  634. if (!(command >> sense)) {
  635. getConsole().print("set-mouse_x-Error: Invalid value");
  636. return -6;
  637. }
  638. getCamera().setSensitivityX(OR_DEG_TO_RAD(sense));
  639. } else if (var.compare("mouse_y") == 0) {
  640. float sense = 1.0f;
  641. if (!(command >> sense)) {
  642. getConsole().print("set-mouse_y-Error: Invalid value");
  643. return -7;
  644. }
  645. getCamera().setSensitivityY(OR_DEG_TO_RAD(sense));
  646. } else if (var.compare("fps") == 0) {
  647. bool fps = false;
  648. if (!(command >> fps)) {
  649. getConsole().print("set-fps-Error: Invalid value");
  650. return -8;
  651. }
  652. mFPS = fps;
  653. } else if (var.compare("basedir") == 0) {
  654. CHANGE_DIR_WITH_EXPANSION(mBaseDir);
  655. } else if (var.compare("pakdir") == 0) {
  656. CHANGE_DIR_WITH_EXPANSION(mPakDir);
  657. } else if (var.compare("audiodir") == 0) {
  658. CHANGE_DIR_WITH_EXPANSION(mAudioDir);
  659. } else if (var.compare("datadir") == 0) {
  660. CHANGE_DIR_WITH_EXPANSION(mDataDir);
  661. } else if (var.compare("font") == 0) {
  662. std::string temp;
  663. command >> temp;
  664. const char *value = temp.c_str();
  665. char *quotes = stringReplace(value, "\"", "");
  666. char *tmp = expandDirectoryNames(quotes);
  667. if (tmp == NULL) {
  668. getWindow().setFont(quotes);
  669. } else {
  670. getWindow().setFont(tmp);
  671. delete [] tmp;
  672. }
  673. delete [] quotes;
  674. } else {
  675. getConsole().print("set-Error: Unknown variable (%s)", var.c_str());
  676. return -1;
  677. }
  678. return 0;
  679. }
  680. int OpenRaider::bind(const char *action, const char *key) {
  681. assert(action != NULL);
  682. assert(action[0] != '\0');
  683. assert(key != NULL);
  684. assert(key[0] != '\0');
  685. ActionEvents e = stringToActionEvent(action);
  686. if (e == ActionEventCount) {
  687. getConsole().print("bind-Error: Unknown action (%s --> %s)", key, action);
  688. return -1;
  689. }
  690. KeyboardButton c = stringToKeyboardButton(key);
  691. if (c == unknownKey) {
  692. getConsole().print("bind-Error: Unknown key (%s)", key);
  693. return -2;
  694. }
  695. keyBindings[e] = c;
  696. return 0;
  697. }