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/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/imagemanager.h"
00047 #include "audio/soundclipmanager.h"
00048 #include "video/renderbackend.h"
00049 #include "video/cursor.h"
00050 #include "video/devicecaps.h"
00051 #ifdef HAVE_OPENGL
00052 #include "video/opengl/fife_opengl.h"
00053 #include "video/opengl/renderbackendopengl.h"
00054 #include "video/opengle/renderbackendopengle.h"
00055 #endif
00056 #include "video/sdl/renderbackendsdl.h"
00057 #include "loaders/native/video/imageloader.h"
00058 #include "loaders/native/audio/ogg_loader.h"
00059 #include "model/model.h"
00060 #include "pathfinder/routepather/routepather.h"
00061 #include "model/metamodel/grids/hexgrid.h"
00062 #include "model/metamodel/grids/squaregrid.h"
00063 #include "view/renderers/quadtreerenderer.h"
00064 #include "view/renderers/gridrenderer.h"
00065 #include "view/renderers/instancerenderer.h"
00066 #include "view/renderers/coordinaterenderer.h"
00067 #include "view/renderers/floatingtextrenderer.h"
00068 #include "view/renderers/cellselectionrenderer.h"
00069 #include "view/renderers/blockinginforenderer.h"
00070 #include "view/renderers/genericrenderer.h"
00071 #include "view/renderers/targetrenderer.h"
00072 #include "view/renderers/lightrenderer.h"
00073 #include "view/renderers/offrenderer.h"
00074 #include "video/image.h"
00075 #include "engine.h"
00076
00077 #ifdef USE_COCOA
00078
00079 #include <objc/message.h>
00080 #include <dlfcn.h>
00081
00082 int32_t main(int32_t 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_imagemanager(0),
00098 m_soundclipmanager(0),
00099 m_vfs(0),
00100 m_model(0),
00101 m_logmanager(0),
00102 m_cursor(0),
00103 m_settings(),
00104 m_devcaps(),
00105 m_offrenderer(0),
00106 m_changelisteners() {
00107 #ifdef USE_COCOA
00108
00109
00110 void* cocoa_lib;
00111 cocoa_lib = dlopen( "/System/Library/Frameworks/Cocoa.framework/Cocoa", RTLD_LAZY );
00112 void (*nsappload)(void);
00113 nsappload = (void(*)()) dlsym( cocoa_lib, "NSApplicationLoad");
00114 nsappload();
00115
00116
00117 objc_object *NSAutoreleasePool = objc_getClass("NSAutoreleasePool");
00118 m_autoreleasePool =
00119 objc_msgSend(NSAutoreleasePool, sel_registerName("new"));
00120 #endif
00121 m_logmanager = LogManager::instance();
00122 }
00123
00124 EngineSettings& Engine::getSettings() {
00125 return m_settings;
00126 }
00127
00128 const DeviceCaps& Engine::getDeviceCaps() const {
00129 return m_devcaps;
00130 }
00131
00132 void Engine::changeScreenMode(const ScreenMode& mode){
00133 m_cursor->invalidate();
00134
00135 m_imagemanager->invalidateAll();
00136
00137 m_renderbackend->setScreenMode(mode);
00138
00139 if (m_guimanager) {
00140 m_guimanager->resizeTopContainer(0,0,mode.getWidth(), mode.getHeight());
00141 }
00142
00143 std::vector<IEngineChangeListener*>::iterator i = m_changelisteners.begin();
00144 while (i != m_changelisteners.end()) {
00145 (*i)->onScreenModeChanged(mode);
00146 ++i;
00147 }
00148 }
00149
00150 void Engine::init() {
00151 m_destroyed = false;
00152
00153 FL_LOG(_log, "================== Engine initialize start =================");
00154 m_timemanager = new TimeManager();
00155 FL_LOG(_log, "Time manager created");
00156
00157 FL_LOG(_log, "Creating VFS");
00158 m_vfs = new VFS();
00159
00160 FL_LOG(_log, "Adding root directory to VFS");
00161 m_vfs->addSource( new VFSDirectory(m_vfs) );
00162 m_vfs->addProvider( new DirectoryProvider() );
00163 #ifdef HAVE_ZIP
00164 FL_LOG(_log, "Adding zip provider to VFS");
00165 m_vfs->addProvider( new ZipProvider() );
00166 #endif
00167
00168
00169 FL_LOG(_log, "Engine pre-init done");
00170
00171
00172 if (SDL_Init(SDL_INIT_NOPARACHUTE | SDL_INIT_TIMER) < 0) {
00173 throw SDLException(SDL_GetError());
00174 }
00175
00176 SDL_EnableUNICODE(1);
00177 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
00178 TTF_Init();
00179
00180 FL_LOG(_log, "Creating event manager");
00181 m_eventmanager = new EventManager();
00182 m_eventmanager->setMouseSensitivity(m_settings.getMouseSensitivity());
00183 m_eventmanager->setMouseAcceleration(m_settings.getMouseAcceleration());
00184
00185 FL_LOG(_log, "Creating resource managers");
00186
00187 m_imagemanager = new ImageManager();
00188 m_soundclipmanager = new SoundClipManager();
00189
00190 FL_LOG(_log, "Creating render backend");
00191 std::string rbackend(m_settings.getRenderBackend());
00192 if (rbackend == "SDL") {
00193 m_renderbackend = new RenderBackendSDL(m_settings.getColorKey());
00194 FL_LOG(_log, "SDL Render backend created");
00195 } else {
00196 #ifdef HAVE_OPENGL
00197 if (rbackend == "OpenGLe") {
00198 m_renderbackend = new RenderBackendOpenGLe(m_settings.getColorKey());
00199 FL_LOG(_log, "OpenGLe Render backend created");
00200 FL_LOG(_log, "This is highly experimental so bear in mind some features may not work/work correctly.");
00201 } else {
00202 m_renderbackend = new RenderBackendOpenGL(m_settings.getColorKey());
00203 FL_LOG(_log, "OpenGL Render backend created");
00204 }
00205 #else
00206 m_renderbackend = new RenderBackendSDL(m_settings.getColorKey());
00207
00208 rbackend = "SDL";
00209 FL_WARN(_log, "Tried to select OpenGL, even though it is not compiled into the engine. Falling back to SDL Render backend");
00210 #endif
00211 }
00212 FL_LOG(_log, "Initializing render backend");
00213 m_renderbackend->setColorKeyEnabled(m_settings.isColorKeyEnabled());
00214
00215
00216 m_renderbackend->setImageCompressingEnabled(m_settings.isGLCompressImages());
00217 m_renderbackend->setFramebufferEnabled(m_settings.isGLUseFramebuffer());
00218 m_renderbackend->setNPOTEnabled(m_settings.isGLUseNPOT());
00219
00220 if (m_settings.isFrameLimitEnabled()) {
00221 m_renderbackend->setFrameLimitEnabled(true);
00222 m_renderbackend->setFrameLimit(m_settings.getFrameLimit());
00223 }
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 (m_settings.getLightingModel() != 0) {
00258 m_renderbackend->setLightingModel(m_settings.getLightingModel());
00259 }
00260
00261 #endif
00262 SDL_EnableUNICODE(1);
00263
00264 FL_LOG(_log, "Creating sound manager");
00265 m_soundmanager = new SoundManager();
00266 m_soundmanager->setVolume(static_cast<float>(m_settings.getInitialVolume()) / 10);
00267
00268 FL_LOG(_log, "Creating renderers");
00269 m_offrenderer = new OffRenderer(m_renderbackend);
00270 m_targetrenderer = new TargetRenderer(m_renderbackend);
00271 m_renderers.push_back(new InstanceRenderer(m_renderbackend, 10));
00272 m_renderers.push_back(new GridRenderer(m_renderbackend, 20));
00273 m_renderers.push_back(new CellSelectionRenderer(m_renderbackend, 30));
00274 m_renderers.push_back(new BlockingInfoRenderer(m_renderbackend, 40));
00275 m_renderers.push_back(new FloatingTextRenderer(m_renderbackend, 50));
00276 m_renderers.push_back(new QuadTreeRenderer(m_renderbackend, 60));
00277 m_renderers.push_back(new CoordinateRenderer(m_renderbackend, 70));
00278 m_renderers.push_back(new GenericRenderer(m_renderbackend, 80));
00279 m_renderers.push_back(new LightRenderer(m_renderbackend, 90));
00280
00281 FL_LOG(_log, "Creating model");
00282 m_model = new Model(m_renderbackend, m_renderers);
00283 FL_LOG(_log, "Adding pathers to model");
00284 m_model->adoptPather(new RoutePather());
00285 FL_LOG(_log, "Adding grid prototypes to model");
00286 m_model->adoptCellGrid(new SquareGrid());
00287 m_model->adoptCellGrid(new HexGrid());
00288
00289 m_cursor = new Cursor(m_renderbackend);
00290 FL_LOG(_log, "Engine intialized");
00291 }
00292
00293 Engine::~Engine() {
00294 if( !m_destroyed ) {
00295 destroy();
00296 }
00297 }
00298
00299 void Engine::destroy() {
00300 FL_LOG(_log, "Destructing engine");
00301 delete m_cursor;
00302 delete m_model;
00303 delete m_soundmanager;
00304 delete m_guimanager;
00305
00306 delete m_imagemanager;
00307 delete m_soundclipmanager;
00308
00309
00310
00311 delete m_offrenderer;
00312 delete m_targetrenderer;
00313 std::vector<RendererBase*>::iterator rendererIter = m_renderers.begin();
00314 for ( ; rendererIter != m_renderers.end(); ++rendererIter)
00315 {
00316 delete *rendererIter;
00317 }
00318 m_renderers.clear();
00319
00320 delete m_renderbackend;
00321 delete m_vfs;
00322 delete m_timemanager;
00323
00324 TTF_Quit();
00325 SDL_Quit();
00326
00327 #ifdef USE_COCOA
00328 objc_msgSend(m_autoreleasePool, sel_registerName("release"));
00329 #endif
00330
00331 FL_LOG(_log, "================== Engine destructed ==================");
00332 m_destroyed = true;
00333
00334 }
00335 void Engine::initializePumping() {
00336 m_eventmanager->processEvents();
00337 }
00338
00339 void Engine::pump() {
00340 m_renderbackend->startFrame();
00341 m_eventmanager->processEvents();
00342 m_timemanager->update();
00343
00344 m_targetrenderer->render();
00345 if (m_model->getMapCount() == 0) {
00346 m_renderbackend->clearBackBuffer();
00347 m_offrenderer->render();
00348 } else {
00349 m_model->update();
00350 }
00351
00352 if (m_guimanager) {
00353 m_guimanager->turn();
00354 }
00355
00356 m_cursor->draw();
00357 m_renderbackend->endFrame();
00358 }
00359
00360 void Engine::finalizePumping() {
00361
00362 }
00363
00364 void Engine::addChangeListener(IEngineChangeListener* listener) {
00365 m_changelisteners.push_back(listener);
00366 }
00367
00368 void Engine::removeChangeListener(IEngineChangeListener* listener) {
00369 std::vector<IEngineChangeListener*>::iterator i = m_changelisteners.begin();
00370 while (i != m_changelisteners.end()) {
00371 if ((*i) == listener) {
00372 m_changelisteners.erase(i);
00373 return;
00374 }
00375 ++i;
00376 }
00377 }
00378 }
00379
00380