Game.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. #include "Base.h"
  2. #include "Game.h"
  3. #include "Platform.h"
  4. #include "RenderState.h"
  5. #include "FileSystem.h"
  6. #include "FrameBuffer.h"
  7. #include "SceneLoader.h"
  8. #include "ScriptListener.h"
  9. GLenum __gl_error_code = GL_NO_ERROR;
  10. ALenum __al_error_code = AL_NO_ERROR;
  11. namespace gameplay
  12. {
  13. static Game* __gameInstance = NULL;
  14. double Game::_pausedTimeLast = 0.0;
  15. double Game::_pausedTimeTotal = 0.0;
  16. Game::Game()
  17. : _initialized(false), _state(UNINITIALIZED),
  18. _frameLastFPS(0), _frameCount(0), _frameRate(0),
  19. _clearDepth(1.0f), _clearStencil(0), _properties(NULL),
  20. _animationController(NULL), _audioController(NULL),
  21. _physicsController(NULL), _aiController(NULL), _audioListener(NULL),
  22. _gamepads(NULL), _timeEvents(NULL), _scriptController(NULL), _scriptListeners(NULL)
  23. {
  24. GP_ASSERT(__gameInstance == NULL);
  25. __gameInstance = this;
  26. _gamepads = new std::vector<Gamepad*>;
  27. _timeEvents = new std::priority_queue<TimeEvent, std::vector<TimeEvent>, std::less<TimeEvent> >();
  28. }
  29. Game::~Game()
  30. {
  31. if (_scriptListeners)
  32. {
  33. for (unsigned int i = 0; i < _scriptListeners->size(); i++)
  34. {
  35. SAFE_DELETE((*_scriptListeners)[i]);
  36. }
  37. SAFE_DELETE(_scriptListeners);
  38. }
  39. if (_scriptController)
  40. {
  41. _scriptController->finalize();
  42. SAFE_DELETE(_scriptController);
  43. }
  44. // Do not call any virtual functions from the destructor.
  45. // Finalization is done from outside this class.
  46. SAFE_DELETE(_timeEvents);
  47. #ifdef GAMEPLAY_MEM_LEAK_DETECTION
  48. Ref::printLeaks();
  49. printMemoryLeaks();
  50. #endif
  51. }
  52. Game* Game::getInstance()
  53. {
  54. GP_ASSERT(__gameInstance);
  55. return __gameInstance;
  56. }
  57. double Game::getAbsoluteTime()
  58. {
  59. return Platform::getAbsoluteTime();
  60. }
  61. double Game::getGameTime()
  62. {
  63. return Platform::getAbsoluteTime() - _pausedTimeTotal;
  64. }
  65. void Game::setVsync(bool enable)
  66. {
  67. Platform::setVsync(enable);
  68. }
  69. bool Game::isVsync()
  70. {
  71. return Platform::isVsync();
  72. }
  73. int Game::run()
  74. {
  75. if (_state != UNINITIALIZED)
  76. return -1;
  77. loadConfig();
  78. _width = Platform::getDisplayWidth();
  79. _height = Platform::getDisplayHeight();
  80. // Start up game systems.
  81. if (!startup())
  82. {
  83. shutdown();
  84. return -2;
  85. }
  86. return 0;
  87. }
  88. bool Game::startup()
  89. {
  90. if (_state != UNINITIALIZED)
  91. return false;
  92. setViewport(Rectangle(0.0f, 0.0f, (float)_width, (float)_height));
  93. RenderState::initialize();
  94. FrameBuffer::initialize();
  95. _animationController = new AnimationController();
  96. _animationController->initialize();
  97. _audioController = new AudioController();
  98. _audioController->initialize();
  99. _physicsController = new PhysicsController();
  100. _physicsController->initialize();
  101. _aiController = new AIController();
  102. _aiController->initialize();
  103. loadGamepads();
  104. _scriptController = new ScriptController();
  105. _scriptController->initialize();
  106. // Set the script callback functions.
  107. if (_properties)
  108. {
  109. Properties* scripts = _properties->getNamespace("scripts", true);
  110. if (scripts)
  111. {
  112. const char* name;
  113. while ((name = scripts->getNextProperty()) != NULL)
  114. {
  115. ScriptController::ScriptCallback callback = ScriptController::toCallback(name);
  116. if (callback != ScriptController::INVALID_CALLBACK)
  117. {
  118. std::string url = scripts->getString();
  119. std::string file;
  120. std::string id;
  121. splitURL(url, &file, &id);
  122. if (file.size() <= 0 || id.size() <= 0)
  123. {
  124. GP_ERROR("Invalid %s script callback function '%s'.", name, url.c_str());
  125. }
  126. else
  127. {
  128. _scriptController->loadScript(file.c_str());
  129. _scriptController->registerCallback(callback, id);
  130. }
  131. }
  132. else
  133. {
  134. // Ignore everything else.
  135. }
  136. }
  137. }
  138. }
  139. _state = RUNNING;
  140. return true;
  141. }
  142. void Game::shutdown()
  143. {
  144. // Call user finalization.
  145. if (_state != UNINITIALIZED)
  146. {
  147. GP_ASSERT(_animationController);
  148. GP_ASSERT(_audioController);
  149. GP_ASSERT(_physicsController);
  150. GP_ASSERT(_aiController);
  151. Platform::signalShutdown();
  152. finalize();
  153. std::vector<Gamepad*>::iterator itr = _gamepads->begin();
  154. std::vector<Gamepad*>::iterator end = _gamepads->end();
  155. while (itr != end)
  156. {
  157. SAFE_DELETE(*itr);
  158. itr++;
  159. }
  160. _gamepads->clear();
  161. SAFE_DELETE(_gamepads);
  162. _scriptController->finalizeGame();
  163. _animationController->finalize();
  164. SAFE_DELETE(_animationController);
  165. _audioController->finalize();
  166. SAFE_DELETE(_audioController);
  167. _physicsController->finalize();
  168. SAFE_DELETE(_physicsController);
  169. _aiController->finalize();
  170. SAFE_DELETE(_aiController);
  171. // Note: we do not clean up the script controller here
  172. // because users can call Game::exit() from a script.
  173. SAFE_DELETE(_audioListener);
  174. RenderState::finalize();
  175. SAFE_DELETE(_properties);
  176. _state = UNINITIALIZED;
  177. }
  178. }
  179. void Game::pause()
  180. {
  181. if (_state == RUNNING)
  182. {
  183. GP_ASSERT(_animationController);
  184. GP_ASSERT(_audioController);
  185. GP_ASSERT(_physicsController);
  186. GP_ASSERT(_aiController);
  187. _state = PAUSED;
  188. _pausedTimeLast = Platform::getAbsoluteTime();
  189. _animationController->pause();
  190. _audioController->pause();
  191. _physicsController->pause();
  192. _aiController->pause();
  193. }
  194. }
  195. void Game::resume()
  196. {
  197. if (_state == PAUSED)
  198. {
  199. GP_ASSERT(_animationController);
  200. GP_ASSERT(_audioController);
  201. GP_ASSERT(_physicsController);
  202. GP_ASSERT(_aiController);
  203. _state = RUNNING;
  204. _pausedTimeTotal += Platform::getAbsoluteTime() - _pausedTimeLast;
  205. _animationController->resume();
  206. _audioController->resume();
  207. _physicsController->resume();
  208. _aiController->resume();
  209. }
  210. }
  211. void Game::exit()
  212. {
  213. shutdown();
  214. }
  215. void Game::frame()
  216. {
  217. if (!_initialized)
  218. {
  219. initialize();
  220. _scriptController->initializeGame();
  221. _initialized = true;
  222. }
  223. if (_state == Game::RUNNING)
  224. {
  225. GP_ASSERT(_animationController);
  226. GP_ASSERT(_audioController);
  227. GP_ASSERT(_physicsController);
  228. GP_ASSERT(_aiController);
  229. // Update Time.
  230. static double lastFrameTime = Game::getGameTime();
  231. double frameTime = getGameTime();
  232. float elapsedTime = (frameTime - lastFrameTime);
  233. lastFrameTime = frameTime;
  234. // Update the scheduled and running animations.
  235. _animationController->update(elapsedTime);
  236. // Fire time events to scheduled TimeListeners
  237. fireTimeEvents(frameTime);
  238. // Update the physics.
  239. _physicsController->update(elapsedTime);
  240. // Update AI.
  241. _aiController->update(elapsedTime);
  242. // Application Update.
  243. update(elapsedTime);
  244. // Run script update.
  245. _scriptController->update(elapsedTime);
  246. // Audio Rendering.
  247. _audioController->update(elapsedTime);
  248. // Graphics Rendering.
  249. render(elapsedTime);
  250. // Run script render.
  251. _scriptController->render(elapsedTime);
  252. // Update FPS.
  253. ++_frameCount;
  254. if ((Game::getGameTime() - _frameLastFPS) >= 1000)
  255. {
  256. _frameRate = _frameCount;
  257. _frameCount = 0;
  258. _frameLastFPS = getGameTime();
  259. }
  260. }
  261. else
  262. {
  263. // Application Update.
  264. update(0);
  265. // Script update.
  266. _scriptController->update(0);
  267. // Graphics Rendering.
  268. render(0);
  269. // Script render.
  270. _scriptController->render(0);
  271. }
  272. }
  273. void Game::renderOnce(const char* function)
  274. {
  275. _scriptController->executeFunction<void>(function, NULL);
  276. Platform::swapBuffers();
  277. }
  278. void Game::updateOnce()
  279. {
  280. GP_ASSERT(_animationController);
  281. GP_ASSERT(_audioController);
  282. GP_ASSERT(_physicsController);
  283. GP_ASSERT(_aiController);
  284. // Update Time.
  285. static double lastFrameTime = getGameTime();
  286. double frameTime = getGameTime();
  287. float elapsedTime = (frameTime - lastFrameTime);
  288. lastFrameTime = frameTime;
  289. // Update the internal controllers.
  290. _animationController->update(elapsedTime);
  291. _physicsController->update(elapsedTime);
  292. _aiController->update(elapsedTime);
  293. _audioController->update(elapsedTime);
  294. _scriptController->update(elapsedTime);
  295. }
  296. void Game::setViewport(const Rectangle& viewport)
  297. {
  298. _viewport = viewport;
  299. glViewport((GLuint)viewport.x, (GLuint)viewport.y, (GLuint)viewport.width, (GLuint)viewport.height);
  300. }
  301. void Game::clear(ClearFlags flags, const Vector4& clearColor, float clearDepth, int clearStencil)
  302. {
  303. GLbitfield bits = 0;
  304. if (flags & CLEAR_COLOR)
  305. {
  306. if (clearColor.x != _clearColor.x ||
  307. clearColor.y != _clearColor.y ||
  308. clearColor.z != _clearColor.z ||
  309. clearColor.w != _clearColor.w )
  310. {
  311. glClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
  312. _clearColor.set(clearColor);
  313. }
  314. bits |= GL_COLOR_BUFFER_BIT;
  315. }
  316. if (flags & CLEAR_DEPTH)
  317. {
  318. if (clearDepth != _clearDepth)
  319. {
  320. glClearDepth(clearDepth);
  321. _clearDepth = clearDepth;
  322. }
  323. bits |= GL_DEPTH_BUFFER_BIT;
  324. // We need to explicitly call the static enableDepthWrite() method on StateBlock
  325. // to ensure depth writing is enabled before clearing the depth buffer (and to
  326. // update the global StateBlock render state to reflect this).
  327. RenderState::StateBlock::enableDepthWrite();
  328. }
  329. if (flags & CLEAR_STENCIL)
  330. {
  331. if (clearStencil != _clearStencil)
  332. {
  333. glClearStencil(clearStencil);
  334. _clearStencil = clearStencil;
  335. }
  336. bits |= GL_STENCIL_BUFFER_BIT;
  337. }
  338. glClear(bits);
  339. }
  340. AudioListener* Game::getAudioListener()
  341. {
  342. if (_audioListener == NULL)
  343. {
  344. _audioListener = new AudioListener();
  345. }
  346. return _audioListener;
  347. }
  348. void Game::menuEvent()
  349. {
  350. }
  351. void Game::keyEvent(Keyboard::KeyEvent evt, int key)
  352. {
  353. }
  354. void Game::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex)
  355. {
  356. }
  357. bool Game::mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta)
  358. {
  359. return false;
  360. }
  361. void Game::gamepadEvent(Gamepad::GamepadEvent evt, Gamepad* gamepad)
  362. {
  363. }
  364. void Game::schedule(float timeOffset, TimeListener* timeListener, void* cookie)
  365. {
  366. GP_ASSERT(_timeEvents);
  367. TimeEvent timeEvent(getGameTime() + timeOffset, timeListener, cookie);
  368. _timeEvents->push(timeEvent);
  369. }
  370. void Game::schedule(float timeOffset, const char* function)
  371. {
  372. if (!_scriptListeners)
  373. _scriptListeners = new std::vector<ScriptListener*>();
  374. ScriptListener* listener = new ScriptListener(function);
  375. _scriptListeners->push_back(listener);
  376. schedule(timeOffset, listener, NULL);
  377. }
  378. void Game::fireTimeEvents(double frameTime)
  379. {
  380. while (_timeEvents->size() > 0)
  381. {
  382. const TimeEvent* timeEvent = &_timeEvents->top();
  383. if (timeEvent->time > frameTime)
  384. {
  385. break;
  386. }
  387. if (timeEvent->listener)
  388. {
  389. timeEvent->listener->timeEvent(frameTime - timeEvent->time, timeEvent->cookie);
  390. }
  391. _timeEvents->pop();
  392. }
  393. }
  394. Game::TimeEvent::TimeEvent(double time, TimeListener* timeListener, void* cookie)
  395. : time(time), listener(timeListener), cookie(cookie)
  396. {
  397. }
  398. bool Game::TimeEvent::operator<(const TimeEvent& v) const
  399. {
  400. // The first element of std::priority_queue is the greatest.
  401. return time > v.time;
  402. }
  403. Properties* Game::getConfig() const
  404. {
  405. if (_properties == NULL)
  406. const_cast<Game*>(this)->loadConfig();
  407. return _properties;
  408. }
  409. void Game::loadConfig()
  410. {
  411. if (_properties == NULL)
  412. {
  413. // Try to load custom config from file.
  414. if (FileSystem::fileExists("game.config"))
  415. {
  416. _properties = Properties::create("game.config");
  417. // Load filesystem aliases.
  418. Properties* aliases = _properties->getNamespace("aliases", true);
  419. if (aliases)
  420. {
  421. FileSystem::loadResourceAliases(aliases);
  422. }
  423. }
  424. }
  425. }
  426. void Game::loadGamepads()
  427. {
  428. if (_properties)
  429. {
  430. // Check if there is a virtual keyboard included in the .config file.
  431. // If there is, try to create it and assign it to "player one".
  432. Properties* gamepadProperties = _properties->getNamespace("gamepads", true);
  433. if (gamepadProperties && gamepadProperties->exists("form"))
  434. {
  435. const char* gamepadFormPath = gamepadProperties->getString("form");
  436. GP_ASSERT(gamepadFormPath);
  437. Gamepad* gamepad = createGamepad(gamepadProperties->getId(), gamepadFormPath);
  438. GP_ASSERT(gamepad);
  439. }
  440. }
  441. }
  442. Gamepad* Game::createGamepad(const char* gamepadId, const char* gamepadFormPath)
  443. {
  444. GP_ASSERT(gamepadFormPath);
  445. Gamepad* gamepad = new Gamepad(gamepadId, gamepadFormPath);
  446. GP_ASSERT(gamepad);
  447. _gamepads->push_back(gamepad);
  448. return gamepad;
  449. }
  450. }