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.

System.cpp 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
  2. /*================================================================
  3. *
  4. * Project : UnRaider
  5. * Author : Terry 'Mongoose' Hendrix II
  6. * Website : http://www.westga.edu/~stu7440/
  7. * Email : stu7440@westga.edu
  8. * Object : System
  9. * License : No use w/o permission (C) 2002 Mongoose
  10. * Comments:
  11. *
  12. *
  13. * This file was generated using Mongoose's C++
  14. * template generator script. <stu7440@westga.edu>
  15. *
  16. *-- History -------------------------------------------------
  17. *
  18. * 2002.08.09:
  19. * Mongoose - Created
  20. =================================================================*/
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <sys/stat.h>
  24. #include <sys/types.h>
  25. #include <string.h>
  26. #include <stdarg.h>
  27. #ifdef USING_OPENGL
  28. #ifdef __APPLE__
  29. #include <OpenGL/gl.h>
  30. #include <OpenGL/glu.h>
  31. #else
  32. #include <GL/gl.h>
  33. #include <GL/glu.h>
  34. #endif
  35. #endif
  36. #ifdef HAVE_LIBFERIT
  37. # include <ferit/Url.h>
  38. # include <ferit/TcpProtocol.h>
  39. # include <ferit/Http.h>
  40. # include <ferit/Ftp.h>
  41. #endif
  42. #if defined(linux) || defined(__APPLE__)
  43. # include <time.h>
  44. # include <sys/time.h>
  45. #endif
  46. #ifdef MEMEORY_TEST
  47. # include "memeory_test.h"
  48. #endif
  49. #ifdef PS2_LINUX
  50. # include "ps2linux.h"
  51. #endif
  52. #include "System.h"
  53. ////////////////////////////////////////////////////////////
  54. // Constructors
  55. ////////////////////////////////////////////////////////////
  56. System::System()
  57. {
  58. m_width = 800;
  59. m_height = 600;
  60. m_fastCard = true;
  61. m_driver = 0x0;
  62. m_clipFar = 4000.0f;
  63. m_clipNear = 4.0f;
  64. m_fovY = 45.0f;
  65. mConsoleMode = false;
  66. printf("[System.Core]\n");
  67. // Hack for bad Map class, as well as reserved commands
  68. addCommandMode("[System.Console]");
  69. mConsoleKey = '`';
  70. bindKeyCommand("+console", mConsoleKey, 0);
  71. #ifdef WIN32
  72. setDriverGL("libGL32.dll");
  73. #else
  74. setDriverGL("/usr/lib/libGL.so.1");
  75. #endif
  76. }
  77. System::~System()
  78. {
  79. }
  80. ////////////////////////////////////////////////////////////
  81. // Public Accessors
  82. ////////////////////////////////////////////////////////////
  83. char *System::bufferString(const char *string, ...)
  84. {
  85. int sz = 60;
  86. int n;
  87. char *text;
  88. va_list args;
  89. // Mongoose 2002.01.01, Only allow valid strings
  90. // we must assume it's NULL terminated also if it passes...
  91. if (!string || !string[0])
  92. {
  93. return NULL;
  94. }
  95. text = new char[sz];
  96. va_start(args, string);
  97. // Mongoose 2002.01.01, Get exact size needed if the first try fails
  98. n = vsnprintf(text, sz, string, args);
  99. // Mongoose 2002.01.01, Realloc correct amount if truncated
  100. while (1)
  101. {
  102. if (n > -1 && n < sz)
  103. {
  104. break;
  105. }
  106. // Mongoose 2002.01.01, For glibc 2.1
  107. if (n > -1)
  108. {
  109. sz = n + 1;
  110. delete [] text;
  111. text = new char[sz];
  112. n = vsnprintf(text, sz, string, args);
  113. break;
  114. }
  115. else // glibc 2.0
  116. {
  117. sz *= 2;
  118. delete [] text;
  119. text = new char[sz];
  120. n = vsnprintf(text, sz, string, args);
  121. }
  122. }
  123. va_end(args);
  124. return text;
  125. }
  126. char *System::fullPath(const char *path, char end)
  127. {
  128. unsigned int i, lenPath, lenEnv, len;
  129. char *env, *dir;
  130. if (!path || !path[0])
  131. return 0;
  132. if (path[0] == '~')
  133. {
  134. #if defined(unix) || defined(__APPLE__)
  135. env = getenv("HOME");
  136. if (!env || !env[0])
  137. {
  138. return 0;
  139. }
  140. lenEnv = strlen(env);
  141. lenPath = strlen(path);
  142. len = lenEnv + lenPath;
  143. dir = new char[len+1];
  144. // Mongoose 2002.08.17, Copy ENV, strip '~', append rest of path
  145. for (i = 0; i < len; ++i)
  146. {
  147. if (i < lenEnv)
  148. {
  149. dir[i] = env[i];
  150. }
  151. else
  152. {
  153. dir[i] = path[1+(i-lenEnv)];
  154. }
  155. }
  156. #else
  157. #error Platform not supported!
  158. #endif
  159. }
  160. else
  161. {
  162. lenPath = strlen(path);
  163. dir = new char[lenPath+1];
  164. strncpy(dir, path, lenPath);
  165. i = lenPath;
  166. }
  167. // Make sure ends in "end" char
  168. if (end && dir[i-1] != end)
  169. {
  170. dir[i++] = end;
  171. }
  172. dir[i] = 0;
  173. return dir;
  174. }
  175. char *System::getFileFromFullPath(char *filename)
  176. {
  177. int i, j, len;
  178. char *str;
  179. len = strlen(filename);
  180. for (i = len, j = 0; i > 0; --i, ++j)
  181. {
  182. if (filename[i] == '/' || filename[i] == '\\')
  183. break;
  184. }
  185. j--;
  186. str = new char[len - j + 1];
  187. for (i = 0; i < len - j; ++i)
  188. {
  189. str[i] = filename[i + len - j];
  190. }
  191. str[i] = 0;
  192. return str;
  193. }
  194. unsigned int System::getTicks()
  195. {
  196. return system_timer(1);
  197. }
  198. int System::createDir(char *path)
  199. {
  200. #ifdef WIN32
  201. return _mkdir(path);
  202. #else
  203. return mkdir(path, S_IRWXU | S_IRWXG);
  204. #endif
  205. }
  206. int System::downloadToBuffer(char *urlString,
  207. unsigned char **buffer, unsigned int *size)
  208. {
  209. #ifdef HAVE_LIBFERIT
  210. printf("ERROR: This build is libferit enabled, but func not implemented\n");
  211. return -1;
  212. #else
  213. printf("ERROR: This build not libferit enabled, unable to download\n");
  214. return -1000;
  215. #endif
  216. }
  217. int System::downloadToFile(char *urlString, char *filename)
  218. {
  219. #ifdef HAVE_LIBFERIT
  220. int err = 0;
  221. unsigned int timeout = 10;
  222. Url *url = 0x0;
  223. TcpProtocol *client = 0x0;
  224. if (!urlString || !urlString[0])
  225. return -1;
  226. url = new Url("");
  227. url->UrlToSession(urlString);
  228. url->Options(OPT_RESUME | OPT_QUIET);
  229. url->Outfile(url->Filename());
  230. switch (url->Protocol())
  231. {
  232. case FTP_SESSION:
  233. client = new Ftp(timeout);
  234. break;
  235. case HTTP_SESSION:
  236. client = new Http(timeout);
  237. break;
  238. default:
  239. printf("Sorry the protocol used in the URL isn't unsupported.\n");
  240. if (client)
  241. {
  242. delete client;
  243. }
  244. return -2;
  245. }
  246. if (client)
  247. {
  248. err = client->Download(url, NULL);
  249. delete client;
  250. }
  251. if (url)
  252. delete url;
  253. return err;
  254. #else
  255. printf("ERROR: This build not libferit enabled, unable to download\n");
  256. return -1000;
  257. #endif
  258. }
  259. ////////////////////////////////////////////////////////////
  260. // Public Mutators
  261. ////////////////////////////////////////////////////////////
  262. unsigned int System::addCommandMode(const char *command)
  263. {
  264. if (command && command[0] == '[')
  265. {
  266. mCmdModes.pushBack(command);
  267. return (mCmdModes.size() - 1);
  268. }
  269. else
  270. {
  271. return 0;
  272. }
  273. }
  274. // FIXME: Modifer support later
  275. void System::bindKeyCommand(const char *cmd, unsigned int key, int event)
  276. {
  277. printf("Bound command '%s' -> event %i (0x%x key)\n", cmd, event, key);
  278. mKeyEvents.Add(key, event);
  279. }
  280. void System::command(const char *cmd)
  281. {
  282. bool modeFound = false;
  283. char *cmdbuf;
  284. if (!cmd || !cmd[0]) // Null command string
  285. return;
  286. if (cmd[0] == '[') // Set a mode, eg "[Engine.OpenGL.Driver]"
  287. {
  288. for (mCmdModes.start(); mCmdModes.forward(); mCmdModes.next())
  289. {
  290. if (strcmp(cmd, mCmdModes.current()) == 0)
  291. {
  292. mCommandMode = mCmdModes.getCurrentIndex();
  293. modeFound = true;
  294. }
  295. }
  296. if (!modeFound)
  297. {
  298. // mCommandMode = 0;
  299. printf("Command> Unknown mode '%s'\n", cmd);
  300. }
  301. }
  302. else // Execute a command in current mode, eg "stat fps"
  303. {
  304. cmdbuf = new char[strlen(cmd) + 1];
  305. strncpy(cmdbuf, cmd, strlen(cmd) + 1);
  306. handleCommand(cmdbuf, mCommandMode);
  307. }
  308. }
  309. int System::loadResourceFile(const char *filename)
  310. {
  311. char buffer[256];
  312. bool line_comment = false;
  313. FILE *f;
  314. char c;
  315. int i, j;
  316. f = fopen(filename, "r");
  317. if (!f)
  318. {
  319. perror(filename);
  320. return -1;
  321. }
  322. printf("Resource system \n");
  323. i = 0;
  324. buffer[0] = 0;
  325. // Strip out whitespace and comments
  326. while (fscanf(f, "%c", &c) != EOF)
  327. {
  328. if (line_comment && c != '\n')
  329. continue;
  330. if (i > 254)
  331. {
  332. printf("loadResourceFile> Overflow handled\n");
  333. i = 254;
  334. }
  335. switch (c)
  336. {
  337. case '\v':
  338. case '\t':
  339. break;
  340. case '#':
  341. buffer[i++] = 0;
  342. line_comment = true;
  343. break;
  344. case '\n':
  345. if (line_comment)
  346. {
  347. line_comment = false;
  348. }
  349. if (buffer[0] == 0)
  350. {
  351. i = 0;
  352. continue;
  353. }
  354. buffer[i] = 0;
  355. //printf("'%s'\n", buffer);
  356. // 'Preprocessor' commands
  357. if (buffer[0] == '@')
  358. {
  359. if (strncmp(buffer, "@include ", 9) == 0)
  360. {
  361. for (j = 9; j < i; ++j)
  362. {
  363. buffer[j-9] = buffer[j];
  364. buffer[j-8] = 0;
  365. }
  366. printf("Importing '%s'\n", buffer);
  367. loadResourceFile(fullPath(buffer, '/'));
  368. }
  369. }
  370. else
  371. {
  372. command(buffer);
  373. }
  374. i = 0;
  375. buffer[0] = 0;
  376. break;
  377. default:
  378. buffer[i++] = c;
  379. }
  380. }
  381. fclose(f);
  382. return 0;
  383. }
  384. void System::setDriverGL(const char *driver)
  385. {
  386. unsigned int len;
  387. if (m_driver)
  388. {
  389. delete [] m_driver;
  390. }
  391. if (driver && driver[0])
  392. {
  393. len = strlen(driver);
  394. m_driver = new char[len+1];
  395. strncpy(m_driver, driver, len);
  396. m_driver[len] = 0;
  397. }
  398. }
  399. void System::setFastCardPerformance(bool is_fast)
  400. {
  401. m_fastCard = is_fast;
  402. }
  403. void System::resetTicks()
  404. {
  405. system_timer(0);
  406. }
  407. void System::initGL()
  408. {
  409. char *s;
  410. // Print driver support information
  411. printf("\n\n\t## GL Driver Info ##\n");
  412. printf("\tVendor : %s\n", glGetString(GL_VENDOR));
  413. printf("\tRenderer : %s\n", glGetString(GL_RENDERER));
  414. printf("\tVersion : %s\n", glGetString(GL_VERSION));
  415. printf("\tExtensions : %s\n\n\n", (char*)glGetString(GL_EXTENSIONS));
  416. // Testing for goodies
  417. // Mongoose 2001.12.31, Fixed string use to check for bad strings
  418. s = (char*)glGetString(GL_EXTENSIONS);
  419. if (s && s[0])
  420. {
  421. printf("\tGL_ARB_multitexture \t\t");
  422. if (strstr(s, "GL_ARB_multitexture"))
  423. {
  424. printf("YES\n");
  425. }
  426. else
  427. {
  428. printf("NO\n");
  429. }
  430. //glActiveTextureARB
  431. //glMultiTexCoord2fARB
  432. //glFogCoordfEXT
  433. printf("\tGL_EXT_texture_env_combine\t\t");
  434. if (strstr(s, "GL_EXT_texture_env_combine"))
  435. {
  436. printf("YES\n");
  437. }
  438. else
  439. {
  440. printf("NO\n");
  441. }
  442. }
  443. // Set up Z buffer
  444. glEnable(GL_DEPTH_TEST);
  445. glDepthFunc(GL_LESS);
  446. // Set up culling
  447. glEnable(GL_CULL_FACE);
  448. //glFrontFace(GL_CW);
  449. glFrontFace(GL_CCW);
  450. //glCullFace(GL_FRONT);
  451. // Set background to black
  452. glClearColor(0.0, 0.0, 0.0, 1.0);
  453. // Disable lighting
  454. glDisable(GL_LIGHTING);
  455. // Set up alpha blending
  456. if (m_fastCard)
  457. {
  458. glEnable(GL_BLEND);
  459. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  460. //glEnable(GL_ALPHA_TEST); // Disable per pixel alpha blending
  461. glAlphaFunc(GL_GREATER, 0);
  462. }
  463. else
  464. {
  465. glDisable(GL_BLEND);
  466. glDisable(GL_ALPHA_TEST);
  467. }
  468. glPointSize(5.0);
  469. // Setup shading
  470. glShadeModel(GL_SMOOTH);
  471. if (m_fastCard)
  472. {
  473. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  474. glHint(GL_FOG_HINT, GL_NICEST);
  475. glDisable(GL_COLOR_MATERIAL);
  476. glEnable(GL_DITHER);
  477. // AA polygon edges
  478. //glEnable(GL_POLYGON_SMOOTH);
  479. //glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
  480. glEnable(GL_POINT_SMOOTH);
  481. }
  482. else
  483. {
  484. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  485. glHint(GL_FOG_HINT, GL_FASTEST);
  486. glDisable(GL_COLOR_MATERIAL);
  487. glDisable(GL_DITHER);
  488. glDisable(GL_POLYGON_SMOOTH);
  489. glDisable(GL_POINT_SMOOTH);
  490. glDisable(GL_FOG);
  491. }
  492. glDisable(GL_LINE_SMOOTH);
  493. glDisable(GL_AUTO_NORMAL);
  494. glDisable(GL_LOGIC_OP);
  495. glDisable(GL_TEXTURE_1D);
  496. glDisable(GL_STENCIL_TEST);
  497. glDisable(GL_NORMALIZE);
  498. glEnableClientState(GL_VERTEX_ARRAY);
  499. glDisableClientState(GL_EDGE_FLAG_ARRAY);
  500. glDisableClientState(GL_COLOR_ARRAY);
  501. glDisableClientState(GL_NORMAL_ARRAY);
  502. glPolygonMode(GL_FRONT, GL_FILL);
  503. glMatrixMode(GL_MODELVIEW);
  504. }
  505. void System::resizeGL(unsigned int w, unsigned int h)
  506. {
  507. if (!w || !h)
  508. {
  509. printf("resizeGL> ERROR assertions 'w > 0', 'h > 0' failed\n");
  510. return;
  511. }
  512. glViewport(0, 0, w, h);
  513. glMatrixMode(GL_PROJECTION);
  514. glLoadIdentity();
  515. // Adjust clipping
  516. gluPerspective(m_fovY, ((GLdouble)w)/((GLdouble)h), m_clipNear, m_clipFar);
  517. glMatrixMode(GL_MODELVIEW);
  518. }
  519. ////////////////////////////////////////////////////////////
  520. // Private Accessors
  521. ////////////////////////////////////////////////////////////
  522. ////////////////////////////////////////////////////////////
  523. // Private Mutators
  524. ////////////////////////////////////////////////////////////
  525. ////////////////////////////////////////////////////////////
  526. // Gobal helper functions
  527. ////////////////////////////////////////////////////////////
  528. // Mongoose 2002.03.23, Checks command to see if it's same
  529. // as symbol, then returns the arg list in command buffer
  530. bool rc_command(const char *symbol, char *command)
  531. {
  532. int i, j, lens, lenc;
  533. if (!symbol || !symbol[0] || !command || !command[0])
  534. {
  535. return false;
  536. }
  537. lens = strlen(symbol);
  538. if (strncmp(command, symbol, lens) == 0)
  539. {
  540. lenc = strlen(command);
  541. // lens+1 skips '=' or ' '
  542. for (i = 0, j = lens+1; j < lenc; ++i, ++j)
  543. {
  544. command[i] = command[j];
  545. command[i+1] = 0;
  546. }
  547. return true;
  548. }
  549. return false;
  550. }
  551. int rc_get_bool(char *buffer, bool *val)
  552. {
  553. if (!buffer || !buffer[0])
  554. {
  555. return -1;
  556. }
  557. if (strncmp(buffer, "true", 4) == 0)
  558. *val = true;
  559. else if (strncmp(buffer, "false", 5) == 0)
  560. *val = false;
  561. else
  562. return -2;
  563. return 0;
  564. }
  565. unsigned int system_timer(int state)
  566. {
  567. static struct timeval start;
  568. static struct timeval stop;
  569. static struct timeval total;
  570. static struct timezone tz;
  571. switch (state)
  572. {
  573. case 0:
  574. gettimeofday(&start, &tz);
  575. total.tv_sec = 0;
  576. total.tv_usec = 0;
  577. break;
  578. case 1:
  579. gettimeofday(&stop, &tz);
  580. if (start.tv_usec > stop.tv_usec)
  581. {
  582. #ifdef OBSOLETE
  583. stop.tv_usec = (1000000 + stop.tv_usec);
  584. #else
  585. stop.tv_usec = (1000 + stop.tv_usec);
  586. #endif
  587. stop.tv_sec--;
  588. }
  589. stop.tv_usec -= start.tv_usec;
  590. stop.tv_sec -= start.tv_sec;
  591. #ifdef OBSOLETE
  592. total.tv_sec += stop.tv_sec;
  593. total.tv_usec += stop.tv_usec;
  594. while (total.tv_usec > 1000000)
  595. {
  596. total.tv_usec -= 1000000;
  597. total.tv_sec++;
  598. }
  599. return total.tv_sec * 1000000 + total.tv_usec;
  600. #else
  601. return (stop.tv_sec-start.tv_sec)*1000+(stop.tv_usec-start.tv_usec)/1000;
  602. #endif
  603. break;
  604. }
  605. return 0;
  606. }
  607. ////////////////////////////////////////////////////////////
  608. // Unit Test code
  609. ////////////////////////////////////////////////////////////
  610. #ifdef UNIT_TEST_SYSTEM
  611. int runSystemUnitTest(int argc, char *argv[])
  612. {
  613. return 0;
  614. }
  615. int main(int argc, char *argv[])
  616. {
  617. System test;
  618. printf("[System class test]\n");
  619. return runSystemUnitTest(argc, argv);
  620. }
  621. #endif