00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <iostream>
00024 #include <algorithm>
00025
00026
00027 #include <SDL.h>
00028 #include <SDL_ttf.h>
00029
00030
00031
00032
00033
00034 #include "util/base/exception.h"
00035 #include "util/log/logger.h"
00036 #include "util/time/timemanager.h"
00037 #include "audio/soundmanager.h"
00038 #include "gui/console/console.h"
00039 #include "gui/guimanager.h"
00040 #include "vfs/vfs.h"
00041 #include "vfs/vfsdirectory.h"
00042 #include "vfs/directoryprovider.h"
00043 #ifdef HAVE_ZIP
00044 #include "vfs/zip/zipprovider.h"
00045 #endif
00046 #include "eventchannel/eventmanager.h"
00047 #include "video/imagepool.h"
00048 #include "video/animationpool.h"
00049 #include "audio/soundclippool.h"
00050 #include "video/renderbackend.h"
00051 #include "video/cursor.h"
00052 #include "video/devicecaps.h"
00053 #ifdef HAVE_OPENGL
00054 #include "video/opengl/fife_opengl.h"
00055 #include "video/opengl/renderbackendopengl.h"
00056 #include "gui/base/opengl/opengl_gui_graphics.h"
00057 #endif
00058 #include "gui/base/sdl/sdl_gui_graphics.h"
00059 #include "gui/base/gui_font.h"
00060 #include "video/sdl/renderbackendsdl.h"
00061 #include "video/fonts/abstractfont.h"
00062 #include "loaders/native/video_loaders/subimage_loader.h"
00063 #include "loaders/native/video_loaders/image_loader.h"
00064 #include "loaders/native/audio_loaders/ogg_loader.h"
00065 #include "model/model.h"
00066 #include "pathfinder/routepather/routepather.h"
00067 #include "model/metamodel/grids/hexgrid.h"
00068 #include "model/metamodel/grids/squaregrid.h"
00069 #include "view/renderers/quadtreerenderer.h"
00070 #include "view/renderers/gridrenderer.h"
00071 #include "view/renderers/instancerenderer.h"
00072 #include "view/renderers/coordinaterenderer.h"
00073 #include "view/renderers/floatingtextrenderer.h"
00074 #include "view/renderers/cellselectionrenderer.h"
00075 #include "view/renderers/blockinginforenderer.h"
00076 #include "view/renderers/genericrenderer.h"
00077 #include "view/renderers/lightrenderer.h"
00078 #include "video/image.h"
00079 #include "gui/console/console.h"
00080 #include "engine.h"
00081
00082 #ifdef USE_COCOA
00083
00084 #include <objc/message.h>
00085 #include <dlfcn.h>
00086
00087 int main(int argc, char **argv)
00088 {
00089 return 0;
00090 }
00091 #endif
00092
00093 namespace FIFE {
00094 static Logger _log(LM_CONTROLLER);
00095
00096 Engine::Engine():
00097 m_renderbackend(0),
00098 m_guimanager(0),
00099 m_eventmanager(0),
00100 m_soundmanager(0),
00101 m_timemanager(0),
00102 m_imagepool(0),
00103 m_animpool(0),
00104 m_soundclippool(0),
00105 m_vfs(0),
00106 m_model(0),
00107 m_gui_graphics(0),
00108 m_logmanager(0),
00109 m_cursor(0),
00110 m_settings(),
00111 m_devcaps(),
00112 m_changelisteners() {
00113 #ifdef USE_COCOA
00114
00115
00116 void* cocoa_lib;
00117 cocoa_lib = dlopen( "/System/Library/Frameworks/Cocoa.framework/Cocoa", RTLD_LAZY );
00118 void (*nsappload)(void);
00119 nsappload = (void(*)()) dlsym( cocoa_lib, "NSApplicationLoad");
00120 nsappload();
00121
00122
00123 objc_object *NSAutoreleasePool = objc_getClass("NSAutoreleasePool");
00124 m_autoreleasePool =
00125 objc_msgSend(NSAutoreleasePool, sel_registerName("new"));
00126 #endif
00127 preInit();
00128 }
00129
00130 EngineSettings& Engine::getSettings() {
00131 return m_settings;
00132 }
00133
00134 const DeviceCaps& Engine::getDeviceCaps() const {
00135 return m_devcaps;
00136 }
00137
00138 Image* Engine::changeScreenMode(const ScreenMode& mode){
00139 m_cursor->invalidate();
00140 m_imagepool->invalidateLoadedImages();
00141 m_defaultfont->invalidate();
00142 m_guimanager->invalidateFonts();
00143
00144 Image* screen = m_renderbackend->setScreenMode(mode);
00145
00146 m_guimanager->resizeTopContainer(0,0,mode.getWidth(), mode.getHeight());
00147 m_guimanager->getConsole()->reLayout();
00148
00149 std::vector<IEngineChangeListener*>::iterator i = m_changelisteners.begin();
00150 while (i != m_changelisteners.end()) {
00151 (*i)->onScreenModeChanged(mode);
00152 ++i;
00153 }
00154
00155 return screen;
00156 }
00157
00158 void Engine::preInit() {
00159 m_logmanager = LogManager::instance();
00160
00161 FL_LOG(_log, "================== Engine pre-init start =================");
00162 m_timemanager = new TimeManager();
00163 FL_LOG(_log, "Time manager created");
00164
00165 FL_LOG(_log, "Creating VFS");
00166 m_vfs = new VFS();
00167
00168 FL_LOG(_log, "Adding root directory to VFS");
00169 m_vfs->addSource( new VFSDirectory(m_vfs) );
00170 m_vfs->addProvider( new DirectoryProvider() );
00171 #ifdef HAVE_ZIP
00172 FL_LOG(_log, "Adding zip provider to VFS");
00173 m_vfs->addProvider( new ZipProvider() );
00174 #endif
00175
00176
00177 FL_LOG(_log, "Engine pre-init done");
00178 m_destroyed = false;
00179 }
00180
00181 void Engine::init() {
00182 FL_LOG(_log, "Engine initialize start");
00183 m_settings.validate();
00184 FL_LOG(_log, "Engine settings validated");
00185
00186
00187 if (SDL_Init(SDL_INIT_NOPARACHUTE | SDL_INIT_TIMER) < 0) {
00188 throw SDLException(SDL_GetError());
00189 }
00190
00191 SDL_EnableUNICODE(1);
00192 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
00193 TTF_Init();
00194
00195 FL_LOG(_log, "Creating event manager");
00196 m_eventmanager = new EventManager();
00197
00198 FL_LOG(_log, "Creating pools");
00199 m_imagepool = new ImagePool();
00200 m_animpool = new AnimationPool();
00201 m_soundclippool = new SoundClipPool();
00202 m_imagepool->addResourceLoader(new SubImageLoader());
00203 m_imagepool->addResourceLoader(new ImageLoader(m_vfs));
00204 m_soundclippool->addResourceLoader(new OggLoader(m_vfs));
00205
00206 FL_LOG(_log, "Creating render backend");
00207 std::string rbackend(m_settings.getRenderBackend());
00208 if (rbackend == "SDL") {
00209 m_renderbackend = new RenderBackendSDL(m_settings.getColorKey());
00210 FL_LOG(_log, "SDL Render backend created");
00211 } else {
00212 #ifdef HAVE_OPENGL
00213 m_renderbackend = new RenderBackendOpenGL(m_settings.getColorKey());
00214 FL_LOG(_log, "OpenGL Render backend created");
00215 #else
00216 m_renderbackend = new RenderBackendSDL(m_settings.getColorKey());
00217
00218 rbackend = "SDL";
00219 FL_WARN(_log, "Tried to select OpenGL, even though it is not compiled into the engine. Falling back to SDL Render backend");
00220 #endif
00221 }
00222 FL_LOG(_log, "Initializing render backend");
00223 m_renderbackend->setColorKeyEnabled(m_settings.isColorKeyEnabled());
00224
00225 std::string driver = m_settings.getVideoDriver();
00226 std::vector<std::string> drivers = m_devcaps.getAvailableDrivers();
00227
00228 if (driver != ""){
00229 if (std::find (drivers.begin(), drivers.end(), driver) == drivers.end()) {
00230 FL_WARN(_log, "Selected driver is not supported for your Operating System! Reverting to default driver.");
00231 driver = "";
00232 }
00233 }
00234
00235 m_renderbackend->init(driver);
00236
00237 FL_LOG(_log, "Querying device capabilities");
00238 m_devcaps.fillDeviceCaps();
00239
00240 uint16_t bpp = m_settings.getBitsPerPixel();
00241
00242 m_screenMode = m_devcaps.getNearestScreenMode(
00243 m_settings.getScreenWidth(),
00244 m_settings.getScreenHeight(),
00245 bpp,
00246 rbackend,
00247 m_settings.isFullScreen());
00248
00249 FL_LOG(_log, "Creating main screen");
00250 m_renderbackend->createMainScreen(
00251 m_screenMode,
00252 m_settings.getWindowTitle(),
00253 m_settings.getWindowIcon());
00254 FL_LOG(_log, "Main screen created");
00255
00256 #ifdef HAVE_OPENGL
00257 if( rbackend != "SDL" ) {
00258 m_gui_graphics = new OpenGLGuiGraphics(*m_imagepool);
00259 }
00260
00261 if (m_settings.getLightingModel() != 0) {
00262 m_renderbackend->setLightingModel(m_settings.getLightingModel());
00263 }
00264
00265 #endif
00266 if( rbackend == "SDL" ) {
00267 m_gui_graphics = new SdlGuiGraphics(*m_imagepool);
00268 }
00269 FL_LOG(_log, "Constructing GUI manager");
00270 m_guimanager = new GUIManager(*m_imagepool);
00271 FL_LOG(_log, "Events bind to GUI manager");
00272 m_eventmanager->addSdlEventListener(m_guimanager);
00273
00274 FL_LOG(_log, "Creating default font");
00275 m_defaultfont = m_guimanager->setDefaultFont(
00276 m_settings.getDefaultFontPath(),
00277 m_settings.getDefaultFontSize(),
00278 m_settings.getDefaultFontGlyphs());
00279 FL_LOG(_log, "Initializing GUI manager");
00280 m_guimanager->init(m_gui_graphics, m_renderbackend->getScreenWidth(), m_renderbackend->getScreenHeight());
00281 FL_LOG(_log, "GUI manager initialized");
00282 SDL_EnableUNICODE(1);
00283
00284 FL_LOG(_log, "Creating sound manager");
00285 m_soundmanager = new SoundManager(m_soundclippool);
00286 m_soundmanager->setVolume(static_cast<float>(m_settings.getInitialVolume()) / 10);
00287
00288 FL_LOG(_log, "Creating renderers");
00289 m_renderers.push_back(new InstanceRenderer(m_renderbackend, 10, m_imagepool, m_animpool));
00290 m_renderers.push_back(new GridRenderer(m_renderbackend, 20));
00291 m_renderers.push_back(new CellSelectionRenderer(m_renderbackend, 30));
00292 m_renderers.push_back(new BlockingInfoRenderer(m_renderbackend, 40));
00293 m_renderers.push_back(new FloatingTextRenderer(m_renderbackend, 50, dynamic_cast<AbstractFont*>(m_defaultfont)));
00294 m_renderers.push_back(new QuadTreeRenderer(m_renderbackend, 60));
00295 m_renderers.push_back(new CoordinateRenderer(m_renderbackend, 70, dynamic_cast<AbstractFont*>(m_defaultfont)));
00296 m_renderers.push_back(new GenericRenderer(m_renderbackend, 80, m_imagepool, m_animpool));
00297 m_renderers.push_back(new LightRenderer(m_renderbackend, 90, m_imagepool, m_animpool));
00298
00299 FL_LOG(_log, "Creating model");
00300 m_model = new Model(m_renderbackend, m_renderers, m_imagepool, m_animpool);
00301 FL_LOG(_log, "Adding pathers to model");
00302 m_model->adoptPather(new RoutePather());
00303 FL_LOG(_log, "Adding grid prototypes to model");
00304 m_model->adoptCellGrid(new SquareGrid());
00305 m_model->adoptCellGrid(new HexGrid());
00306
00307 m_cursor = new Cursor(m_imagepool, m_animpool, m_renderbackend);
00308 FL_LOG(_log, "Engine intialized");
00309 }
00310
00311 Engine::~Engine() {
00312 if( !m_destroyed ) {
00313 destroy();
00314 }
00315 }
00316
00317 void Engine::destroy() {
00318 FL_LOG(_log, "Destructing engine");
00319 delete m_cursor;
00320 delete m_model;
00321 delete m_soundmanager;
00322 delete m_guimanager;
00323 delete m_gui_graphics;
00324
00325
00326
00327
00328 delete m_animpool;
00329 delete m_imagepool;
00330 delete m_eventmanager;
00331
00332
00333 std::vector<RendererBase*>::iterator rendererIter = m_renderers.begin();
00334 for ( ; rendererIter != m_renderers.end(); ++rendererIter)
00335 {
00336 delete *rendererIter;
00337 }
00338 m_renderers.clear();
00339
00340 m_renderbackend->deinit();
00341 delete m_renderbackend;
00342
00343 delete m_vfs;
00344
00345 delete m_timemanager;
00346
00347 TTF_Quit();
00348 SDL_Quit();
00349
00350 #ifdef USE_COCOA
00351 objc_msgSend(m_autoreleasePool, sel_registerName("release"));
00352 #endif
00353
00354 FL_LOG(_log, "================== Engine destructed ==================");
00355 m_destroyed = true;
00356
00357 }
00358 void Engine::initializePumping() {
00359 m_eventmanager->processEvents();
00360 }
00361
00362 void Engine::pump() {
00363 m_eventmanager->processEvents();
00364 m_renderbackend->startFrame();
00365 m_timemanager->update();
00366
00367 if (m_model->getNumMaps() == 0) {
00368 m_renderbackend->clearBackBuffer();
00369 }
00370
00371 m_model->update();
00372 #ifdef HAVE_OPENGL
00373 if (m_settings.getLightingModel() == 1) {
00374 m_renderbackend->disableLighting();
00375 }
00376 #endif
00377 m_guimanager->turn();
00378 m_cursor->draw();
00379 #ifdef HAVE_OPENGL
00380 if (m_settings.getLightingModel() == 1) {
00381 m_renderbackend->enableLighting();
00382 }
00383 #endif
00384 m_renderbackend->endFrame();
00385 }
00386
00387 void Engine::finalizePumping() {
00388
00389 }
00390
00391 void Engine::addChangeListener(IEngineChangeListener* listener) {
00392 m_changelisteners.push_back(listener);
00393 }
00394
00395 void Engine::removeChangeListener(IEngineChangeListener* listener) {
00396 std::vector<IEngineChangeListener*>::iterator i = m_changelisteners.begin();
00397 while (i != m_changelisteners.end()) {
00398 if ((*i) == listener) {
00399 m_changelisteners.erase(i);
00400 return;
00401 }
00402 ++i;
00403 }
00404 }
00405 }
00406
00407