FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator Pages
engine.cpp
1 /***************************************************************************
2  * Copyright (C) 2005-2008 by the FIFE team *
3  * http://www.fifengine.de *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20  ***************************************************************************/
21 
22 // Standard C++ library includes
23 #include <iostream>
24 #include <algorithm>
25 
26 // 3rd party library includes
27 #include <SDL.h>
28 #include <SDL_ttf.h>
29 
30 // FIFE includes
31 // These includes are split up in two parts, separated by one empty line
32 // First block: files included from the FIFE root src directory
33 // Second block: files included from the same folder
34 #include "util/base/exception.h"
35 #include "util/log/logger.h"
36 #include "util/time/timemanager.h"
37 #include "audio/soundmanager.h"
38 #include "gui/guimanager.h"
39 #include "vfs/vfs.h"
40 #include "vfs/vfsdirectory.h"
41 #include "vfs/directoryprovider.h"
42 #ifdef HAVE_ZIP
43 #include "vfs/zip/zipprovider.h"
44 #endif
45 #include "eventchannel/eventmanager.h"
46 #include "video/imagemanager.h"
47 #include "audio/soundclipmanager.h"
48 #include "video/renderbackend.h"
49 #include "video/cursor.h"
50 #include "video/devicecaps.h"
51 #ifdef HAVE_OPENGL
52 #include "video/opengl/fife_opengl.h"
53 #include "video/opengl/renderbackendopengl.h"
54 #include "video/opengle/renderbackendopengle.h"
55 #endif
56 #include "video/sdl/renderbackendsdl.h"
57 #include "loaders/native/video/imageloader.h"
58 #include "loaders/native/audio/ogg_loader.h"
59 #include "model/model.h"
60 #include "pathfinder/routepather/routepather.h"
61 #include "model/metamodel/grids/hexgrid.h"
62 #include "model/metamodel/grids/squaregrid.h"
63 #include "view/renderers/quadtreerenderer.h"
64 #include "view/renderers/gridrenderer.h"
65 #include "view/renderers/instancerenderer.h"
66 #include "view/renderers/coordinaterenderer.h"
67 #include "view/renderers/floatingtextrenderer.h"
68 #include "view/renderers/cellselectionrenderer.h"
69 #include "view/renderers/blockinginforenderer.h"
70 #include "view/renderers/genericrenderer.h"
71 #include "view/renderers/targetrenderer.h"
72 #include "view/renderers/lightrenderer.h"
73 #include "view/renderers/offrenderer.h"
74 #include "video/image.h"
75 #include "engine.h"
76 
77 #ifdef USE_COCOA
78 
79 #include <objc/message.h>
80 #include <dlfcn.h>
81 
82 int32_t main(int32_t argc, char **argv)
83 {
84  return 0;
85 }
86 #endif
87 
88 namespace FIFE {
89  static Logger _log(LM_CONTROLLER);
90 
92  m_renderbackend(0),
93  m_guimanager(0),
94  m_eventmanager(0),
95  m_soundmanager(0),
96  m_timemanager(0),
97  m_imagemanager(0),
98  m_soundclipmanager(0),
99  m_vfs(0),
100  m_model(0),
101  m_logmanager(0),
102  m_cursor(0),
103  m_settings(),
104  m_devcaps(),
105  m_offrenderer(0),
106  m_changelisteners() {
107 #ifdef USE_COCOA
108  // The next lines ensure that Cocoa is initialzed correctly.
109  // This is needed for SDL to function properly on MAC OS X.
110  void* cocoa_lib;
111  cocoa_lib = dlopen( "/System/Library/Frameworks/Cocoa.framework/Cocoa", RTLD_LAZY );
112  void (*nsappload)(void);
113  nsappload = (void(*)()) dlsym( cocoa_lib, "NSApplicationLoad");
114  nsappload();
115 
116  // Create an autorelease pool, so autoreleased SDL objects don't leak.
117  objc_object *NSAutoreleasePool = objc_getClass("NSAutoreleasePool");
118  m_autoreleasePool =
119  objc_msgSend(NSAutoreleasePool, sel_registerName("new"));
120 #endif
121  m_logmanager = LogManager::instance();
122  }
123 
125  return m_settings;
126  }
127 
128  const DeviceCaps& Engine::getDeviceCaps() const {
129  return m_devcaps;
130  }
131 
132  void Engine::changeScreenMode(const ScreenMode& mode){
133  m_cursor->invalidate();
134 
135  m_imagemanager->invalidateAll();
136 
137  m_renderbackend->setScreenMode(mode);
138 
139  if (m_guimanager) {
140  m_guimanager->resizeTopContainer(0,0,mode.getWidth(), mode.getHeight());
141  }
142 
143  std::vector<IEngineChangeListener*>::iterator i = m_changelisteners.begin();
144  while (i != m_changelisteners.end()) {
145  (*i)->onScreenModeChanged(mode);
146  ++i;
147  }
148  }
149 
150  void Engine::init() {
151  m_destroyed = false;
152 
153  FL_LOG(_log, "================== Engine initialize start =================");
154  m_timemanager = new TimeManager();
155  FL_LOG(_log, "Time manager created");
156 
157  FL_LOG(_log, "Creating VFS");
158  m_vfs = new VFS();
159 
160  FL_LOG(_log, "Adding root directory to VFS");
161  m_vfs->addSource( new VFSDirectory(m_vfs) );
162  m_vfs->addProvider( new DirectoryProvider() );
163 #ifdef HAVE_ZIP
164  FL_LOG(_log, "Adding zip provider to VFS");
165  m_vfs->addProvider( new ZipProvider() );
166 #endif
167  //m_vfs->addProvider(ProviderDAT2());
168  //m_vfs->addProvider(ProviderDAT1());
169  FL_LOG(_log, "Engine pre-init done");
170 
171  // If failed to init SDL throw exception.
172  if (SDL_Init(SDL_INIT_NOPARACHUTE | SDL_INIT_TIMER) < 0) {
173  throw SDLException(SDL_GetError());
174  }
175 
176  SDL_EnableUNICODE(1);
177  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
178  TTF_Init();
179 
180  FL_LOG(_log, "Creating event manager");
181  m_eventmanager = new EventManager();
182  m_eventmanager->setMouseSensitivity(m_settings.getMouseSensitivity());
183  m_eventmanager->setMouseAcceleration(m_settings.getMouseAcceleration());
184 
185  FL_LOG(_log, "Creating resource managers");
186 
187  m_imagemanager = new ImageManager();
188  m_soundclipmanager = new SoundClipManager();
189 
190  FL_LOG(_log, "Creating render backend");
191  std::string rbackend(m_settings.getRenderBackend());
192  if (rbackend == "SDL") {
193  m_renderbackend = new RenderBackendSDL(m_settings.getColorKey());
194  FL_LOG(_log, "SDL Render backend created");
195  } else {
196 #ifdef HAVE_OPENGL
197  if (rbackend == "OpenGLe") {
198  m_renderbackend = new RenderBackendOpenGLe(m_settings.getColorKey());
199  FL_LOG(_log, "OpenGLe Render backend created");
200  FL_LOG(_log, "This is highly experimental so bear in mind some features may not work/work correctly.");
201  } else {
202  m_renderbackend = new RenderBackendOpenGL(m_settings.getColorKey());
203  FL_LOG(_log, "OpenGL Render backend created");
204  }
205 #else
206  m_renderbackend = new RenderBackendSDL(m_settings.getColorKey());
207  // Remember the choice so we pick the right graphics class.
208  rbackend = "SDL";
209  FL_WARN(_log, "Tried to select OpenGL, even though it is not compiled into the engine. Falling back to SDL Render backend");
210 #endif
211  }
212  FL_LOG(_log, "Initializing render backend");
213  m_renderbackend->setColorKeyEnabled(m_settings.isColorKeyEnabled());
214  // we always set this to false
215  //m_renderbackend->setAlphaOptimizerEnabled(false);
216  m_renderbackend->setImageCompressingEnabled(m_settings.isGLCompressImages());
217  m_renderbackend->setFramebufferEnabled(m_settings.isGLUseFramebuffer());
218  m_renderbackend->setNPOTEnabled(m_settings.isGLUseNPOT());
219 
220  if (m_settings.isFrameLimitEnabled()) {
221  m_renderbackend->setFrameLimitEnabled(true);
222  m_renderbackend->setFrameLimit(m_settings.getFrameLimit());
223  }
224 
225  std::string driver = m_settings.getVideoDriver();
226  std::vector<std::string> drivers = m_devcaps.getAvailableDrivers();
227 
228  if (driver != ""){
229  if (std::find (drivers.begin(), drivers.end(), driver) == drivers.end()) {
230  FL_WARN(_log, "Selected driver is not supported for your Operating System! Reverting to default driver.");
231  driver = "";
232  }
233  }
234 
235  m_renderbackend->init(driver);
236 
237  FL_LOG(_log, "Querying device capabilities");
238  m_devcaps.fillDeviceCaps();
239 
240  uint16_t bpp = m_settings.getBitsPerPixel();
241 
242  m_screenMode = m_devcaps.getNearestScreenMode(
243  m_settings.getScreenWidth(),
244  m_settings.getScreenHeight(),
245  bpp,
246  rbackend,
247  m_settings.isFullScreen());
248 
249  FL_LOG(_log, "Creating main screen");
250  m_renderbackend->createMainScreen(
251  m_screenMode,
252  m_settings.getWindowTitle(),
253  m_settings.getWindowIcon());
254  FL_LOG(_log, "Main screen created");
255 
256 #ifdef HAVE_OPENGL
257  if (m_settings.getLightingModel() != 0) {
258  m_renderbackend->setLightingModel(m_settings.getLightingModel());
259  }
260 
261 #endif
262  SDL_EnableUNICODE(1);
263 
264  FL_LOG(_log, "Creating sound manager");
265  m_soundmanager = new SoundManager();
266  m_soundmanager->setVolume(static_cast<float>(m_settings.getInitialVolume()) / 10);
267 
268  FL_LOG(_log, "Creating renderers");
269  m_offrenderer = new OffRenderer(m_renderbackend);
270  m_targetrenderer = new TargetRenderer(m_renderbackend);
271  m_renderers.push_back(new InstanceRenderer(m_renderbackend, 10));
272  m_renderers.push_back(new GridRenderer(m_renderbackend, 20));
273  m_renderers.push_back(new CellSelectionRenderer(m_renderbackend, 30));
274  m_renderers.push_back(new BlockingInfoRenderer(m_renderbackend, 40));
275  m_renderers.push_back(new FloatingTextRenderer(m_renderbackend, 50));
276  m_renderers.push_back(new QuadTreeRenderer(m_renderbackend, 60));
277  m_renderers.push_back(new CoordinateRenderer(m_renderbackend, 70));
278  m_renderers.push_back(new GenericRenderer(m_renderbackend, 80));
279  m_renderers.push_back(new LightRenderer(m_renderbackend, 90));
280 
281  FL_LOG(_log, "Creating model");
282  m_model = new Model(m_renderbackend, m_renderers);
283  FL_LOG(_log, "Adding pathers to model");
284  m_model->adoptPather(new RoutePather());
285  FL_LOG(_log, "Adding grid prototypes to model");
286  m_model->adoptCellGrid(new SquareGrid());
287  m_model->adoptCellGrid(new HexGrid());
288 
289  m_cursor = new Cursor(m_renderbackend);
290  FL_LOG(_log, "Engine intialized");
291  }
292 
294  if( !m_destroyed ) {
295  destroy();
296  }
297  }
298 
300  FL_LOG(_log, "Destructing engine");
301  delete m_cursor;
302  delete m_model;
303  delete m_soundmanager;
304  delete m_guimanager;
305 
306  delete m_imagemanager;
307  delete m_soundclipmanager;
308 // delete m_eventmanager;
309 
310  // properly remove all the renderers created during init
311  delete m_offrenderer;
312  delete m_targetrenderer;
313  std::vector<RendererBase*>::iterator rendererIter = m_renderers.begin();
314  for ( ; rendererIter != m_renderers.end(); ++rendererIter)
315  {
316  delete *rendererIter;
317  }
318  m_renderers.clear();
319 
320  delete m_renderbackend;
321  delete m_vfs;
322  delete m_timemanager;
323 
324  TTF_Quit();
325  SDL_Quit();
326 
327 #ifdef USE_COCOA
328  objc_msgSend(m_autoreleasePool, sel_registerName("release"));
329 #endif
330 
331  FL_LOG(_log, "================== Engine destructed ==================");
332  m_destroyed = true;
333  //delete m_logmanager;
334  }
336  m_eventmanager->processEvents();
337  }
338 
339  void Engine::pump() {
340  m_renderbackend->startFrame();
341  m_eventmanager->processEvents();
342  m_timemanager->update();
343 
344  m_targetrenderer->render();
345  if (m_model->getMapCount() == 0) {
346  m_renderbackend->clearBackBuffer();
347  m_offrenderer->render();
348  } else {
349  m_model->update();
350  }
351 
352  if (m_guimanager) {
353  m_guimanager->turn();
354  }
355 
356  m_cursor->draw();
357  m_renderbackend->endFrame();
358  }
359 
361  // nothing here at the moment..
362  }
363 
364  void Engine::addChangeListener(IEngineChangeListener* listener) {
365  m_changelisteners.push_back(listener);
366  }
367 
368  void Engine::removeChangeListener(IEngineChangeListener* listener) {
369  std::vector<IEngineChangeListener*>::iterator i = m_changelisteners.begin();
370  while (i != m_changelisteners.end()) {
371  if ((*i) == listener) {
372  m_changelisteners.erase(i);
373  return;
374  }
375  ++i;
376  }
377  }
378 }//FIFE
379 
380 /* vim: set noexpandtab: set shiftwidth=2: set tabstop=2: */
void pump()
Definition: engine.cpp:339
bool getMouseAcceleration() const
void adoptCellGrid(CellGrid *grid)
Definition: model.cpp:92
void addProvider(VFSSourceProvider *provider)
Definition: vfs.cpp:64
void addChangeListener(IEngineChangeListener *listener)
Definition: engine.cpp:364
bool isColorKeyEnabled() const
void finalizePumping()
Definition: engine.cpp:360
void destroy()
Definition: engine.cpp:299
virtual void createMainScreen(const ScreenMode &mode, const std::string &title, const std::string &icon)=0
void update()
Definition: model.cpp:271
bool isFrameLimitEnabled() const
void setColorKeyEnabled(bool colorkeyenable)
void setFramebufferEnabled(bool enabled)
uint16_t getScreenHeight() const
virtual void init(const std::string &driver)=0
const SDL_Color & getColorKey() const
void initializePumping()
Definition: engine.cpp:335
virtual void clearBackBuffer()=0
const std::string & getWindowTitle() const
bool isGLUseNPOT() const
uint16_t getScreenWidth() const
void init()
Definition: engine.cpp:150
EngineSettings & getSettings()
Definition: engine.cpp:124
float getMouseSensitivity() const
bool isGLCompressImages() const
virtual void draw()
Definition: cursor.cpp:193
virtual void startFrame()
uint32_t getMapCount() const
Definition: model.cpp:131
void setFrameLimit(uint16_t framelimit)
void setNPOTEnabled(bool enabled)
float getInitialVolume() const
const DeviceCaps & getDeviceCaps() const
Definition: engine.cpp:128
void removeChangeListener(IEngineChangeListener *listener)
Definition: engine.cpp:368
const std::string & getRenderBackend() const
uint8_t getBitsPerPixel() const
void addSource(VFSSource *source)
Definition: vfs.cpp:108
virtual ~Engine()
Definition: engine.cpp:293
virtual void endFrame()
static LogManager * instance()
Definition: logger.cpp:65
uint16_t getFrameLimit() const
bool isGLUseFramebuffer() const
void setFrameLimitEnabled(bool limited)
Definition: vfs.h:58
bool isFullScreen() const
void adoptPather(IPather *pather)
Definition: model.cpp:77
uint32_t getLightingModel() const
void setMouseAcceleration(bool acceleration)
const std::string & getWindowIcon() const
void setMouseSensitivity(float sensitivity)
void setImageCompressingEnabled(bool enabled)
virtual void setScreenMode(const ScreenMode &mode)=0
virtual void setLightingModel(uint32_t lighting)=0
void changeScreenMode(const ScreenMode &mode)
Definition: engine.cpp:132