123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- #include <cstdlib>
- #include <cmath>
- #include <cstring>
- #include <ctime>
- #if EM_THREADS
- #include <sched.h>
- #endif
- #include "Private.h"
- #include "Engine.h"
- #include "Camera.h"
- #include "Keyboard.h"
- #include "AlignVisitor.h"
- #include "AllegroVisitor.h"
- #include "AmbientLightVisitor.h"
- #include "BehaviorVisitor.h"
- #include "CollisionVisitor.h"
- #include "OpenGLVisitor.h"
- #include "SoundVisitor.h"
- #include "SignalSender.h"
- #include "TransformVisitor.h"
- #include "Config.h"
- #include "SoundUtil.h"
- #include "TextureUtil.h"
- #include "Profiler.h"
- #if EM_USE_SDL
- #if EM_DEBUG
- #include <GL/glu.h>
- #endif
- #endif
- volatile int g_iStartTime = -1;
- volatile int g_iLastRender = 0;
- volatile unsigned int g_iLoops = 0;
- volatile unsigned int g_iMSeconds = 0;
- #if EM_DEBUG
- #define StartProfile(a) Profiler::getInstance()->startProfile(a)
- #define StopProfile() Profiler::getInstance()->stopProfile()
- #else
- #define StartProfile(a)
- #define StopProfile()
- #endif
- #if EM_USE_ALLEGRO
- extern "C" {
- void fctCallBack() {
- g_iMSeconds += 10;
- }
- END_OF_FUNCTION(fctCallBack)
- }
- #endif
- #if EM_USE_SDL
- #define GET_TIME (signed)SDL_GetTicks()
- #endif
- #if EM_USE_ALLEGRO
- #define GET_TIME g_iMSeconds
- #endif
- float Engine::m_fFps = 0.0f;
- Engine * Engine::p_Engine = NULL;
- Engine::Engine(int & argc, char *argv[]) {
- Config * config = Config::getInstance();
- config->loadArgs(argc, argv);
-
- if (!config->useExternGL()) {
- #if EM_USE_SDL
- SDL_Init(SDL_INIT_TIMER);
- #endif
- TextureUtil::getInstance()->initGrx();
- #if EM_USE_ALLEGRO
- LOCK_VARIABLE(g_iStartTime);
-
- LOCK_VARIABLE(g_iLastRender);
- LOCK_VARIABLE(g_iLoops);
- LOCK_VARIABLE(g_iMSeconds);
- LOCK_VARIABLE(g_fFps);
- LOCK_FUNCTION(fctCallBack);
- install_int(fctCallBack, 10);
- #endif
- }
-
- SoundUtil::getInstance()->applyConfigVolume();
-
-
-
-
-
-
-
-
-
- srand((unsigned int)time((time_t *)NULL));
- p_Engine = this;
- }
- Engine::~Engine() {
- p_Engine = NULL;
- this->stopEngine();
- }
- void Engine::stopEngine() {
- #if EM_USE_SDL
- SoundUtil::getInstance()->stopSound();
- TextureUtil::getInstance()->stopGrx();
- #endif
- #if EM_DEBUG
- extern float em_groups_m, em_shapes_m, em_bounds_m, em_polygons_m;
- cerr << "Collision profile ********************" << endl;
- cerr << "Group-group detections " << em_groups_m << endl;
- cerr << "Shape-shape detections " << em_shapes_m << endl;
- cerr << "Bound-bound detections " << em_bounds_m << endl;
- cerr << "Poly-poly detections " << em_polygons_m << endl;
- Profiler::getInstance()->printProfile();
-
-
-
- #endif
- }
- void Engine::clear() {
- SignalSender::getInstance()->clear();
- AmbientLightVisitor::getInstance()->clear();
-
- this->freeObjects();
- }
- void Engine::addLight(Light* l) {
-
- AmbientLightVisitor::getInstance()->add(l);
- }
- void Engine::setClearColor(float r, float g, float b, float a) {
- TextureUtil::getInstance()->setClearColor(r, g, b, a);
- }
- void Engine::clearScreen() {
- StartProfile(SWAP);
- #if EM_USE_SDL
- glDepthMask(GL_TRUE);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glColor3f(1, 1, 1);
- glLoadIdentity();
-
- #endif
- #if EM_USE_ALLEGRO
- clear_zbuffer(zbuffer, 0);
- clear_bitmap(backbuffer);
- #endif
- StopProfile();
- }
- void Engine::setLightning(float diffuse, float ambient) {
- AmbientLightVisitor::getInstance()->setLightning(diffuse, ambient);
-
- }
- void Engine::drawSplash(EmTexture * tex) {
- if (tex == NULL) return;
- #if EM_USE_SDL
- int filter = Config::getInstance()->getGLFilter();
- if (filter == -1) return;
- glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
- glDisable(GL_ALPHA_TEST);
- glDisable(GL_BLEND);
- glDepthMask(GL_FALSE);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, *(tex));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0);
- glVertex3f(-EM_RIGHT, EM_UP, -1);
- glTexCoord2f(1, 0);
- glVertex3f(EM_RIGHT, EM_UP, -1);
- glTexCoord2f(1, 1);
- glVertex3f(EM_RIGHT, -EM_UP, -1);
- glTexCoord2f(0, 1);
- glVertex3f(-EM_RIGHT, -EM_UP, -1);
- glEnd();
- #endif
-
- #if EM_USE_ALLEGRO
-
- stretch_blit(tex, backbuffer, 0, 0, 256, 256, 0, 0,
- Config::getInstance()->getWidth(), Config::getInstance()->getHeight());
- #endif
- }
- void Engine::setEngineCamera(Group* g) {
- AlignVisitor::getInstance()->setCamera(g);
- TransformVisitor::getInstance()->setCamera(g);
- }
- void Engine::render() {
- EM_COUT("Engine::render()", 0);
- if (GET_TIME - g_iLastRender != 0.0f) {
- m_fFps = m_fFps*0.9f + 0.1f*1000.0f/(GET_TIME - g_iLastRender);
- }
- g_iLastRender = GET_TIME;
-
- StartProfile(GLIGHT);
- AmbientLightVisitor::getInstance()->empty();
- this->accept(AmbientLightVisitor::getInstance());
- StopProfile();
-
- EM_COUT("Engine::render() lights", 0);
- StartProfile(PLIGHT);
-
-
- StopProfile();
-
- EM_COUT("Engine::render() align", 0);
- StartProfile(ALIGN);
- AlignVisitor::getInstance()->empty();
- this->accept(AlignVisitor::getInstance());
- StopProfile();
-
- StartProfile(SOUND);
-
-
- StopProfile();
- this->clearScreen();
-
- EM_COUT("Engine::render() render", 0);
- StartProfile(RENDER);
- #if EM_USE_SDL
- OpenGLVisitor::getInstance()->setMode(EM_GL_GCOL_TEX);
- OpenGLVisitor::getInstance()->empty();
- this->accept(OpenGLVisitor::getInstance());
- OpenGLVisitor::getInstance()->setMode(EM_GL_GCOL_TEX_TRANS);
- OpenGLVisitor::getInstance()->empty();
- this->accept(OpenGLVisitor::getInstance());
- OpenGLVisitor::getInstance()->setMode(EM_GL_CLEAN);
- OpenGLVisitor::getInstance()->empty();
- #endif
- #if EM_USE_ALLEGRO
- AllegroVisitor::getInstance()->setMode(EM_ALLEGRO_GCOL_TEX);
- AllegroVisitor::getInstance()->empty();
- this->accept(AllegroVisitor::getInstance());
- AllegroVisitor::getInstance()->setMode(EM_ALLEGRO_GCOL_TEX_TRANS);
- AllegroVisitor::getInstance()->empty();
- this->accept(AllegroVisitor::getInstance());
- AllegroVisitor::getInstance()->setMode(EM_GL_CLEAN);
- AllegroVisitor::getInstance()->empty();
- #endif
- StopProfile();
- }
- void Engine::swap() {
- StartProfile(SWAP);
- EM_COUT("Engine::swap()", 0);
- g_iLoops++;
-
- #if EM_USE_SDL
- SDL_GL_SwapBuffers();
- EM_GLERROR(" In Engine::swap ");
- #endif
- #if EM_USE_ALLEGRO
- blit(backbuffer, screen, 0, 0, 0, 0, Config::getInstance()->getWidth(), Config::getInstance()->getHeight());
- #endif
- StopProfile();
- }
- void Engine::tick() {
- EM_COUT("Engine::tick() key", 0);
- if (!Config::getInstance()->useExternGL()) {
- StartProfile(KEY);
-
- Keyboard::poll();
- StopProfile();
- }
-
- EM_COUT("Engine::tick() beh", 0);
- StartProfile(BEH);
- BehaviorVisitor::getInstance()->empty();
- this->accept(BehaviorVisitor::getInstance());
- StopProfile();
-
- EM_COUT("Engine::tick() trans", 0);
- StartProfile(TRANS);
- TransformVisitor::getInstance()->empty();
- this->accept(TransformVisitor::getInstance());
- StopProfile();
-
- EM_COUT("Engine::tick() coll", 0);
- StartProfile(COLLISION);
- CollisionVisitor::getInstance()->empty();
- this->accept(CollisionVisitor::getInstance());
- StopProfile();
-
- StartProfile(SIG);
- SignalSender::getInstance()->tick();
- StopProfile();
- }
- void Engine::delay(int ms) {
- #if EM_USE_SDL
- SDL_Delay(ms);
- #endif
- #if EM_USE_ALLEGRO
- rest(ms);
- #endif
- }
- bool Engine::nextTickFPS(int fps) {
-
- int delay = 10;
- if (fps > 0) {
- delay = 1000/fps;
- }
- if ((g_iStartTime + delay) <= GET_TIME) {
- g_iStartTime += delay;
- return true;
- }
- return false;
- }
- void Engine::resetTick() {
- g_iStartTime = GET_TIME;
- }
- #undef GET_TIME
- #if EM_THREADS
- volatile bool g_bThread = true;;
- SDL_mutex* g_Mutex = NULL;
- SDL_Thread* g_Thread = NULL;
- void Engine::renderThreadSafe() {
- this->pauseTickThread();
- EM_COUT("Engine::render()", 0);
-
- EM_COUT("Engine::render() glight", 0);
- AmbientLightVisitor::getInstance()->empty();
- this->accept(AmbientLightVisitor::getInstance());
-
-
- EM_COUT("Engine::render() align", 0);
- AlignVisitor::getInstance()->empty();
- this->accept(AlignVisitor::getInstance());
-
- EM_COUT("Engine::render() sound", 0);
-
-
- this->resumeTickThread();
- this->pauseTickThread();
-
- EM_COUT("Engine::render() opengl", 0);
- this->clearScreen();
- OpenGLVisitor::getInstance()->setMode(EM_GL_GCOL);
- OpenGLVisitor::getInstance()->empty();
- this->accept(OpenGLVisitor::getInstance());
- OpenGLVisitor::getInstance()->setMode(EM_GL_TEX);
- OpenGLVisitor::getInstance()->empty();
- this->accept(OpenGLVisitor::getInstance());
- this->resumeTickThread();
- this->pauseTickThread();
- OpenGLVisitor::getInstance()->setMode(EM_GL_GCOL_TRANS);
- OpenGLVisitor::getInstance()->empty();
- this->accept(OpenGLVisitor::getInstance());
- OpenGLVisitor::getInstance()->setMode(EM_GL_TEX_TRANS);
- OpenGLVisitor::getInstance()->empty();
- this->accept(OpenGLVisitor::getInstance());
- OpenGLVisitor::getInstance()->setMode(EM_GL_CLEAN);
- OpenGLVisitor::getInstance()->empty();
-
- EM_COUT("Engine::render() opengltrans", 0);
-
-
-
- Keyboard::poll();
- this->resumeTickThread();
- }
- int fctThread(void * data) {
- Engine* engine = (Engine*) data;
- while (g_bThread) {
-
- if (SDL_mutexP(g_Mutex) == -1) cerr << "Error locking mutex" << endl;
- EM_COUT("Engine::tick()", 0);
-
-
- EM_COUT("Engine::tick() signal", 0);
- SignalSender::getInstance()->tick();
-
-
- EM_COUT("Engine::tick() behavior", 0);
- BehaviorVisitor::getInstance()->empty();
- engine->accept(BehaviorVisitor::getInstance());
-
-
- EM_COUT("Engine::tick() trans", 0);
- TransformVisitor::getInstance()->empty();
- engine->accept(TransformVisitor::getInstance());
-
-
- EM_COUT("Engine::tick() collision", 0);
- CollisionVisitor::getInstance()->empty();
- engine->accept(CollisionVisitor::getInstance());
-
- if (SDL_mutexV(g_Mutex) == -1) cerr << "Error unlocking mutex" << endl;
- engine->limitFPS(100);
- }
- return 0;
- }
- void Engine::startTickThread() {
- g_bThread = true;
- if (g_Mutex == NULL) {
- g_Mutex = SDL_CreateMutex();
- } else {
- cerr << "Mutex already created" << endl;
- }
- if (g_Thread == NULL) {
- g_Thread = SDL_CreateThread(fctThread, this);
- } else {
- cerr << "Thread already created" << endl;
- }
- }
- void Engine::endTickThread() {
- int status;
- g_bThread = false;
- SDL_WaitThread(g_Thread, &status);
- SDL_DestroyMutex(g_Mutex);
- g_Thread = NULL;
- g_Mutex = NULL;
- }
- void Engine::pauseTickThread() {
- if (g_Mutex != NULL) {
- if (SDL_mutexP(g_Mutex) == -1) cerr << "Error unlocking mutex" << endl;
- }
- }
- void Engine::resumeTickThread() {
- if (g_Mutex != NULL) {
- if (SDL_mutexV(g_Mutex) == -1) cerr << "Error unlocking mutex" << endl;
- }
- sched_yield();
- }
- #endif
|