engine.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2008 by the FIFE team                              *
00003  *   http://www.fifengine.de                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 #include <iostream>
00024 
00025 // 3rd party library includes
00026 #include <SDL.h>
00027 #include <SDL_ttf.h>
00028 
00029 // FIFE includes
00030 // These includes are split up in two parts, separated by one empty line
00031 // First block: files included from the FIFE root src directory
00032 // Second block: files included from the same folder
00033 #include "util/base/exception.h"
00034 #include "util/log/logger.h"
00035 #include "util/time/timemanager.h"
00036 #include "audio/soundmanager.h"
00037 #include "gui/console/console.h"
00038 #include "gui/guimanager.h"
00039 #include "vfs/vfs.h"
00040 #include "vfs/vfsdirectory.h"
00041 #include "vfs/directoryprovider.h"
00042 #ifdef HAVE_ZIP
00043 #include "vfs/zip/zipprovider.h"
00044 #endif
00045 #include "eventchannel/eventmanager.h"
00046 #include "video/imagepool.h"
00047 #include "video/animationpool.h"
00048 #include "audio/soundclippool.h"
00049 #include "video/renderbackend.h"
00050 #include "video/cursor.h"
00051 #ifdef HAVE_OPENGL
00052 #include "video/opengl/renderbackendopengl.h"
00053 #include "gui/base/opengl/opengl_gui_graphics.h"
00054 #endif
00055 #include "gui/base/sdl/sdl_gui_graphics.h"
00056 #include "gui/base/gui_font.h"
00057 #include "video/sdl/renderbackendsdl.h"
00058 #include "video/fonts/abstractfont.h"
00059 #include "loaders/native/video_loaders/subimage_loader.h"
00060 #include "loaders/native/video_loaders/image_loader.h"
00061 #include "loaders/native/audio_loaders/ogg_loader.h"
00062 #include "model/model.h"
00063 #include "pathfinder/routepather/routepather.h"
00064 #include "model/metamodel/grids/hexgrid.h"
00065 #include "model/metamodel/grids/squaregrid.h"
00066 #include "view/renderers/camerazonerenderer.h"
00067 #include "view/renderers/quadtreerenderer.h"
00068 #include "view/renderers/gridrenderer.h"
00069 #include "view/renderers/instancerenderer.h"
00070 #include "view/renderers/coordinaterenderer.h"
00071 #include "view/renderers/floatingtextrenderer.h"
00072 #include "view/renderers/cellselectionrenderer.h"
00073 #include "view/renderers/blockinginforenderer.h"
00074 #include "view/renderers/genericrenderer.h"
00075 #include "engine.h"
00076 
00077 #ifdef USE_COCOA
00078 
00079 #include <objc/message.h>
00080 #include <dlfcn.h>
00081 
00082 int main(int argc, char **argv)
00083 {
00084     return 0;
00085 }
00086 #endif
00087 
00088 namespace FIFE {
00089     static Logger _log(LM_CONTROLLER);
00090 
00091     Engine::Engine():
00092         m_renderbackend(0),
00093         m_guimanager(0),
00094         m_eventmanager(0),
00095         m_soundmanager(0),
00096         m_timemanager(0),
00097         m_imagepool(0),
00098         m_animpool(0),
00099         m_soundclippool(0),
00100         m_vfs(0),
00101         m_model(0),
00102         m_gui_graphics(0),
00103         m_logmanager(0),
00104         m_cursor(0),
00105         m_settings() {
00106 #ifdef USE_COCOA
00107         // The next lines ensure that Cocoa is initialzed correctly.
00108         // This is needed for SDL to function properly on MAC OS X.
00109         void* cocoa_lib;
00110         cocoa_lib = dlopen( "/System/Library/Frameworks/Cocoa.framework/Cocoa", RTLD_LAZY );
00111         void (*nsappload)(void);
00112         nsappload = (void(*)()) dlsym( cocoa_lib, "NSApplicationLoad");
00113         nsappload();
00114 
00115         // Create an autorelease pool, so autoreleased SDL objects don't leak.
00116         objc_object *NSAutoreleasePool = objc_getClass("NSAutoreleasePool");
00117         m_autoreleasePool =
00118             objc_msgSend(NSAutoreleasePool, sel_registerName("new"));
00119 #endif
00120         preInit();
00121     }
00122 
00123     EngineSettings& Engine::getSettings() {
00124         return m_settings;
00125     }
00126 
00127     void Engine::preInit() {
00128         m_logmanager = LogManager::instance();
00129 
00130         FL_LOG(_log, "================== Engine pre-init start =================");
00131         m_timemanager = new TimeManager();
00132         FL_LOG(_log, "Time manager created");
00133 
00134         FL_LOG(_log, "Creating VFS");
00135         m_vfs = new VFS();
00136 
00137         FL_LOG(_log, "Adding root directory to VFS");
00138         m_vfs->addSource( new VFSDirectory(m_vfs) );
00139         m_vfs->addProvider( new DirectoryProvider() );
00140 #ifdef HAVE_ZIP
00141         FL_LOG(_log, "Adding zip provider to VFS");
00142         m_vfs->addProvider( new ZipProvider() );
00143 #endif
00144         //m_vfs->addProvider(ProviderDAT2());
00145         //m_vfs->addProvider(ProviderDAT1());
00146         FL_LOG(_log, "Engine pre-init done");
00147         m_destroyed = false;
00148     }
00149 
00150     void Engine::init() {
00151         FL_LOG(_log, "Engine initialize start");
00152         m_settings.validate();
00153         FL_LOG(_log, "Engine settings validated");
00154 
00155         // If failed to init SDL throw exception.
00156         if (SDL_Init(SDL_INIT_NOPARACHUTE | SDL_INIT_TIMER) < 0) {
00157             throw SDLException(SDL_GetError());
00158         }
00159 
00160         SDL_EnableUNICODE(1);
00161         SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
00162         TTF_Init();
00163 
00164         FL_LOG(_log, "Creating event manager");
00165         m_eventmanager = new EventManager();
00166 
00167         FL_LOG(_log, "Creating pools");
00168         m_imagepool = new ImagePool();
00169         m_animpool = new AnimationPool();
00170         m_soundclippool = new SoundClipPool();
00171         m_imagepool->addResourceLoader(new SubImageLoader());
00172         m_imagepool->addResourceLoader(new ImageLoader(m_vfs));
00173         m_soundclippool->addResourceLoader(new OggLoader(m_vfs));
00174 
00175         FL_LOG(_log, "Creating render backend");
00176         std::string rbackend(m_settings.getRenderBackend());
00177         if (rbackend == "SDL") {
00178             m_renderbackend = new RenderBackendSDL(m_settings.getColorKey());
00179             FL_LOG(_log, "SDL Render backend created");
00180         } else {
00181 #ifdef HAVE_OPENGL
00182             m_renderbackend = new RenderBackendOpenGL(m_settings.getColorKey());
00183             FL_LOG(_log, "OpenGL Render backend created");
00184 #else
00185             m_renderbackend = new RenderBackendSDL(m_settings.getColorKey());
00186             // Remember  the choice so we pick the right graphics class.
00187             rbackend = "SDL";
00188             FL_WARN(_log, "Tried to select OpenGL, even though it is not compiled into the engine. Falling back to SDL Render backend");
00189 #endif
00190         }
00191         FL_LOG(_log, "Initializing render backend");
00192         m_renderbackend->setChunkingSize(m_settings.getImageChunkingSize());
00193         m_renderbackend->setColorKeyEnabled(m_settings.isColorKeyEnabled());
00194         m_renderbackend->init();
00195 
00196         FL_LOG(_log, "Creating main screen");
00197         m_renderbackend->createMainScreen(
00198             m_settings.getScreenWidth(),
00199             m_settings.getScreenHeight(),
00200             static_cast<unsigned char>(m_settings.getBitsPerPixel()),
00201             m_settings.isFullScreen(),
00202             m_settings.getWindowTitle(),
00203             m_settings.getWindowIcon());
00204         FL_LOG(_log, "Main screen created");
00205 
00206 #ifdef HAVE_OPENGL
00207         if( rbackend != "SDL" ) {
00208             m_gui_graphics = new OpenGLGuiGraphics(*m_imagepool);
00209         }
00210 #endif
00211         if( rbackend == "SDL" ) {
00212             m_gui_graphics = new SdlGuiGraphics(*m_imagepool);
00213         }
00214         FL_LOG(_log, "Constructing GUI manager");
00215         m_guimanager = new GUIManager(*m_imagepool);
00216         FL_LOG(_log, "Events bind to GUI manager");
00217         m_eventmanager->addSdlEventListener(m_guimanager);
00218 
00219         FL_LOG(_log, "Creating default font");
00220         m_defaultfont = m_guimanager->setDefaultFont(
00221             m_settings.getDefaultFontPath(),
00222             m_settings.getDefaultFontSize(),
00223             m_settings.getDefaultFontGlyphs());
00224         FL_LOG(_log, "Initializing GUI manager");
00225         m_guimanager->init(m_gui_graphics, m_settings.getScreenWidth(), m_settings.getScreenHeight());
00226         FL_LOG(_log, "GUI manager initialized");
00227         SDL_EnableUNICODE(1);
00228 
00229         FL_LOG(_log, "Creating sound manager");
00230         m_soundmanager = new SoundManager(m_soundclippool);
00231         m_soundmanager->setVolume(static_cast<float>(m_settings.getInitialVolume()) / 10);
00232 
00233         FL_LOG(_log, "Creating renderers");
00234         m_renderers.push_back(new CameraZoneRenderer(m_renderbackend, 0, m_imagepool));
00235         m_renderers.push_back(new InstanceRenderer(m_renderbackend, 10, m_imagepool, m_animpool));
00236         m_renderers.push_back(new GridRenderer(m_renderbackend, 20));
00237         m_renderers.push_back(new CellSelectionRenderer(m_renderbackend, 30));
00238         m_renderers.push_back(new BlockingInfoRenderer(m_renderbackend, 40));
00239         m_renderers.push_back(new FloatingTextRenderer(m_renderbackend, 50, dynamic_cast<AbstractFont*>(m_defaultfont)));
00240         m_renderers.push_back(new QuadTreeRenderer(m_renderbackend, 60));
00241         m_renderers.push_back(new CoordinateRenderer(m_renderbackend, 70, dynamic_cast<AbstractFont*>(m_defaultfont)));
00242         m_renderers.push_back(new GenericRenderer(m_renderbackend, 80, m_imagepool, m_animpool));
00243 
00244         FL_LOG(_log, "Creating model");
00245         m_model = new Model(m_renderbackend, m_renderers, m_imagepool, m_animpool);
00246         FL_LOG(_log, "Adding pathers to model");
00247         m_model->adoptPather(new RoutePather());
00248         FL_LOG(_log, "Adding grid prototypes to model");
00249         m_model->adoptCellGrid(new SquareGrid());
00250         m_model->adoptCellGrid(new HexGrid());
00251 
00252         m_cursor = new Cursor(m_imagepool, m_animpool, m_renderbackend);
00253         FL_LOG(_log, "Engine intialized");
00254     }
00255 
00256     Engine::~Engine() {
00257         if( !m_destroyed ) {
00258             destroy();
00259         }
00260     }
00261 
00262     void Engine::destroy() {
00263         FL_LOG(_log, "Destructing engine");
00264         delete m_cursor;
00265         delete m_model;
00266         delete m_soundmanager;
00267         delete m_guimanager;
00268         delete m_gui_graphics;
00269 
00270         // Note the dependancy between image and animation pools
00271         // as animations reference images they have to be deleted
00272         // before clearing the image pool.
00273         delete m_animpool;
00274         delete m_imagepool;
00275         delete m_eventmanager;
00276 
00277         // properly remove all the renderers created during init
00278         std::vector<RendererBase*>::iterator rendererIter = m_renderers.begin();
00279         for ( ; rendererIter != m_renderers.end(); ++rendererIter)
00280         {
00281             delete *rendererIter;
00282         }
00283         m_renderers.clear();
00284 
00285         m_renderbackend->deinit();
00286         delete m_renderbackend;
00287 
00288         delete m_vfs;
00289 
00290         delete m_timemanager;
00291 
00292         TTF_Quit();
00293         SDL_Quit();
00294 #ifdef USE_COCOA
00295         objc_msgSend(m_autoreleasePool, sel_registerName("release"));
00296 #endif
00297         FL_LOG(_log, "================== Engine destructed ==================");
00298         m_destroyed = true;
00299         //delete m_logmanager;
00300     }
00301     void Engine::initializePumping() {
00302         m_eventmanager->processEvents();
00303     }
00304 
00305     void Engine::pump() {
00306         m_eventmanager->processEvents();
00307         m_renderbackend->startFrame();
00308         m_timemanager->update();
00309         m_model->update();
00310         m_guimanager->turn();
00311         m_cursor->draw();
00312         m_renderbackend->endFrame();
00313     }
00314 
00315     void Engine::finalizePumping() {
00316         // nothing here at the moment..
00317     }
00318 }//FIFE
00319 
00320 /* vim: set noexpandtab: set shiftwidth=2: set tabstop=2: */
Generated by  doxygen 1.6.2-20100208