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

System.cpp 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. /*!
  2. * \file src/System.cpp
  3. * \brief Mostly defines the interface of System implementations.
  4. *
  5. * Currently only SDL is used, but there was a GLUT implementation.
  6. *
  7. * \author Mongoose
  8. */
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <sys/stat.h>
  12. #include <sys/types.h>
  13. #include <string.h>
  14. #include <stdarg.h>
  15. #include <cmath>
  16. #ifdef __APPLE__
  17. #include <OpenGL/gl.h>
  18. #include <OpenGL/glu.h>
  19. #else
  20. #include <GL/gl.h>
  21. #include <GL/glu.h>
  22. #endif
  23. #if defined(linux) || defined(__APPLE__)
  24. #include <time.h>
  25. #include <sys/time.h>
  26. #endif
  27. #include "utils/math.h"
  28. #include "System.h"
  29. ////////////////////////////////////////////////////////////
  30. // Constructors
  31. ////////////////////////////////////////////////////////////
  32. System::System()
  33. {
  34. m_width = 800;
  35. m_height = 600;
  36. m_driver = 0x0;
  37. m_clipFar = 4000.0f;
  38. m_clipNear = 4.0f;
  39. m_fovY = 45.0f;
  40. mConsoleMode = false;
  41. mCommandMode = 0;
  42. printf("[System.Core]\n");
  43. // Hack for bad Map class, as well as reserved commands
  44. addCommandMode("[System.Console]");
  45. mConsoleKey = '`';
  46. bindKeyCommand("+console", mConsoleKey, 0);
  47. #ifdef WIN32
  48. setDriverGL("libGL32.dll");
  49. #else
  50. setDriverGL("/usr/lib/libGL.so.1");
  51. #endif
  52. }
  53. System::~System()
  54. {
  55. }
  56. ////////////////////////////////////////////////////////////
  57. // Public Accessors
  58. ////////////////////////////////////////////////////////////
  59. unsigned int System::getTicks()
  60. {
  61. return system_timer(1);
  62. }
  63. int System::createDir(char *path)
  64. {
  65. #ifdef WIN32
  66. return _mkdir(path);
  67. #else
  68. return mkdir(path, S_IRWXU | S_IRWXG);
  69. #endif
  70. }
  71. ////////////////////////////////////////////////////////////
  72. // Public Mutators
  73. ////////////////////////////////////////////////////////////
  74. unsigned int System::addCommandMode(const char *command)
  75. {
  76. if (command && command[0] == '[')
  77. {
  78. mCmdModes.pushBack(command);
  79. return (mCmdModes.size() - 1);
  80. }
  81. else
  82. {
  83. return 0;
  84. }
  85. }
  86. //! \fixme Modifer support later
  87. void System::bindKeyCommand(const char *cmd, unsigned int key, int event)
  88. {
  89. printf("Bound command '%s' -> event %i (0x%x key)\n", cmd, event, key);
  90. mKeyEvents[key] = event;
  91. }
  92. void System::command(const char *cmd)
  93. {
  94. bool modeFound = false;
  95. char *cmdbuf;
  96. if (!cmd || !cmd[0]) // Null command string
  97. return;
  98. if (cmd[0] == '[') // Set a mode, eg "[Engine.OpenGL.Driver]"
  99. {
  100. for (mCmdModes.start(); mCmdModes.forward(); mCmdModes.next())
  101. {
  102. if (strcmp(cmd, mCmdModes.current()) == 0)
  103. {
  104. mCommandMode = mCmdModes.getCurrentIndex();
  105. modeFound = true;
  106. }
  107. }
  108. if (!modeFound)
  109. {
  110. // mCommandMode = 0;
  111. printf("Command> Unknown mode '%s'\n", cmd);
  112. }
  113. }
  114. else // Execute a command in current mode, eg "stat fps"
  115. {
  116. cmdbuf = new char[strlen(cmd) + 1];
  117. strncpy(cmdbuf, cmd, strlen(cmd) + 1);
  118. handleCommand(cmdbuf, mCommandMode);
  119. }
  120. }
  121. int System::loadResourceFile(const char *filename)
  122. {
  123. char buffer[256];
  124. bool line_comment = false;
  125. FILE *f;
  126. char c;
  127. int i, j;
  128. f = fopen(filename, "r");
  129. if (!f)
  130. {
  131. perror(filename);
  132. return -1;
  133. }
  134. printf("Loading %s...\n", filename);
  135. i = 0;
  136. buffer[0] = 0;
  137. // Strip out whitespace and comments
  138. while (fscanf(f, "%c", &c) != EOF)
  139. {
  140. if (line_comment && c != '\n')
  141. continue;
  142. if (i > 254)
  143. {
  144. printf("loadResourceFile> Overflow handled\n");
  145. i = 254;
  146. }
  147. switch (c)
  148. {
  149. case '\v':
  150. case '\t':
  151. break;
  152. case '#':
  153. buffer[i++] = 0;
  154. line_comment = true;
  155. break;
  156. case '\n':
  157. if (line_comment)
  158. {
  159. line_comment = false;
  160. }
  161. if (buffer[0] == 0)
  162. {
  163. i = 0;
  164. continue;
  165. }
  166. buffer[i] = 0;
  167. //printf("'%s'\n", buffer);
  168. // 'Preprocessor' commands
  169. if (buffer[0] == '@')
  170. {
  171. if (strncmp(buffer, "@include ", 9) == 0)
  172. {
  173. for (j = 9; j < i; ++j)
  174. {
  175. buffer[j-9] = buffer[j];
  176. buffer[j-8] = 0;
  177. }
  178. printf("Importing '%s'\n", buffer);
  179. loadResourceFile(fullPath(buffer, 0));
  180. }
  181. }
  182. else
  183. {
  184. command(buffer);
  185. }
  186. i = 0;
  187. buffer[0] = 0;
  188. break;
  189. default:
  190. buffer[i++] = c;
  191. }
  192. }
  193. fclose(f);
  194. return 0;
  195. }
  196. void System::setDriverGL(const char *driver)
  197. {
  198. unsigned int len;
  199. if (m_driver)
  200. {
  201. delete [] m_driver;
  202. }
  203. if (driver && driver[0])
  204. {
  205. len = strlen(driver);
  206. m_driver = new char[len+1];
  207. strncpy(m_driver, driver, len);
  208. m_driver[len] = 0;
  209. }
  210. }
  211. void System::resetTicks()
  212. {
  213. system_timer(0);
  214. }
  215. void System::initGL()
  216. {
  217. char *s;
  218. // Print driver support information
  219. printf("\n\n\t## GL Driver Info 1 ##\n");
  220. printf("\tVendor : %s\n", glGetString(GL_VENDOR));
  221. printf("\tRenderer : %s\n", glGetString(GL_RENDERER));
  222. printf("\tVersion : %s\n", glGetString(GL_VERSION));
  223. printf("\tExtensions : %s\n\n\n", (char*)glGetString(GL_EXTENSIONS));
  224. // Testing for goodies
  225. // Mongoose 2001.12.31, Fixed string use to check for bad strings
  226. s = (char*)glGetString(GL_EXTENSIONS);
  227. if (s && s[0])
  228. {
  229. printf("\tGL_ARB_multitexture \t\t");
  230. if (strstr(s, "GL_ARB_multitexture"))
  231. {
  232. printf("YES\n");
  233. }
  234. else
  235. {
  236. printf("NO\n");
  237. }
  238. //glActiveTextureARB
  239. //glMultiTexCoord2fARB
  240. //glFogCoordfEXT
  241. printf("\tGL_EXT_texture_env_combine\t\t");
  242. if (strstr(s, "GL_EXT_texture_env_combine"))
  243. {
  244. printf("YES\n");
  245. }
  246. else
  247. {
  248. printf("NO\n");
  249. }
  250. }
  251. // Set up Z buffer
  252. glEnable(GL_DEPTH_TEST);
  253. glDepthFunc(GL_LESS);
  254. // Set up culling
  255. glEnable(GL_CULL_FACE);
  256. //glFrontFace(GL_CW);
  257. glFrontFace(GL_CCW);
  258. //glCullFace(GL_FRONT);
  259. // Set background to black
  260. glClearColor(0.0, 0.0, 0.0, 1.0);
  261. // Disable lighting
  262. glDisable(GL_LIGHTING);
  263. // Set up alpha blending
  264. glEnable(GL_BLEND);
  265. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  266. //glEnable(GL_ALPHA_TEST); // Disable per pixel alpha blending
  267. glAlphaFunc(GL_GREATER, 0);
  268. glPointSize(5.0);
  269. // Setup shading
  270. glShadeModel(GL_SMOOTH);
  271. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  272. glHint(GL_FOG_HINT, GL_NICEST);
  273. glEnable(GL_COLOR_MATERIAL);
  274. glEnable(GL_DITHER);
  275. // AA polygon edges
  276. glEnable(GL_POLYGON_SMOOTH);
  277. glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
  278. glEnable(GL_POINT_SMOOTH);
  279. glEnable(GL_FOG);
  280. glDisable(GL_LINE_SMOOTH);
  281. glDisable(GL_AUTO_NORMAL);
  282. glDisable(GL_LOGIC_OP);
  283. glDisable(GL_TEXTURE_1D);
  284. glDisable(GL_STENCIL_TEST);
  285. glDisable(GL_NORMALIZE);
  286. glEnableClientState(GL_VERTEX_ARRAY);
  287. glDisableClientState(GL_EDGE_FLAG_ARRAY);
  288. glDisableClientState(GL_COLOR_ARRAY);
  289. glDisableClientState(GL_NORMAL_ARRAY);
  290. glPolygonMode(GL_FRONT, GL_FILL);
  291. glMatrixMode(GL_MODELVIEW);
  292. }
  293. void System::resizeGL(unsigned int w, unsigned int h)
  294. {
  295. if (!w || !h)
  296. {
  297. printf("resizeGL> ERROR assertions 'w > 0', 'h > 0' failed\n");
  298. return;
  299. }
  300. glViewport(0, 0, w, h);
  301. glMatrixMode(GL_PROJECTION);
  302. glLoadIdentity();
  303. // Adjust clipping
  304. // gluPerspective is deprecated!
  305. // gluPerspective(m_fovY, ((GLdouble)w)/((GLdouble)h), m_clipNear, m_clipFar);
  306. // Fix: http://stackoverflow.com/a/2417756
  307. GLfloat fH = tanf(m_fovY * HEL_PI / 360.0f) * m_clipNear;
  308. GLfloat fW = fH * ((GLfloat)w)/((GLfloat)h);
  309. glFrustum(-fW, fW, -fH, fH, m_clipNear, m_clipFar);
  310. glMatrixMode(GL_MODELVIEW);
  311. }
  312. ////////////////////////////////////////////////////////////
  313. // Private Accessors
  314. ////////////////////////////////////////////////////////////
  315. ////////////////////////////////////////////////////////////
  316. // Private Mutators
  317. ////////////////////////////////////////////////////////////
  318. ////////////////////////////////////////////////////////////
  319. // Gobal helper functions
  320. ////////////////////////////////////////////////////////////
  321. unsigned int system_timer(int state)
  322. {
  323. static struct timeval start;
  324. static struct timeval stop;
  325. static struct timezone tz;
  326. switch (state)
  327. {
  328. case 0:
  329. gettimeofday(&start, &tz);
  330. break;
  331. case 1:
  332. gettimeofday(&stop, &tz);
  333. if (start.tv_usec > stop.tv_usec)
  334. {
  335. stop.tv_usec += 1000000;
  336. stop.tv_sec--;
  337. }
  338. stop.tv_usec -= start.tv_usec;
  339. stop.tv_sec -= start.tv_sec;
  340. return ((stop.tv_sec - start.tv_sec) * 1000) + ((stop.tv_usec - start.tv_usec) / 1000);
  341. }
  342. return 0;
  343. }