changeset 661:e3140f01749d

* Merged the light branch back into trunk. * Modified the demos so they work with the new loaders and setting.
author helios2000@33b003aa-7bff-0310-803a-e67f0ece8222
date Fri, 05 Nov 2010 15:21:10 +0000
parents b0733d998d0f
children 1ed5b5a0e7e3
files demos/pychan_demo/settings-dist.xml demos/rio_de_hola/misc/infotext.txt demos/rio_de_hola/scripts/world.py demos/rio_de_hola/settings-dist.xml demos/rpg/scripts/gamecontroller.py demos/rpg/scripts/scene.py demos/rpg/settings-dist.xml demos/shooter/gui/highscores.xml demos/shooter/scripts/world.py demos/shooter/settings-dist.xml engine/core/controller/engine.cpp engine/core/controller/engine.i engine/core/controller/enginesettings.cpp engine/core/controller/enginesettings.h engine/core/video/animation.cpp engine/core/video/image.h engine/core/video/opengl/fife_opengl.h engine/core/video/opengl/glimage.cpp engine/core/video/opengl/glimage.h engine/core/video/opengl/renderbackendopengl.cpp engine/core/video/opengl/renderbackendopengl.h engine/core/video/renderbackend.h engine/core/video/sdl/renderbackendsdl.cpp engine/core/video/sdl/renderbackendsdl.h engine/core/video/sdl/sdlimage.cpp engine/core/video/sdl/sdlimage.h engine/core/video/video.i engine/core/view/camera.cpp engine/core/view/camera.h engine/core/view/camera.i engine/core/view/rendererbase.i engine/core/view/renderers/cellselectionrenderer.cpp engine/core/view/renderers/floatingtextrenderer.cpp engine/core/view/renderers/floatingtextrenderer.h engine/core/view/renderers/genericrenderer.cpp engine/core/view/renderers/genericrenderer.h engine/core/view/renderers/genericrenderer.i engine/core/view/renderers/gridrenderer.cpp engine/core/view/renderers/instancerenderer.cpp engine/core/view/renderers/instancerenderer.h engine/core/view/renderers/instancerenderer.i engine/core/view/renderers/lightrenderer.cpp engine/core/view/renderers/lightrenderer.h engine/core/view/renderers/lightrenderer.i engine/core/view/renderers/quadtreerenderer.cpp engine/core/view/visual.h engine/python/fife/extensions/basicapplication.py engine/python/fife/extensions/fife_settings.py engine/python/fife/extensions/loaders.py engine/python/fife/extensions/savers.py engine/python/fife/extensions/serializers/__init__.py engine/python/fife/extensions/serializers/xml_loader_tools.py engine/python/fife/extensions/serializers/xmlanimation.py engine/python/fife/extensions/serializers/xmlmap.py engine/python/fife/extensions/serializers/xmlobject.py
diffstat 55 files changed, 2674 insertions(+), 261 deletions(-) [+]
line wrap: on
line diff
--- a/demos/pychan_demo/settings-dist.xml	Wed Nov 03 13:44:12 2010 +0000
+++ b/demos/pychan_demo/settings-dist.xml	Fri Nov 05 15:21:10 2010 +0000
@@ -1,24 +1,25 @@
-<?xml version='1.0' encoding='UTF-8'?>
-<Settings>
-	<Module name="FIFE">
+<?xml version='1.0' encoding='UTF-8'?>
+<Settings>
+	<Module name="FIFE">
 		<Setting name="FullScreen" type="bool"> False </Setting>
 		<Setting name="PlaySounds" type="bool"> True </Setting>
 		<Setting name="RenderBackend" type="str"> OpenGL </Setting>
 		<Setting name="ScreenResolution" type="str">1024x768</Setting>
-		<Setting name="BitsPerPixel" type="int"> 0 </Setting>
-		<Setting name="InitialVolume" type="float"> 5.0 </Setting>
-		<Setting name="SDLRemoveFakeAlpha" type="int"> 1 </Setting>
-		<Setting name="WindowTitle" type="str"> Pychan demo [FIFE Client] </Setting>
-		<Setting name="WindowIcon" type="str"> gui/icons/pychan_logo.png </Setting>
-		<Setting name="Font" type="str"> fonts/freefont/FreeMono.ttf </Setting>
-		<Setting name="FontGlyphs" strip="0" type="str"> abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&amp;`'*#=[]\"</Setting>
-		<Setting name="DefaultFontSize" type="int"> 16 </Setting>
-		<Setting name="LogModules" type="list"> controller ; GUI </Setting>
-		<Setting name="PychanDebug" type="bool"> True </Setting>
-		<Setting name="LogToPrompt" type="int"> 1 </Setting>
-		<Setting name="LogToFile" type="int"> 0 </Setting>
-		<Setting name="ColorKeyEnabled" type="bool"> False </Setting>
-		<Setting name="ColorKey" type="string"> 255,0,255 </Setting>
-	</Module>
-
+		<Setting name="BitsPerPixel" type="int"> 0 </Setting>
+		<Setting name="InitialVolume" type="float"> 5.0 </Setting>
+		<Setting name="SDLRemoveFakeAlpha" type="int"> 1 </Setting>
+		<Setting name="WindowTitle" type="str"> Pychan demo [FIFE Client] </Setting>
+		<Setting name="WindowIcon" type="str"> gui/icons/pychan_logo.png </Setting>
+		<Setting name="Font" type="str"> fonts/freefont/FreeMono.ttf </Setting>
+		<Setting name="FontGlyphs" strip="0" type="str"> abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&amp;`'*#=[]\"</Setting>
+		<Setting name="DefaultFontSize" type="int"> 16 </Setting>
+		<Setting name="LogModules" type="list"> controller ; GUI </Setting>
+		<Setting name="PychanDebug" type="bool"> True </Setting>
+		<Setting name="LogToPrompt" type="int"> 1 </Setting>
+		<Setting name="LogToFile" type="int"> 0 </Setting>
+		<Setting name="ColorKeyEnabled" type="bool"> False </Setting>
+		<Setting name="ColorKey" type="string"> 255,0,255 </Setting>
+    <Setting name="Lighting" type="int"> 0 </Setting>
+	</Module>
+
 </Settings>
\ No newline at end of file
--- a/demos/rio_de_hola/misc/infotext.txt	Wed Nov 03 13:44:12 2010 +0000
+++ b/demos/rio_de_hola/misc/infotext.txt	Fri Nov 05 15:21:10 2010 +0000
@@ -11,6 +11,8 @@
 - R = Reload map (useful for map editing)
 - S = Second camera on / off
 - O = Rotate main camera
+- 1,2 = Change global light intensity
+- 3,4 = Change light source intensity
 
 Have fun,
 The FIFE team
--- a/demos/rio_de_hola/scripts/world.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/demos/rio_de_hola/scripts/world.py	Fri Nov 05 15:21:10 2010 +0000
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 
 # ####################################################################
-#  Copyright (C) 2005-2009 by the FIFE team
+#  Copyright (C) 2005-2010 by the FIFE team
 #  http://www.fifengine.de
 #  This file is part of FIFE.
 #
@@ -83,6 +83,10 @@
 		self.instance_to_agent = {}
 		self.dynamic_widgets = {}
 
+		self.light_intensity = 1
+		self.light_sources = 0
+		self.lightmodel = int(TDS.get("FIFE", "Lighting"))
+
 		self.soundmanager = SoundManager(self.engine)
 		self.music = None
 
@@ -157,7 +161,7 @@
 		
 		self.filename = filename
 		self.reset()
-		self.map = loadMapFile(filename, self.engine)
+		self.map = loadMapFile(filename, self.engine, extensions = {'lights': True})
 		self.maplistener = MapListener(self.map)
 
 		self.initAgents()
@@ -259,6 +263,13 @@
 		if str(TDS.get("rio", "QuadTreeLayerName")):
 			renderer.addActiveLayer(self.map.getLayer(str(TDS.get("rio", "QuadTreeLayerName"))))
 
+		# If Light is enabled in settings then init the lightrenderer.
+		if self.lightmodel != 0:
+			renderer = fife.LightRenderer.getInstance(self.cameras['main'])
+			renderer.setEnabled(True)
+			renderer.clearActiveLayers()
+			renderer.addActiveLayer(self.map.getLayer('TechdemoMapGroundObjectLayer'))
+			
 		# Set up the second camera
 		# NOTE: We need to explicitly call setLocation, there's a bit of a messup in the Camera code.
 		self.cameras['small'].setLocation(self.hero.agent.getLocation())
@@ -304,6 +315,14 @@
 			self.load(self.filename)
 		elif keystr == 'o':
 			self.target_rotation = (self.target_rotation + 90) % 360
+		elif keystr == '2':
+			self.lightIntensity(0.1)
+		elif keystr == '1':
+			self.lightIntensity(-0.1)
+		elif keystr == '5':
+			self.lightSourceIntensity(25)
+		elif keystr == '4':
+			self.lightSourceIntensity(-25)
 		elif keyval in (fife.Key.LEFT_CONTROL, fife.Key.RIGHT_CONTROL):
 			self.ctrldown = True
 
@@ -354,6 +373,50 @@
 			if i.getObject().getId() in ('girl', 'beekeeper'):
 				renderer.addOutlined(i, 173, 255, 47, 2)
 
+	def lightIntensity(self, value):
+		if self.light_intensity+value <= 1 and self.light_intensity+value >= 0:
+			self.light_intensity = self.light_intensity + value
+
+			if self.lightmodel == 1:
+				self.cameras['main'].setLightingColor(self.light_intensity, self.light_intensity, self.light_intensity, 1.0)
+
+			if self.lightmodel == 2:
+				self.cameras['main'].setLightingColor(0, 0, 0, 1-self.light_intensity)
+
+	def lightSourceIntensity(self, value):
+		if self.light_sources+value <= 255 and self.light_sources+value >= 0:
+			self.light_sources = self.light_sources+value
+			renderer = fife.LightRenderer.getInstance(self.cameras['main'])
+
+			renderer.removeAll("beekeeper_simple_light")
+			renderer.removeAll("hero_simple_light")
+			renderer.removeAll("girl_simple_light")
+
+			if self.lightmodel == 1:
+				node = fife.LightRendererNode(self.hero.agent)
+				renderer.addSimpleLight("hero_simple_light", node, self.light_sources, 64, 32, 1, 1, 255, 255, 255)
+
+				node = fife.LightRendererNode(self.girl.agent)		
+				renderer.addSimpleLight("girl_simple_light", node, self.light_sources, 64, 32, 1, 1, 255, 255, 255)
+
+				for beekeeper in self.beekeepers:
+					node = fife.LightRendererNode(beekeeper.agent)
+					renderer.addSimpleLight("beekeeper_simple_light", node, self.light_sources, 120, 32, 1, 1, 255, 255, 255)
+
+			if self.lightmodel == 2:
+				node = fife.LightRendererNode(self.hero.agent)
+				renderer.addSimpleLight("hero_simple_light", node, self.light_sources, 64, 32, 1, 1, 0, 0, 0)
+				renderer.addStencilTest("hero_simple_light")
+
+				node = fife.LightRendererNode(self.girl.agent)		
+				renderer.addSimpleLight("girl_simple_light", node, self.light_sources, 64, 32, 1, 1, 0, 0, 0)
+				renderer.addStencilTest("girl_simple_light")
+
+				for beekeeper in self.beekeepers:
+					node = fife.LightRendererNode(beekeeper.agent)
+					renderer.addSimpleLight("beekeeper_simple_light", node, 255, 120, 32, 1, 1, 0, 0, 0)
+					renderer.addStencilTest("beekeeper_simple_light")				
+
 	def onConsoleCommand(self, command):
 		result = ''
 		try:
--- a/demos/rio_de_hola/settings-dist.xml	Wed Nov 03 13:44:12 2010 +0000
+++ b/demos/rio_de_hola/settings-dist.xml	Fri Nov 05 15:21:10 2010 +0000
@@ -19,6 +19,7 @@
  		<Setting name="UsePsyco" type="bool"> False </Setting>
 		<Setting name="ProfilingOn" type="bool"> False </Setting>
 		<Setting name="LogToFile" type="int"> 0 </Setting>
+		<Setting name="Lighting" type="int"> 0 </Setting>
 	</Module>
 
 	<Module name="rio">
--- a/demos/rpg/scripts/gamecontroller.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/demos/rpg/scripts/gamecontroller.py	Fri Nov 05 15:21:10 2010 +0000
@@ -28,7 +28,7 @@
 from fife import fife
 
 from fife.extensions.soundmanager import SoundManager
-from fife.extensions.loaders import loadImportFile
+from fife.extensions.serializers.xml_loader_tools import loadImportFile
 
 from scripts.scene import Scene
 from scripts.guicontroller import GUIController
--- a/demos/rpg/scripts/scene.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/demos/rpg/scripts/scene.py	Fri Nov 05 15:21:10 2010 +0000
@@ -27,8 +27,9 @@
 
 from fife import fife
 from fife.extensions.loaders import loadMapFile
-from fife.extensions.loaders import loadImportFile
+from fife.extensions.serializers.xml_loader_tools import loadImportFile
 from fife.extensions.serializers.simplexml import SimpleXMLSerializer
+from fife.extensions.serializers.xmlobject import XMLObjectLoader
 
 from scripts.actors.baseactor import Actor
 from scripts.actors.questgiver import QuestGiver
@@ -57,6 +58,13 @@
 		self._objectsettings = None
 		self._modelsettings = None
 
+		self.obj_loader = XMLObjectLoader(
+			gamecontroller.engine.getImagePool(),
+			gamecontroller.engine.getAnimationPool(),
+			gamecontroller.engine.getModel(),
+			gamecontroller.engine.getVFS()
+		)
+
 	def loadObject(self, objectname, objectid=None, valuedict=None):
 		if objectid:
 			identifier = objectid
@@ -67,7 +75,7 @@
 			objdict = self._modelsettings.get("objects", objectname, {})
 			modeldict = self._modelsettings.get("models", objdict["modelname"], {})
 			
-			loadImportFile(modeldict["file"], self._gamecontroller.engine)
+			loadImportFile(self.obj_loader, modeldict["file"], self._gamecontroller.engine)
 			
 			if objdict["type"] == "GOLD":
 				newobject = GoldStack(self._gamecontroller, self.itemlayer, objdict["type"], objectname, modeldict["model"], identifier)
@@ -114,7 +122,7 @@
 		"""
 		modeldict = self._modelsettings.get("models", "Player", {})
 	
-		loadImportFile(modeldict["file"], self._gamecontroller.engine)
+		loadImportFile(self.obj_loader, modeldict["file"], self._gamecontroller.engine)
 		self._player = Player(self._gamecontroller, self.actorlayer, "warrior")
 		
 		playerfilename = os.path.join("saves", "player_save.xml")
--- a/demos/rpg/settings-dist.xml	Wed Nov 03 13:44:12 2010 +0000
+++ b/demos/rpg/settings-dist.xml	Fri Nov 05 15:21:10 2010 +0000
@@ -19,6 +19,7 @@
  		<Setting name="UsePsyco" type="bool"> False </Setting>
 		<Setting name="ProfilingOn" type="bool"> False </Setting>
 		<Setting name="LogToFile" type="int"> 0 </Setting>
+    <Setting name="Lighting" type="int"> 0 </Setting>
 	</Module>
 
 	<Module name="RPG">
--- a/demos/shooter/gui/highscores.xml	Wed Nov 03 13:44:12 2010 +0000
+++ b/demos/shooter/gui/highscores.xml	Fri Nov 05 15:21:10 2010 +0000
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="ascii"?>
-<Container base_color="0,0,0" border_size="0" opaque="0" position="0,0" name="HighScores" size="1024,768">
+<Container opaque="0" name="HighScores" border_size="0" position="0,0" size="1024,768" base_color="0,0,0">
 	<VBox name="high_score" position="412,200" opaque="1" base_color="188,0,0">
 		<HBox>
 			<Label name="high_scores" border_size="0" text="High Scores" min_size="100,0">
--- a/demos/shooter/scripts/world.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/demos/shooter/scripts/world.py	Fri Nov 05 15:21:10 2010 +0000
@@ -29,7 +29,9 @@
 from fife.extensions.soundmanager import SoundManager
 
 from scripts.common.eventlistenerbase import EventListenerBase
-from fife.extensions.loaders import loadMapFile, loadImportFile
+from fife.extensions.loaders import loadMapFile
+from fife.extensions.serializers.xml_loader_tools import loadImportFile
+from fife.extensions.serializers.xmlobject import XMLObjectLoader
 
 from scripts.gui.guis import *
 
@@ -57,6 +59,12 @@
 		self._timemanager = engine.getTimeManager()
 		self._eventmanager = engine.getEventManager()
 		self._model = engine.getModel()
+		self.obj_loader = XMLObjectLoader(
+			engine.getImagePool(),
+			engine.getAnimationPool(),
+			engine.getModel(),
+			engine.getVFS()
+		)
 		self._filename = ''
 		self._keystate = { 'UP': False, 
 		                   'DOWN': False, 
@@ -140,8 +148,8 @@
 		
 		#specific imports that needed to be added
 		#@todo: you should be able to add file imports via the map editor
-		loadImportFile("objects/projectiles/bullet1/object.xml", self._engine)
-		loadImportFile("objects/projectiles/fireball/object.xml", self._engine)
+		loadImportFile(self.obj_loader, "objects/projectiles/bullet1/object.xml", self._engine)
+		loadImportFile(self.obj_loader,"objects/projectiles/fireball/object.xml", self._engine)
 		
 		self._map = loadMapFile(self._filename, self._engine)
 
--- a/demos/shooter/settings-dist.xml	Wed Nov 03 13:44:12 2010 +0000
+++ b/demos/shooter/settings-dist.xml	Fri Nov 05 15:21:10 2010 +0000
@@ -17,6 +17,7 @@
 		<Setting name="PychanDebug" type="bool"> False </Setting>
 		<Setting name="LogToPrompt" type="int"> 1 </Setting>
 		<Setting name="LogToFile" type="int"> 0 </Setting>
+    <Setting name="Lighting" type="int"> 0 </Setting>
 	</Module>
 	<Module name="shooter">
 		<Setting name="MaxSounds" type="int">100</Setting>
--- a/engine/core/controller/engine.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/controller/engine.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -51,6 +51,7 @@
 #include "video/cursor.h"
 #include "video/devicecaps.h"
 #ifdef HAVE_OPENGL
+#include "video/opengl/fife_opengl.h"
 #include "video/opengl/renderbackendopengl.h"
 #include "gui/base/opengl/opengl_gui_graphics.h"
 #endif
@@ -74,6 +75,7 @@
 #include "view/renderers/cellselectionrenderer.h"
 #include "view/renderers/blockinginforenderer.h"
 #include "view/renderers/genericrenderer.h"
+#include "view/renderers/lightrenderer.h"
 #include "video/image.h"
 #include "gui/console/console.h"
 #include "engine.h"
@@ -256,6 +258,11 @@
 		if( rbackend != "SDL" ) {
 			m_gui_graphics = new OpenGLGuiGraphics(*m_imagepool);
 		}
+
+		if (m_settings.getLightingModel() != 0) {
+			m_renderbackend->setLightingModel(m_settings.getLightingModel());
+		}
+
 #endif
 		if( rbackend == "SDL" ) {
 			m_gui_graphics = new SdlGuiGraphics(*m_imagepool);
@@ -289,6 +296,7 @@
 		m_renderers.push_back(new QuadTreeRenderer(m_renderbackend, 60));
 		m_renderers.push_back(new CoordinateRenderer(m_renderbackend, 70, dynamic_cast<AbstractFont*>(m_defaultfont)));
 		m_renderers.push_back(new GenericRenderer(m_renderbackend, 80, m_imagepool, m_animpool));
+		m_renderers.push_back(new LightRenderer(m_renderbackend, 90, m_imagepool, m_animpool));
 
 		FL_LOG(_log, "Creating model");
 		m_model = new Model(m_renderbackend, m_renderers, m_imagepool, m_animpool);
@@ -358,8 +366,18 @@
 		m_renderbackend->startFrame();
 		m_timemanager->update();
 		m_model->update();
+#ifdef HAVE_OPENGL
+		if (m_settings.getLightingModel() == 1) {
+			m_renderbackend->disableLighting();
+		}
+#endif
 		m_guimanager->turn();
 		m_cursor->draw();
+#ifdef HAVE_OPENGL
+		if (m_settings.getLightingModel() == 1) {
+			m_renderbackend->enableLighting();
+		}
+#endif
 		m_renderbackend->endFrame();
 	}
 
--- a/engine/core/controller/engine.i	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/controller/engine.i	Fri Nov 05 15:21:10 2010 +0000
@@ -81,6 +81,8 @@
 		const SDL_Color& getColorKey() const;
 		void setVideoDriver(const std::string& driver);
 		const std::string& getVideoDriver() const;
+		void setLightingModel(unsigned int lighting);
+		unsigned int getLightingModel() const;
 		
 	private:
 		EngineSettings();
--- a/engine/core/controller/enginesettings.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/controller/enginesettings.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -50,6 +50,7 @@
 		m_defaultfontpath(""),
 		m_defaultfontsize(8),
 		m_defaultfontglyphs(""),
+		m_lighting(0),
 		m_iscolorkeyenabled(false){
 			m_colorkey.r = 255;
 			m_colorkey.g = 0;
@@ -199,5 +200,13 @@
 	const std::string& EngineSettings::getVideoDriver() const {
 		return m_videodriver;
 	}
+	void EngineSettings::setLightingModel(unsigned int lighting) {
+		if (lighting <= 2) {
+			m_lighting = lighting;
+			return;
+		}
+		throw NotSupported("Given light model is not supported");
+	}
+
 }
 
--- a/engine/core/controller/enginesettings.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/controller/enginesettings.h	Fri Nov 05 15:21:10 2010 +0000
@@ -214,6 +214,16 @@
 
 		const std::string& getVideoDriver() const;
 
+		/** Sets the light model
+		 */
+		void setLightingModel(unsigned int lighting);
+
+		/** Gets the currently set light model
+		 */
+		unsigned int getLightingModel() const {
+			return m_lighting;
+		}
+
 	private:
 		uint8_t m_bitsperpixel;
 		bool m_fullscreen;
@@ -223,7 +233,7 @@
 		uint16_t m_screenwidth;
 		uint16_t m_screenheight;
 		std::string m_windowtitle;
-		std::string m_windowicon;
+		std::string m_windowicon;		
 
 
 		std::string m_defaultfontpath;
@@ -232,6 +242,7 @@
 		bool m_iscolorkeyenabled;
 		SDL_Color m_colorkey;
 		std::string m_videodriver;
+		unsigned int m_lighting;
 	};
 
 }//FIFE
--- a/engine/core/video/animation.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/animation.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -82,7 +82,7 @@
 	bool Animation::isValidIndex(int index) const{
 		int size = m_frames.size();
 		return size > 0 && index >= 0 && index < size; 
-		}
+	}
 
 	Image* Animation::getFrame(int index) {
 		if (isValidIndex(index)) {
--- a/engine/core/video/image.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/image.h	Fri Nov 05 15:21:10 2010 +0000
@@ -93,6 +93,10 @@
 		 */
 		virtual void drawVertex(const Point& p, const uint8_t size, int r, int g, int b, int a = 255) = 0;
 
+		/** Draws a light primitive that based on a triangle fan
+		 */
+		virtual void drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue) = 0;
+
 		/** Returns pixel RGBA values from given position
 		 */
 		virtual void getPixelRGBA(int x, int y, uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) = 0;
--- a/engine/core/video/opengl/fife_opengl.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/opengl/fife_opengl.h	Fri Nov 05 15:21:10 2010 +0000
@@ -29,6 +29,7 @@
 #if defined( __unix__ )
 #include <GL/gl.h>
 #include <GL/glu.h>
+#include <GL/glext.h>
 #endif
 
 // Win32
@@ -38,11 +39,13 @@
 #include <windows.h>
 #include <GL/gl.h>
 #include <GL/glu.h>
+#include <GL/glext.h>
 #undef DELETE
 // MinGW
 #else
 #include <GL/gl.h>
 #include <GL/glu.h>
+#include <GL/glext.h>
 #endif
 #endif
 
@@ -50,6 +53,7 @@
 #if defined( __APPLE_CC__ )
 #include <OpenGL/gl.h>
 #include <OpenGL/glu.h>
+#include <OpenGL/glext.h>
 #endif
 
 // 3rd party library includes
--- a/engine/core/video/opengl/glimage.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/opengl/glimage.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -110,7 +110,7 @@
 		uint16_t w = static_cast<int>(round(scale_x*m_surface->w));
 		uint16_t h = static_cast<int>(round(scale_y*m_surface->h));
 
-		/// setting transparency for the whole primitive:
+		// setting transparency for the whole primitive:
 		glColor4ub( 255, 255, 255, alpha );
 
 		glEnable(GL_TEXTURE_2D);
@@ -239,7 +239,7 @@
 		glScissor(cliparea.x, getHeight() - cliparea.y - cliparea.h, cliparea.w, cliparea.h);
 
 		if (clear) {
-	        	glClear(GL_COLOR_BUFFER_BIT);
+			glClear(GL_COLOR_BUFFER_BIT);
 		}
 	}
 
@@ -277,4 +277,9 @@
 		cleanup();
 		m_sdlimage->drawVertex(p, size, r, g, b, a);
 	}
+
+	void GLImage::drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue) {
+		cleanup();
+		m_sdlimage->drawLightPrimitive(p, intensity, radius, subdivisions, xstretch, ystretch, red, green, blue);
+	}
 }
--- a/engine/core/video/opengl/glimage.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/opengl/glimage.h	Fri Nov 05 15:21:10 2010 +0000
@@ -70,6 +70,7 @@
 		void fillRectangle(const Point& p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255);
 		void drawQuad(const Point& p1, const Point& p2, const Point& p3, const Point& p4,  int r, int g, int b, int a = 255);
 		void drawVertex(const Point& p, const uint8_t size, int r, int g, int b, int a = 255);
+		void drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue);
 
 	protected:
 		void setClipArea(const Rect& cliparea, bool clear);
--- a/engine/core/video/opengl/renderbackendopengl.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/opengl/renderbackendopengl.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -36,6 +36,7 @@
 #include "renderbackendopengl.h"
 #include "SDL_image.h"
 
+
 namespace FIFE {
 	static Logger _log(LM_VIDEO);
 
@@ -47,6 +48,16 @@
 		m_rgba_format = *(testsurface->format);
 		SDL_FreeSurface(testsurface);
 		m_clear = false;
+		m_lightmodel = 0;
+		m_light_enabled = false;
+		m_stencil_enabled = false;
+		m_alpha_enabled = false;
+		m_sten_ref = 0;
+		m_sten_buf = 0;
+		m_sten_op = 0;
+		m_sten_func = 0;
+		m_blend_src = GL_SRC_ALPHA;
+		m_blend_dst = GL_ONE_MINUS_SRC_ALPHA;
 	}
 
 	const std::string& RenderBackendOpenGL::getName() const {
@@ -66,8 +77,10 @@
 		if (SDL_InitSubSystem(flags) < 0)
 			throw SDLException(SDL_GetError());
 		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+		SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
 
 		SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); // temporary hack
+
 	}
 
 	void RenderBackendOpenGL::clearBackBuffer() {
@@ -132,6 +145,7 @@
 		glMatrixMode(GL_MODELVIEW);
 
 		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
 		glEnable(GL_TEXTURE_2D);
 		glEnable(GL_BLEND);
 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -140,7 +154,7 @@
 
 		glPointSize(1.0);
 		glLineWidth(1.0);
-
+		delete m_screen;
 		delete m_screen;
 		m_screen = new GLImage(screen);
 		return m_screen;
@@ -182,7 +196,7 @@
 			return new GLImage(surface);
 		}
 
-		SDL_Surface* conv = SDL_ConvertSurface(surface, &m_rgba_format, SDL_SWSURFACE|SDL_SRCALPHA);
+		SDL_Surface* conv = SDL_ConvertSurface(surface, &m_rgba_format, SDL_SWSURFACE | SDL_SRCALPHA);
 		GLImage* image = new GLImage(conv);
 		SDL_FreeSurface( surface );
 		return image;
@@ -192,6 +206,183 @@
 		return new GLImage(data, width, height);
 	}
 
+	void RenderBackendOpenGL::setLightingModel(unsigned int lighting) {
+		if (m_lightmodel != lighting) {
+			if (m_lightmodel == 1) {
+				disableLighting();
+				glDisable(GL_COLOR_MATERIAL);
+			} else if (lighting == 1) {
+				enableLighting();
+				glEnable(GL_LIGHT0);
+				glColorMaterial(GL_FRONT, GL_DIFFUSE);
+				glEnable(GL_COLOR_MATERIAL);
+			}
+			m_lightmodel = lighting;
+		}
+	}
+
+	unsigned int RenderBackendOpenGL::getLightingModel() const {
+		return m_lightmodel;
+	}
+
+	void RenderBackendOpenGL::enableLighting() {
+		if (m_lightmodel == 1 && !m_light_enabled) {
+			glEnable(GL_LIGHTING);
+			m_light_enabled = true;
+		}
+	}
+
+	void RenderBackendOpenGL::disableLighting() {
+		if (m_lightmodel == 1 && m_light_enabled) {
+			glDisable(GL_LIGHTING);
+			m_light_enabled = false;
+		}
+	}
+
+	void RenderBackendOpenGL::setLighting(float red, float green, float blue, float alpha) {
+		if (m_lightmodel == 1) {
+			GLfloat lightDiffuse[] = {red, green, blue, alpha};
+			glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
+		} else if(m_lightmodel == 2) {
+			m_lred = red;
+			m_lgreen = green;
+			m_lblue = blue;
+			m_lalpha = alpha;
+		}
+	}
+
+	void RenderBackendOpenGL::resetLighting() {
+		if (m_lightmodel == 1) {
+			setLighting(1.0, 1.0, 1.0, 1.0);
+		} else if (m_lightmodel == 2 && m_lalpha > 0.01) {
+			uint16_t width = getScreenWidth();
+			uint16_t height = getScreenHeight();
+			Point p = Point(0,0);
+			setStencilTest(0, 0, 5);
+			fillRectangle(p, width, height, m_lred*255, m_lgreen*255, m_lblue*255, m_lalpha*255);
+			disableStencilTest();
+		}
+	}
+
+	void RenderBackendOpenGL::enableStencilTest() {
+		if (!m_stencil_enabled) {
+			glEnable(GL_STENCIL_TEST);
+			m_stencil_enabled = true;
+		}
+	}
+
+	void RenderBackendOpenGL::disableStencilTest() {
+		if (m_stencil_enabled) {
+			glDisable(GL_STENCIL_TEST);
+			m_stencil_enabled = false;
+		}
+	}
+
+	void RenderBackendOpenGL::setStencilTest(uint8_t stencil_ref, unsigned int stencil_op, unsigned int stencil_func) {
+		enableStencilTest();
+		if(m_sten_op != stencil_op) {
+			GLenum op;
+			m_sten_op = stencil_op;
+			switch(stencil_op) {
+				default :
+				case 0  : op = GL_KEEP; break;
+				case 1  : op = GL_ZERO; break;
+				case 2  : op = GL_REPLACE; break;
+				case 3  : op = GL_INCR; break;
+				case 4  : op = GL_DECR; break;
+				case 5  : op = GL_INVERT; break;
+			}
+			glStencilOp(GL_KEEP, GL_KEEP, op);
+		}
+
+		if(m_sten_ref != stencil_ref || m_sten_func != stencil_func) {
+			GLenum func;
+			m_sten_ref = stencil_ref;
+			m_sten_func = stencil_func;
+			switch(stencil_func) {
+				default :
+				case 0  : func = GL_NEVER; break;
+				case 1  : func = GL_LESS; break;
+				case 2  : func = GL_LEQUAL; break;
+				case 3  : func = GL_GREATER; break;
+				case 4  : func = GL_GEQUAL; break;
+				case 5  : func = GL_EQUAL; break;
+				case 6  : func = GL_NOTEQUAL; break;
+				case 7  : func = GL_ALWAYS; break;
+			}
+			glStencilFunc(func, stencil_ref, 0xff);
+		}
+	}
+
+	void RenderBackendOpenGL::resetStencilBuffer(uint8_t buffer) {
+		if (buffer != m_sten_buf) {
+			m_sten_buf = buffer;
+			glClearStencil(buffer);
+		}
+		GLDisable flag(GL_SCISSOR_TEST);
+		glClear(GL_STENCIL_BUFFER_BIT);
+	}
+
+	uint8_t RenderBackendOpenGL::getStencilRef() const {
+		return m_sten_ref;
+	}
+
+	void RenderBackendOpenGL::enableAlphaTest() {
+		if (!m_alpha_enabled) {
+			glEnable(GL_ALPHA_TEST);
+			m_alpha_enabled = true;
+		}
+	}
+
+	void RenderBackendOpenGL::disableAlphaTest() {
+		if (m_alpha_enabled) {
+			glDisable(GL_ALPHA_TEST);
+			m_alpha_enabled = false;
+		}
+	}
+
+	void RenderBackendOpenGL::setAlphaTest(float ref_alpha) {
+		enableAlphaTest();
+		glAlphaFunc(GL_GREATER, ref_alpha);
+	}
+
+	void RenderBackendOpenGL::changeBlending(int src, int dst) {
+		GLenum src_fact;
+		GLenum dst_fact;
+
+		switch(src) { 
+			case 0  : src_fact = GL_ZERO; break;
+			case 1  : src_fact = GL_ONE; break;
+			case 2  : src_fact = GL_DST_COLOR; break;
+			case 3  : src_fact = GL_ONE_MINUS_DST_COLOR; break;
+			case 4  : src_fact = GL_SRC_ALPHA; break;
+			case 5  : src_fact = GL_ONE_MINUS_SRC_ALPHA; break;
+			case 6  : src_fact = GL_DST_ALPHA; break;
+			case 7  : src_fact = GL_ONE_MINUS_DST_ALPHA; break;
+
+			default : src_fact = GL_DST_COLOR; break;
+		}
+
+		switch(dst) { 
+			case 0  : dst_fact = GL_ZERO; break;
+			case 1  : dst_fact = GL_ONE; break;
+			case 2  : dst_fact = GL_SRC_COLOR; break;
+			case 3  : dst_fact = GL_ONE_MINUS_SRC_COLOR; break;
+			case 4  : dst_fact = GL_SRC_ALPHA; break;
+			case 5  : dst_fact = GL_ONE_MINUS_SRC_ALPHA; break;
+			case 6  : dst_fact = GL_DST_ALPHA; break;
+			case 7  : dst_fact = GL_ONE_MINUS_DST_ALPHA; break;
+
+			default : dst_fact = GL_SRC_ALPHA; break;
+		}
+
+		if (m_blend_src != src_fact || m_blend_dst != dst_fact) {
+			m_blend_src = src_fact;
+			m_blend_dst = dst_fact;
+			glBlendFunc(src_fact, dst_fact);
+		}
+	}
+
 	bool RenderBackendOpenGL::putPixel(int x, int y, int r, int g, int b, int a) {
 		if ((x < 0) || (x >= (int)getWidth()) || (y < 0) || (y >= (int)getHeight())) {
 			return false;
@@ -277,4 +468,21 @@
 
 		glLineWidth(width);
 	}
+
+	void RenderBackendOpenGL::drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue) {
+		glBegin(GL_TRIANGLE_FAN);
+		glColor4ub(red, green, blue, intensity);
+		glVertex2f(p.x, p.y);
+		if (m_lightmodel == 2) {
+			glColor4ub(0, 0, 0, intensity);
+		} else {
+			glColor4ub(0, 0, 0, 255);
+		}
+		for(float angle=0; angle<=Mathf::twoPi(); angle+=(Mathf::twoPi()/subdivisions)){
+			glVertex2f( radius*Mathf::Cos(angle)*xstretch + p.x,
+						radius*Mathf::Sin(angle)*ystretch + p.y);  
+		}
+		glVertex2f(p.x+radius*xstretch, p.y);
+		glEnd();
+	}
 }
--- a/engine/core/video/opengl/renderbackendopengl.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/opengl/renderbackendopengl.h	Fri Nov 05 15:21:10 2010 +0000
@@ -48,6 +48,21 @@
 		void endFrame();
 		void init(const std::string& driver);
 		void clearBackBuffer();
+		void setLightingModel(unsigned int lighting);
+		unsigned int getLightingModel() const;
+		void enableLighting();
+		void disableLighting();
+		void setLighting(float red, float green, float blue, float alpha);
+		void resetLighting();
+		void enableStencilTest();
+		void disableStencilTest();
+		void setStencilTest(uint8_t stencil_ref, unsigned int stencil_op, unsigned int stencil_func);
+		void resetStencilBuffer(uint8_t buffer);
+		uint8_t getStencilRef() const;
+		void enableAlphaTest();
+		void disableAlphaTest();
+		void setAlphaTest(float ref_alpha);
+		void changeBlending(int scr, int dst);
 
 		Image* createMainScreen(const ScreenMode& mode, const std::string& title, const std::string& icon);
 		Image*  setScreenMode(const ScreenMode& mode);
@@ -60,9 +75,25 @@
 		void fillRectangle(const Point& p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255);
 		void drawQuad(const Point& p1, const Point& p2, const Point& p3, const Point& p4,  int r, int g, int b, int a = 255);
 		void drawVertex(const Point& p, const uint8_t size, int r, int g, int b, int a = 255);
+		void drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue);
 
 	private:
 		SDL_PixelFormat m_rgba_format;
+
+		unsigned int m_lightmodel;
+		float m_lred;
+		float m_lgreen;
+		float m_lblue;
+		float m_lalpha;
+		bool m_light_enabled;
+		bool m_stencil_enabled;
+		bool m_alpha_enabled;
+		uint8_t m_sten_ref;
+		GLint m_sten_buf;
+		unsigned int m_sten_op;
+		unsigned int m_sten_func;
+		GLenum m_blend_src;
+		GLenum m_blend_dst;
 	};
 
 }
--- a/engine/core/video/renderbackend.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/renderbackend.h	Fri Nov 05 15:21:10 2010 +0000
@@ -24,6 +24,7 @@
 
 // Standard C++ library includes
 #include <string>
+#include <vector>
 
 // Platform specific includes
 #include "util/base/fife_stdint.h"
@@ -80,6 +81,66 @@
 		 */
 		virtual void clearBackBuffer() = 0;
 
+		/** Initializes the light.
+		 */
+		virtual void setLightingModel(unsigned int lighting) = 0;
+
+		/** Gets the current light model.
+		 */
+		virtual unsigned int getLightingModel() const = 0;
+
+		/** Enable the lighting.
+		 */
+		virtual void enableLighting() = 0;
+
+		/** Disable the lighting.
+		 */
+		virtual void disableLighting() = 0;
+
+		/** Set colors for lighting
+		 */
+		virtual void setLighting(float red, float green, float blue, float alpha) = 0;
+
+		/** Reset lighting with default values.
+		 */
+		virtual void resetLighting() = 0;
+
+		/** Enable the stencil test.
+		 */
+		virtual void enableStencilTest() = 0;
+
+		/** Disable the stencil test.
+		 */
+		virtual void disableStencilTest() = 0;
+
+		/** Set reference for the stencil test.
+		 */
+		virtual void setStencilTest(Uint8 stencil_ref, unsigned int stencil_op, unsigned int stencil_func) = 0;
+
+		/** Reset stencil buffer with given value.
+		 */
+		virtual void resetStencilBuffer(Uint8 buffer) = 0;
+
+		/** Return the reference value for the stencil test.
+		 */
+		virtual Uint8 getStencilRef() const = 0;
+
+		/** Enable the alpha test.
+		 */
+		virtual void enableAlphaTest() = 0;
+
+		/** Disable the stencil test.
+		 */
+		virtual void disableAlphaTest() = 0;
+
+		/** Set reference for the alpha test.
+		 */
+		virtual void setAlphaTest(float ref_alpha) = 0;
+
+		/** Change the Blendingmodel.
+		 */
+		virtual void changeBlending(int scr, int dst) = 0;
+
 		/** Performs cleanup actions.
 		 */
 		virtual void deinit();
--- a/engine/core/video/sdl/renderbackendsdl.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/sdl/renderbackendsdl.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -152,6 +152,54 @@
 		return new SDLImage(data, width, height);
 	}
 
+	void RenderBackendSDL::setLightingModel(unsigned int lighting) {
+		SDLException("Lighting not available under SDL");
+	}
+
+	unsigned int RenderBackendSDL::getLightingModel() const {
+		return 0;
+	}
+
+	void RenderBackendSDL::enableLighting() {
+	}
+
+	void RenderBackendSDL::disableLighting() {
+	}
+
+	void RenderBackendSDL::setLighting(float red, float green, float blue, float alpha) {
+	}
+
+	void RenderBackendSDL::resetLighting() {
+	}
+
+	void RenderBackendSDL::enableStencilTest() {
+	}
+
+	void RenderBackendSDL::disableStencilTest() {
+	}
+
+	void RenderBackendSDL::setStencilTest(uint8_t stencil_ref, unsigned int stencil_op, unsigned int stencil_func) {
+	}
+
+	void RenderBackendSDL::resetStencilBuffer(uint8_t buffer) {
+	}
+
+	uint8_t RenderBackendSDL::getStencilRef() const {
+		return 0;
+	}
+
+	void RenderBackendSDL::enableAlphaTest() {
+	}
+
+	void RenderBackendSDL::disableAlphaTest() {
+	}
+
+	void RenderBackendSDL::setAlphaTest(float ref_alpha) {
+	}
+
+	void RenderBackendSDL::changeBlending(int scr, int dst){
+	}
+	
 	bool RenderBackendSDL::putPixel(int x, int y, int r, int g, int b, int a) {
 		return static_cast<SDLImage*>(m_screen)->putPixel(x, y, r, g, b, a);
 	}
@@ -180,4 +228,7 @@
 		static_cast<SDLImage*>(m_screen)->drawVertex(p, 2, r, g, b, a);
 	}
 
+	void RenderBackendSDL::drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue){
+		static_cast<SDLImage*>(m_screen)->drawLightPrimitive(p, intensity, radius, subdivisions, xstretch, ystretch, red, green, blue);
+	}
 }//FIFE
--- a/engine/core/video/sdl/renderbackendsdl.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/sdl/renderbackendsdl.h	Fri Nov 05 15:21:10 2010 +0000
@@ -50,6 +50,21 @@
 		void endFrame();
 		void init(const std::string& driver);
 		void clearBackBuffer();
+		void setLightingModel(unsigned int lighting);
+		unsigned int getLightingModel() const;
+		void enableLighting();
+		void disableLighting();
+		void setLighting(float red, float green, float blue, float alpha);
+		void resetLighting();
+		void enableStencilTest();
+		void disableStencilTest();
+		void setStencilTest(uint8_t stencil_ref, unsigned int stencil_op, unsigned int stencil_func);
+		void resetStencilBuffer(uint8_t buffer);
+		uint8_t getStencilRef() const;
+		void enableAlphaTest();
+		void disableAlphaTest();
+		void setAlphaTest(float ref_alpha);
+		void changeBlending(int scr, int dst);
 
 		Image* createMainScreen(const ScreenMode& mode, const std::string& title, const std::string& icon);
 		Image* setScreenMode(const ScreenMode& mode);
@@ -62,6 +77,7 @@
 		void fillRectangle(const Point& p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255);
 		void drawQuad(const Point& p1, const Point& p2, const Point& p3, const Point& p4,  int r, int g, int b, int a = 255);
 		void drawVertex(const Point& p, const uint8_t size, int r, int g, int b, int a = 255);
+		void drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue);
 	};
 
 }
--- a/engine/core/video/sdl/sdlimage.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/sdl/sdlimage.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -807,6 +807,9 @@
 		drawLine(p4, p1, r, g, b, a);
 	}
 
+	void SDLImage::drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue) {
+	}
+
 	void SDLImage::saveImage(const std::string& filename) {
 		if(m_surface) {
 			const unsigned int swidth = getWidth();
--- a/engine/core/video/sdl/sdlimage.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/sdl/sdlimage.h	Fri Nov 05 15:21:10 2010 +0000
@@ -52,6 +52,7 @@
 		void fillRectangle(const Point& p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255);
 		void drawQuad(const Point& p1, const Point& p2, const Point& p3, const Point& p4,  int r, int g, int b, int a = 255);
 		void drawVertex(const Point& p, const uint8_t size, int r, int g, int b, int a = 255);
+		void drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue);
 
 	protected:
 		void setClipArea(const Rect& cliparea, bool clear);
--- a/engine/core/video/video.i	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/video/video.i	Fri Nov 05 15:21:10 2010 +0000
@@ -64,6 +64,7 @@
 		virtual void drawRectangle(const Point& p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) = 0;
 		virtual void fillRectangle(const Point& p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255) = 0;
 		virtual void drawQuad(const Point& p1, const Point& p2, const Point& p3, const Point& p4,  int r, int g, int b, int a = 255) = 0;
+		virtual void drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue);
 		virtual void pushClipArea(const Rect& cliparea, bool clear=true) = 0;
 		virtual void popClipArea() = 0;
 		virtual const Rect& getClipArea() const = 0;
@@ -173,6 +174,7 @@
 		void fillRectangle(const Point& p, uint16_t w, uint16_t h, uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255);
 		void drawQuad(const Point& p1, const Point& p2, const Point& p3, const Point& p4,  int r, int g, int b, int a = 255);
 		void drawVertex(const Point& p, int size,  int r, int g, int b, int a = 255);
+		void drawLightPrimitive(const Point& p, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t red, uint8_t green, uint8_t blue);
 		void pushClipArea(const Rect& cliparea, bool clear=true);
 		void popClipArea();
 		const Rect& getClipArea() const;
--- a/engine/core/view/camera.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/camera.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -105,7 +105,9 @@
 			m_renderbackend(renderbackend),
 			m_ipool(ipool),
 			m_apool(apool),
-			m_layer_to_instances() {
+			m_layer_to_instances(),
+			m_lighting(false),
+			m_light_colors() {
 
 		m_viewport = viewport;
 		m_map_observer = new MapObserver(this);
@@ -630,6 +632,29 @@
 		m_layer_to_instances.erase(layer);
 	}
 
+	void Camera::setLightingColor(float red, float green, float blue, float alpha) {
+		m_lighting = true;
+		m_light_colors.clear();
+		m_light_colors.push_back(red);
+		m_light_colors.push_back(green);
+		m_light_colors.push_back(blue);
+		m_light_colors.push_back(alpha);
+	}
+
+	std::vector<float> Camera::getLightingColor() {
+		if(m_light_colors.empty()) {
+			for(int colors = 0; colors != 4; ++colors) {
+				m_light_colors.push_back(1.0f);
+			}
+		}
+		return m_light_colors;
+	}
+
+	void Camera::resetLightingColor() {
+		m_lighting = false;
+		m_renderbackend->resetLighting();
+	}
+
 	void Camera::render() {
 		Transform transform = NormalTransform;
 		if(m_iswarped)
@@ -645,13 +670,22 @@
 		//	return;
 		//}
 
+		if (m_renderbackend->getLightingModel() != 0) {
+			m_renderbackend->resetStencilBuffer(0);
+			if (m_lighting) {
+				m_renderbackend->setLighting(m_light_colors[0], m_light_colors[1], m_light_colors[2], m_light_colors[3]);
+			}
+		}
+
 		if(m_backendSDL) {
 			m_renderbackend->pushClipArea(getViewPort());
 		} else {
 			m_renderbackend->pushClipArea(getViewPort(), testRenderedViewPort());
 		}
+
 		// update each layer
 // 		m_layer_to_instances.clear();
+
 		const std::list<Layer*>& layers = map->getLayers();
 		std::list<Layer*>::const_iterator layer_it = layers.begin();
 		for (;layer_it != layers.end(); ++layer_it) {
@@ -671,6 +705,11 @@
 				}
 			}
 		}
+
+		if (m_lighting) {
+			m_renderbackend->resetLighting();
+		}
+
 		m_renderbackend->popClipArea();
 		resetUpdates();
 		m_updated = true;
--- a/engine/core/view/camera.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/camera.h	Fri Nov 05 15:21:10 2010 +0000
@@ -283,6 +283,10 @@
 		 */
 		bool testRenderedViewPort();
 
+		void setLightingColor(float red, float green, float blue, float alpha);
+		void resetLightingColor();
+		std::vector<float> getLightingColor();
+
 		/** Renders camera
 		 */
 		void render();
@@ -356,6 +360,11 @@
 		std::map<Layer*,LayerCache*> m_cache;
 		MapObserver* m_map_observer;
 		Map* m_map;
+
+		// is lighting enable
+		bool m_lighting;
+		// caches the light color for the camera
+		std::vector<float> m_light_colors;
 	};
 }
 #endif
--- a/engine/core/view/camera.i	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/camera.i	Fri Nov 05 15:21:10 2010 +0000
@@ -63,6 +63,10 @@
 		void getMatchingInstances(Location& loc, std::list<Instance*>& instances, bool use_exactcoordinates=false);
 		RendererBase* getRenderer(const std::string& name);
 		void resetRenderers();
+		
+		void setLightingColor(float red, float green, float blue, float alpha);
+		void resetLightingColor();
+		std::vector<float> getLightingColor();
 
 		void refresh();
 	private:
@@ -71,4 +75,4 @@
 	%clear std::list<Instance*>& instances;
 }
 
-%clear InstanceLst& instances;
+%clear InstanceLst& instances;
\ No newline at end of file
--- a/engine/core/view/rendererbase.i	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/rendererbase.i	Fri Nov 05 15:21:10 2010 +0000
@@ -43,6 +43,7 @@
 		void removeActiveLayer(Layer* layer);
 		void clearActiveLayers();
 		void activateAllLayers(Map* map);
+		std::list<Layer*> getActiveLayers() const {return m_active_layers;}
 	};
 	
 	class IRendererContainer {
--- a/engine/core/view/renderers/cellselectionrenderer.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/renderers/cellselectionrenderer.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -109,6 +109,8 @@
 				continue;
 			}
 
+			m_renderbackend->disableLighting();
+
 			std::vector<ExactModelCoordinate> vertices;
 			cg->getVertices(vertices, loc.getLayerCoordinates());
 			std::vector<ExactModelCoordinate>::const_iterator it = vertices.begin();
@@ -125,6 +127,7 @@
 				pt1 = pt2;
 			}
 			m_renderbackend->drawLine(pt2, Point(firstpt.x, firstpt.y), m_color.r, m_color.g, m_color.b);
+			m_renderbackend->enableLighting();
 		}
 	}
 
--- a/engine/core/view/renderers/floatingtextrenderer.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/renderers/floatingtextrenderer.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -78,10 +78,16 @@
 
 		RenderList::const_iterator instance_it = instances.begin();
 		const std::string* saytext = NULL;
+		unsigned int lm = m_renderbackend->getLightingModel();
 		SDL_Color old_color = m_font->getColor();
 		if(m_font_color) {
 			m_font->setColor(m_color.r, m_color.g, m_color.b, m_color.unused);
 		}
+		if(lm != 0) {
+			m_renderbackend->disableLighting();
+			m_renderbackend->setStencilTest(255, 2, 7);
+			m_renderbackend->setAlphaTest(0.0);
+		}
 		for (;instance_it != instances.end(); ++instance_it) {
 			Instance* instance = (*instance_it)->instance;
 			saytext = instance->getSayText();
@@ -110,6 +116,11 @@
 				img->render(r);
 			}
 		}
+		if(lm != 0) {
+			m_renderbackend->disableAlphaTest();
+			m_renderbackend->disableStencilTest();
+			m_renderbackend->enableLighting();
+		}
 		if(m_font_color) {
 			m_font->setColor(old_color.r, old_color.g, old_color.b, old_color.unused);
 		}
--- a/engine/core/view/renderers/floatingtextrenderer.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/renderers/floatingtextrenderer.h	Fri Nov 05 15:21:10 2010 +0000
@@ -89,6 +89,10 @@
 		 */
 		static FloatingTextRenderer* getInstance(IRendererContainer* cnt);
 
+		/** Provides access point to the RenderBackend
+		 */
+		RenderBackend* getRenderBackend() const {return m_renderbackend;}
+
 	private:
 		RenderBackend* m_renderbackend;
 		AbstractFont* m_font;
--- a/engine/core/view/renderers/genericrenderer.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/renderers/genericrenderer.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -377,11 +377,36 @@
 			r.y = p.y-img->getHeight()/2;
 			r.w = img->getWidth();
 			r.h = img->getHeight();
-			if(r.intersects(viewport))
+			if(r.intersects(viewport)) {
+				renderbackend->disableLighting();
 				img->render(r);
+				renderbackend->enableLighting();
+			}
 		}
 	}
 
+	GenericRendererResizeInfo::GenericRendererResizeInfo(GenericRendererNode anchor, int image, int width, int height):
+		GenericRendererElementInfo(),
+		m_anchor(anchor),
+		m_image(image),
+		m_width(width),
+		m_height(height){
+	}
+	void GenericRendererResizeInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
+		Point p = m_anchor.getCalculatedPoint(cam, layer);
+		if(m_anchor.getLayer() == layer) {
+			Image* img = &imagepool->getImage(m_image);
+			Rect r;
+			r.x = p.x-m_width/2;
+			r.y = p.y-m_height/2;
+			r.w = m_width;
+			r.h = m_height;
+			renderbackend->disableLighting();
+			img->render(r);
+			renderbackend->enableLighting();
+		}
+	}
+	
 	GenericRenderer* GenericRenderer::getInstance(IRendererContainer* cnt) {
 		return dynamic_cast<GenericRenderer*>(cnt->getRenderer("GenericRenderer"));
 	}
@@ -440,7 +465,10 @@
 		GenericRendererElementInfo* info = new GenericRendererAnimationInfo(n, animation);
 		m_groups[group].push_back(info);
 	}
-
+	void GenericRenderer::resizeImage(const std::string &group, GenericRendererNode n, int image, int width, int height) {
+		GenericRendererElementInfo* info = new GenericRendererResizeInfo(n, image, width, height);
+		m_groups[group].push_back(info);
+	}
 	void GenericRenderer::removeAll(const std::string &group) {
 		std::vector<GenericRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
 		for (;info_it != m_groups[group].end(); ++info_it) {
--- a/engine/core/view/renderers/genericrenderer.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/renderers/genericrenderer.h	Fri Nov 05 15:21:10 2010 +0000
@@ -188,6 +188,17 @@
 		AbstractFont* m_font;
 		std::string m_text;
 	};
+	class GenericRendererResizeInfo : public GenericRendererElementInfo {
+	public:
+		void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool);
+		GenericRendererResizeInfo(GenericRendererNode n, int image, int width, int height);
+		virtual ~GenericRendererResizeInfo() {};
+	private:
+		GenericRendererNode m_anchor;
+		int m_image;
+		int m_width;
+		int m_height;
+	};
 	class GenericRenderer: public RendererBase {
 	public:
 		/** constructor.
@@ -218,6 +229,7 @@
 		void addText(const std::string &group, GenericRendererNode n, AbstractFont* font, const std::string &text);
 		void addImage(const std::string &group, GenericRendererNode n, int image);
 		void addAnimation(const std::string &group, GenericRendererNode n, int animation);
+		void resizeImage(const std::string &group, GenericRendererNode n, int image, int width, int height);
 		void removeAll(const std::string &group);
 
 	private:
--- a/engine/core/view/renderers/genericrenderer.i	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/renderers/genericrenderer.i	Fri Nov 05 15:21:10 2010 +0000
@@ -164,6 +164,16 @@
 		AbstractFont* m_font;
 		std::string m_text;
 	};
+	class GenericRendererResizeInfo : public GenericRendererElementInfo {
+	public:
+		GenericRendererResizeInfo(GenericRendererNode n, int image, int width, int height);
+		virtual ~GenericRendererResizeInfo() {};
+	private:
+		GenericRendererNode m_anchor;
+		int m_image;
+		int m_width;
+		int m_height;
+	};
 	class GenericRenderer: public RendererBase {
 	public:
 		GenericRenderer(RenderBackend* renderbackend, int position, ImagePool* imagepool, AnimationPool* animpool);
@@ -178,6 +188,7 @@
 		void addText(const std::string &group, GenericRendererNode n, AbstractFont* font, const std::string &text);
 		void addImage(const std::string &group, GenericRendererNode n, int image);
 		void addAnimation(const std::string &group, GenericRendererNode n, int animation);
+		void resizeImage(const std::string &group, GenericRendererNode n, int image, int width, int height);
 		void removeAll(const std::string &group);
 	};
 }
--- a/engine/core/view/renderers/gridrenderer.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/renderers/gridrenderer.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -73,6 +73,7 @@
 			FL_WARN(_log, "No cellgrid assigned to layer, cannot draw grid");
 			return;
 		}
+		m_renderbackend->disableLighting();
 //
 //
 //		//render elev_coord box
@@ -180,6 +181,7 @@
 				}
 			}
 		}
+		m_renderbackend->enableLighting();
 	}
 
 	void GridRenderer::setColor(Uint8 r, Uint8 g, Uint8 b) {
--- a/engine/core/view/renderers/instancerenderer.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/renderers/instancerenderer.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -40,11 +40,13 @@
 #include "model/structures/instance.h"
 #include "model/structures/layer.h"
 #include "model/structures/location.h"
+#include "video/opengl/fife_opengl.h"
 
 #include "view/camera.h"
 #include "view/visual.h"
 #include "instancerenderer.h"
 
+
 namespace {
 	unsigned int scale(unsigned int val, double factor) {
 		return static_cast<unsigned int>(ceil(static_cast<double>(val) * factor));
@@ -129,6 +131,8 @@
 		}
 
 		const bool any_effects = !(m_instance_outlines.empty() && m_instance_colorings.empty());
+		const bool unlit = !m_unlit_groups.empty();
+		unsigned int lm = m_renderbackend->getLightingModel();
 
 		m_area_layer = false;
 		if(!m_instance_areas.empty()) {
@@ -185,17 +189,56 @@
 			if (any_effects) {
 				InstanceToOutlines_t::iterator outline_it = m_instance_outlines.find(instance);
 				if (outline_it != m_instance_outlines.end()) {
+					if (lm != 0) {
+						m_renderbackend->disableLighting();
+						m_renderbackend->setStencilTest(255, 2, 7);
+						m_renderbackend->setAlphaTest(0.0);
+						bindOutline(outline_it->second, vc, cam)->render(vc.dimensions, vc.transparency);
+						m_renderbackend->enableLighting();
+						m_renderbackend->setStencilTest(0, 2, 7);
+						vc.image->render(vc.dimensions, vc.transparency);
+						m_renderbackend->disableAlphaTest();
+						m_renderbackend->disableStencilTest();
+						continue;
+					}
 					bindOutline(outline_it->second, vc, cam)->render(vc.dimensions, vc.transparency);
 				}
 
 				InstanceToColoring_t::iterator coloring_it = m_instance_colorings.find(instance);
 				if (coloring_it != m_instance_colorings.end()) {
+					m_renderbackend->disableLighting();
 					bindColoring(coloring_it->second, vc, cam)->render(vc.dimensions, vc.transparency);
+					m_renderbackend->enableLighting();
 					continue; // Skip normal rendering after drawing overlay
 				}
 			}
+			if(lm != 0) {
+				if(unlit) {
+					bool found = false;
+					std::string lit_name = instance->getObject()->getNamespace();
+					std::list<std::string>::iterator unlit_it = m_unlit_groups.begin();
+					for(;unlit_it != m_unlit_groups.end(); ++unlit_it) {
+						if(lit_name.find(*unlit_it) != -1) {
+							m_renderbackend->setStencilTest(255, 2, 7);
+							found = true;
+							break;
+						}
+					}
+					// This is very expensiv, we have to change it
+					if(!found)
+						m_renderbackend->setStencilTest(0, 1, 7);
 
+					m_renderbackend->setAlphaTest(0.0);
+					vc.image->render(vc.dimensions, vc.transparency);
+					continue;
+				}
+			}
 			vc.image->render(vc.dimensions, vc.transparency);
+
+		}
+		if(lm != 0) {
+			m_renderbackend->disableAlphaTest();
+			m_renderbackend->disableStencilTest();
 		}
 	}
 
@@ -422,10 +465,37 @@
 		m_instance_areas.clear();
 	}
 
+	void InstanceRenderer::addIgnoreLight(const std::list<std::string> &groups) {
+		std::list<std::string>::const_iterator group_it = groups.begin();
+		for(;group_it != groups.end(); ++group_it) {
+			m_unlit_groups.push_back(*group_it);
+		}
+		m_unlit_groups.sort();
+		m_unlit_groups.unique();
+	}
+
+	void InstanceRenderer::removeIgnoreLight(const std::list<std::string> &groups) {
+		std::list<std::string>::const_iterator group_it = groups.begin();
+		for(;group_it != groups.end(); ++group_it) {
+			std::list<std::string>::iterator unlit_it = m_unlit_groups.begin();
+			for(;unlit_it != m_unlit_groups.end(); ++unlit_it) {
+				if((*group_it).find(*unlit_it) != -1) {
+					m_unlit_groups.remove(*unlit_it);
+					break;
+				}
+			}
+		}
+	}
+
+	void InstanceRenderer::removeAllIgnoreLight() {
+		m_unlit_groups.clear();
+	}
+
 	void InstanceRenderer::reset() {
 		removeAllOutlines();
 		removeAllColored();
 		removeAllTransparentAreas();
+		removeAllIgnoreLight();
 	}
 
 }
--- a/engine/core/view/renderers/instancerenderer.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/renderers/instancerenderer.h	Fri Nov 05 15:21:10 2010 +0000
@@ -95,9 +95,26 @@
 		 */
 		void removeAllTransparentAreas();
 		
+		/** Add groups(Namespaces) into a list. All instances, whose namespace is in the list
+		 *  will not lighted from the LightRenderer.
+		 */
+		void addIgnoreLight(const std::list<std::string> &groups);
+
+		/** Removes groups(Namespaces) from the list
+		 */
+		void removeIgnoreLight(const std::list<std::string> &groups);
+
+		/** Removes all groups(Namespaces)
+		 */
+		void removeAllIgnoreLight();
+
 		/** Gets instance for interface access
 		 */
 		static InstanceRenderer* getInstance(IRendererContainer* cnt);
+
+		/** Provides access point to the RenderBackend
+		 */
+		RenderBackend* getRenderBackend() const {return m_renderbackend;}
 		
 		void reset();
 
@@ -105,6 +122,7 @@
 		ImagePool* m_imagepool;
 		AnimationPool* m_animationpool;
 		bool m_area_layer;
+		std::list<std::string> m_unlit_groups;
 		
 		// contains per-instance information for outline drawing
 		class OutlineInfo {
--- a/engine/core/view/renderers/instancerenderer.i	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/renderers/instancerenderer.i	Fri Nov 05 15:21:10 2010 +0000
@@ -43,6 +43,9 @@
 		void addTransparentArea(Instance* instance, const std::list<std::string> &groups, unsigned int w, unsigned int h, unsigned char trans, bool front = true);
 		void removeTransparentArea(Instance* instance);
 		void removeAllTransparentAreas();
+		void addIgnoreLight(const std::list<std::string> &groups);
+		void removeIgnoreLight(const std::list<std::string> &groups);
+		void removeAllIgnoreLight();
 		static InstanceRenderer* getInstance(IRendererContainer* cnt);
 	private:
 		InstanceRenderer(RenderBackend* renderbackend, int position, ImagePool* imagepool, AnimationPool* animpool);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/core/view/renderers/lightrenderer.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -0,0 +1,555 @@
+/***************************************************************************
+ *   Copyright (C) 2005-2008 by the FIFE team                              *
+ *   http://www.fifengine.de                                               *
+ *   This file is part of FIFE.                                            *
+ *                                                                         *
+ *   FIFE is free software; you can redistribute it and/or                 *
+ *   modify it under the terms of the GNU Lesser General Public            *
+ *   License as published by the Free Software Foundation; either          *
+ *   version 2.1 of the License, or (at your option) any later version.    *
+ *                                                                         *
+ *   This library is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
+ *   Lesser General Public License for more details.                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU Lesser General Public      *
+ *   License along with this library; if not, write to the                 *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+// Standard C++ library includes
+#include <SDL.h>
+
+// 3rd party library includes
+
+// FIFE includes
+// These includes are split up in two parts, separated by one empty line
+// First block: files included from the FIFE root src directory
+// Second block: files included from the same folder
+#include "video/renderbackend.h"
+#include "video/imagepool.h"
+#include "video/animation.h"
+#include "video/animationpool.h"
+#include "video/fonts/abstractfont.h"
+#include "video/image.h"
+#include "video/opengl/glimage.h"
+#include "util/math/fife_math.h"
+#include "util/log/logger.h"
+#include "util/time/timemanager.h"
+#include "model/metamodel/grids/cellgrid.h"
+#include "model/metamodel/timeprovider.h"
+#include "model/structures/instance.h"
+#include "model/structures/layer.h"
+#include "model/structures/location.h"
+
+#include "view/camera.h"
+#include "lightrenderer.h"
+
+
+namespace FIFE {
+	static Logger _log(LM_VIEWVIEW);
+
+	LightRendererNode::LightRendererNode(Instance* attached_instance, const Location &relative_location, Layer* relative_layer, const Point &relative_point):
+		m_instance(attached_instance),
+		m_location(relative_location),
+		m_layer(relative_layer),
+		m_point(relative_point) {
+	}
+	LightRendererNode::LightRendererNode(Instance* attached_instance, const Location &relative_location, const Point &relative_point):
+		m_instance(attached_instance),
+		m_location(relative_location),
+		m_layer(NULL),
+		m_point(relative_point) {
+	}
+	LightRendererNode::LightRendererNode(Instance* attached_instance, Layer* relative_layer, const Point &relative_point):
+		m_instance(attached_instance),
+		m_location(NULL),
+		m_layer(relative_layer),
+		m_point(relative_point) {
+	}
+	LightRendererNode::LightRendererNode(Instance* attached_instance, const Point &relative_point):
+		m_instance(attached_instance),
+		m_location(NULL),
+		m_layer(NULL),
+		m_point(relative_point) {
+	}
+	LightRendererNode::LightRendererNode(const Location &attached_location, Layer* relative_layer, const Point &relative_point):
+		m_instance(NULL),
+		m_location(attached_location),
+		m_layer(relative_layer),
+		m_point(relative_point) {
+	}
+	LightRendererNode::LightRendererNode(const Location &attached_location, const Point &relative_point):
+		m_instance(NULL),
+		m_location(attached_location),
+		m_layer(NULL),
+		m_point(relative_point) {
+	}
+	LightRendererNode::LightRendererNode(Layer* attached_layer, const Point &relative_point):
+		m_instance(NULL),
+		m_location(NULL),
+		m_layer(attached_layer),
+		m_point(relative_point) {
+	}
+	LightRendererNode::LightRendererNode(const Point &attached_point):
+		m_instance(NULL),
+		m_location(NULL),
+		m_layer(NULL),
+		m_point(attached_point) {
+	}
+	LightRendererNode::~LightRendererNode() {
+	}
+
+	void LightRendererNode::setAttached(Instance* attached_instance, const Location &relative_location, const Point &relative_point) {
+		m_instance = attached_instance;
+		m_location = relative_location;
+		m_point = relative_point;
+	}
+	void LightRendererNode::setAttached(Instance* attached_instance, const Location &relative_location) {
+		m_instance = attached_instance;
+		m_location = relative_location;
+	}
+	void LightRendererNode::setAttached(Instance* attached_instance, const Point &relative_point) {
+		m_instance = attached_instance;
+		m_point = relative_point;
+	}
+	void LightRendererNode::setAttached(Instance* attached_instance) {
+		m_instance = attached_instance;
+	}
+	void LightRendererNode::setAttached(const Location &attached_location, const Point &relative_point) {
+		m_instance = NULL;
+		m_location = attached_location;
+		m_point = relative_point;
+	}
+	void LightRendererNode::setAttached(const Location &attached_location) {
+		m_instance = NULL;
+		m_location = attached_location;
+	}
+	void LightRendererNode::setAttached(Layer* attached_layer) {
+		m_layer = attached_layer;
+	}
+	void LightRendererNode::setAttached(const Point &attached_point) {
+		m_instance = NULL;
+		m_location = NULL;
+		m_point = attached_point;
+	}
+
+	void LightRendererNode::setRelative(const Location &relative_location) {
+		if(m_instance == NULL) {
+			throw NotSupported("No instance attached.");
+		}
+		m_location = relative_location;
+	}
+	void LightRendererNode::setRelative(const Location &relative_location, Point relative_point) {
+		if(m_instance == NULL) {
+			throw NotSupported("No instance attached.");
+		}
+		m_location = relative_location;
+		m_point = relative_point;
+	}
+	void LightRendererNode::setRelative(const Point &relative_point) {
+		if(m_instance == NULL || m_location == NULL) {
+			throw NotSupported("No instance or location attached.");
+		}
+		m_point = relative_point;
+	}
+
+	Instance* LightRendererNode::getAttachedInstance() {
+		if(m_instance == NULL) {
+			throw NotSupported("No instance attached.");
+		}
+		return m_instance;
+	}
+	Location LightRendererNode::getAttachedLocation() {
+		if(m_instance != NULL || m_location == NULL) {
+			throw NotSupported("No location attached.");
+		}
+		return m_location;
+	}
+	Layer* LightRendererNode::getAttachedLayer() {
+		if(m_layer == NULL) {
+			throw NotSupported("No layer attached.");
+		}
+		return m_layer;
+	}
+	Point LightRendererNode::getAttachedPoint() {
+		if(m_instance != NULL || m_location != NULL) {
+			throw NotSupported("No point attached.");
+		}
+		return m_point;
+	}
+
+	Location LightRendererNode::getOffsetLocation() {
+		if(m_instance == NULL || m_location == NULL) {
+			throw NotSupported("No location as offset used.");
+		}
+		return m_location;
+	}
+	Point LightRendererNode::getOffsetPoint() {
+		if(m_instance == NULL && m_location == NULL) {
+			throw NotSupported("No point as offset used.");
+		}
+		return m_point;
+	}
+
+	Instance* LightRendererNode::getInstance() {
+		return m_instance;
+	}
+	Location LightRendererNode::getLocation() {
+		return m_location;
+	}
+	Layer* LightRendererNode::getLayer() {
+		return m_layer;
+	}
+	Point LightRendererNode::getPoint() {
+		return m_point;
+	}
+
+	Point LightRendererNode::getCalculatedPoint(Camera* cam, Layer* layer) {
+		ScreenPoint p;
+		if(m_instance != NULL) {
+			if(m_layer == NULL) {
+				m_layer = m_instance->getLocation().getLayer();
+			}
+			if(m_location != NULL) {
+				p = cam->toScreenCoordinates(m_instance->getLocationRef().getMapCoordinates() + m_location.getMapCoordinates());
+			} else {
+				p = cam->toScreenCoordinates(m_instance->getLocation().getMapCoordinates());
+			}
+		} else if(m_location != NULL) {
+			if(m_layer == NULL) {
+				m_layer = m_location.getLayer();
+			}
+			p = cam->toScreenCoordinates(m_location.getMapCoordinates());
+		} else if(m_layer == NULL) {
+			const std::list<Layer*>& layers = cam->getRenderer("LightRenderer")->getActiveLayers();
+			std::list<Layer*>::const_reverse_iterator layer_it = layers.rbegin();
+			setAttached(*layer_it);
+		}
+		return Point(m_point.x + p.x, m_point.y + p.y);
+	}
+
+	LightRendererImageInfo::LightRendererImageInfo(LightRendererNode anchor, int image, int src, int dst):
+		LightRendererElementInfo(),
+		m_anchor(anchor),
+		m_image(image),
+		m_src(src),
+		m_dst(dst),
+		m_stencil(false),
+		m_stencil_ref(0),
+		m_alpha_ref(0.0) {
+	}
+	void LightRendererImageInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
+		Point p = m_anchor.getCalculatedPoint(cam, layer);
+		if(m_anchor.getLayer() == layer) {
+			Image* img = &imagepool->getImage(m_image);
+			Rect r;
+			Rect viewport = cam->getViewPort();
+			r.x = p.x-img->getWidth()/2;
+			r.y = p.y-img->getHeight()/2;
+			r.w = img->getWidth();
+			r.h = img->getHeight();
+			renderbackend->changeBlending(m_src, m_dst);
+			if(r.intersects(viewport))
+				img->render(r);
+		}
+	}
+	void LightRendererImageInfo::setStencil(uint8_t stencil_ref, float alpha_ref) {
+		m_stencil = true;
+		m_stencil_ref = stencil_ref;
+		m_alpha_ref = alpha_ref;
+	}
+	int LightRendererImageInfo::getStencil() {
+		if(!m_stencil) {
+			return -1;
+		}
+		return m_stencil_ref;
+	}
+	float LightRendererImageInfo::getAlpha() {
+		return m_alpha_ref;
+	}
+	void LightRendererImageInfo::removeStencil() {
+		m_stencil = false;
+		m_stencil_ref = 0;
+		m_alpha_ref = 0.0;
+	}
+	
+	LightRendererAnimationInfo::LightRendererAnimationInfo(LightRendererNode anchor, int animation, int src, int dst):
+		LightRendererElementInfo(),
+		m_anchor(anchor),
+		m_animation(animation),
+		m_src(src),
+		m_dst(dst),
+		m_start_time(TimeManager::instance()->getTime()),
+		m_time_scale(1.0),
+		m_stencil(false),
+		m_stencil_ref(0),
+		m_alpha_ref(0.0) {
+	}
+	void LightRendererAnimationInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) { 
+		Point p = m_anchor.getCalculatedPoint(cam, layer);
+		if(m_anchor.getLayer() == layer) {
+			Animation& animation = animpool->getAnimation(m_animation);
+			int animtime = scaleTime(m_time_scale, TimeManager::instance()->getTime() - m_start_time) % animation.getDuration();
+			Image* img = animation.getFrameByTimestamp(animtime);
+			Rect r;
+			Rect viewport = cam->getViewPort();
+			r.x = p.x-img->getWidth()/2;
+			r.y = p.y-img->getHeight()/2;
+			r.w = img->getWidth();
+			r.h = img->getHeight();
+			renderbackend->changeBlending(m_src, m_dst);
+			if(r.intersects(viewport))
+				img->render(r);
+		}
+	}
+	void LightRendererAnimationInfo::setStencil(uint8_t stencil_ref, float alpha_ref) {
+		m_stencil = true;
+		m_stencil_ref = stencil_ref;
+		m_alpha_ref = alpha_ref;
+	}
+	int LightRendererAnimationInfo::getStencil() {
+		if(!m_stencil) {
+			return -1;
+		}
+		return m_stencil_ref;
+	}
+	float LightRendererAnimationInfo::getAlpha() {
+		return m_alpha_ref;
+	}
+	void LightRendererAnimationInfo::removeStencil() {
+		m_stencil = false;
+		m_stencil_ref = 0;
+		m_alpha_ref = 0.0;
+	}
+
+	LightRendererResizeInfo::LightRendererResizeInfo(LightRendererNode anchor, int image, int width, int height, int src, int dst):
+		LightRendererElementInfo(),
+		m_anchor(anchor),
+		m_image(image),
+		m_width(width),
+		m_height(height),
+		m_src(src),
+		m_dst(dst),
+		m_stencil(false),
+		m_stencil_ref(0),
+		m_alpha_ref(0.0) {
+	}
+	void LightRendererResizeInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
+		Point p = m_anchor.getCalculatedPoint(cam, layer);
+		if(m_anchor.getLayer() == layer) {
+			Image* img = &imagepool->getImage(m_image);
+			Rect r;
+			Rect viewport = cam->getViewPort();
+			r.x = p.x-m_width/2;
+			r.y = p.y-m_height/2;
+			r.w = m_width;
+			r.h = m_height;
+			renderbackend->changeBlending(m_src, m_dst);
+			if(r.intersects(viewport))
+				img->render(r);
+		}
+	}
+	void LightRendererResizeInfo::setStencil(uint8_t stencil_ref, float alpha_ref) {
+		m_stencil = true;
+		m_stencil_ref = stencil_ref;
+		m_alpha_ref = alpha_ref;
+	}
+	int LightRendererResizeInfo::getStencil() {
+		if(!m_stencil) {
+			return -1;
+		}
+		return m_stencil_ref;
+	}
+	float LightRendererResizeInfo::getAlpha() {
+		return m_alpha_ref;
+	}
+	void LightRendererResizeInfo::removeStencil() {
+		m_stencil = false;
+		m_stencil_ref = 0;
+		m_alpha_ref = 0.0;
+	}
+
+	LightRendererSimpleLightInfo::LightRendererSimpleLightInfo(LightRendererNode anchor, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t r, uint8_t g, uint8_t b, int src, int dst):
+		LightRendererElementInfo(),
+		m_anchor(anchor),
+		m_intensity(intensity),
+		m_radius(radius),
+		m_subdivisions(subdivisions),
+		m_xstretch(xstretch),
+		m_ystretch(ystretch),
+		m_red(r),
+		m_green(g),
+		m_blue(b),
+		m_src(src),
+		m_dst(dst),
+		m_stencil(false),
+		m_stencil_ref(0),
+		m_alpha_ref(0.0) {
+	}
+	void LightRendererSimpleLightInfo::render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {
+		Point p = m_anchor.getCalculatedPoint(cam, layer);
+		if(m_anchor.getLayer() == layer) {
+			renderbackend->changeBlending(m_src, m_dst);
+			renderbackend->drawLightPrimitive(p, m_intensity, m_radius, m_subdivisions, m_xstretch, m_ystretch, m_red, m_green, m_blue);
+		}
+	}
+	void LightRendererSimpleLightInfo::setStencil(uint8_t stencil_ref, float alpha_ref) {
+		m_stencil = true;
+		m_stencil_ref = stencil_ref;
+		m_alpha_ref = alpha_ref;
+	}
+	int LightRendererSimpleLightInfo::getStencil() {
+		if(!m_stencil) {
+			return -1;
+		}
+		return m_stencil_ref;
+	}
+	float LightRendererSimpleLightInfo::getAlpha() {
+		return m_alpha_ref;
+	}
+	void LightRendererSimpleLightInfo::removeStencil() {
+		m_stencil = false;
+		m_stencil_ref = 0;
+		m_alpha_ref = 0.0;
+	}
+	std::vector<uint8_t> LightRendererSimpleLightInfo::getColor() {
+		std::vector<uint8_t> colors;
+		colors.push_back(m_red);
+		colors.push_back(m_green);
+		colors.push_back(m_blue);
+		colors.push_back(m_intensity);
+		return colors;
+	}
+
+	LightRenderer* LightRenderer::getInstance(IRendererContainer* cnt) {
+		return dynamic_cast<LightRenderer*>(cnt->getRenderer("LightRenderer"));
+	}
+	
+	LightRenderer::LightRenderer(RenderBackend* renderbackend, int position, ImagePool* imagepool, AnimationPool* animpool):
+		RendererBase(renderbackend, position),
+		m_imagepool(imagepool),
+		m_animationpool(animpool),
+		m_groups() {
+		setEnabled(false);
+	}
+
+	LightRenderer::LightRenderer(const LightRenderer& old):
+		RendererBase(old),
+		m_imagepool(old.m_imagepool),
+		m_animationpool(old.m_animationpool),
+		m_groups() {
+		setEnabled(false);
+	}
+
+	RendererBase* LightRenderer::clone() {
+		return new LightRenderer(*this);
+	}
+
+	LightRenderer::~LightRenderer() {
+	}
+	// Add a static lightmap
+	void LightRenderer::addImage(const std::string &group, LightRendererNode n, int image, int src, int dst) {
+		LightRendererElementInfo* info = new LightRendererImageInfo(n, image, src, dst);
+		m_groups[group].push_back(info);
+	}
+	// Add a animation lightmap
+	void LightRenderer::addAnimation(const std::string &group, LightRendererNode n, int animation, int src, int dst) {
+		LightRendererElementInfo* info = new LightRendererAnimationInfo(n, animation, src, dst);
+		m_groups[group].push_back(info);
+	}
+	// Add a simple light
+	void LightRenderer::addSimpleLight(const std::string &group, LightRendererNode n, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t r, uint8_t g, uint8_t b, int src, int dst) {
+		LightRendererElementInfo* info = new LightRendererSimpleLightInfo(n, intensity, radius, subdivisions, xstretch, ystretch, r, g, b, src, dst);
+		m_groups[group].push_back(info);
+	}
+	// Resize an Image
+	void LightRenderer::resizeImage(const std::string &group, LightRendererNode n, int image, int width, int height, int src, int dst) {
+		LightRendererElementInfo* info = new LightRendererResizeInfo(n, image, width, height, src, dst);
+		m_groups[group].push_back(info);
+	}
+	// Enable stencil test for the group
+	void LightRenderer::addStencilTest(const std::string &group, uint8_t stencil_ref, float alpha_ref) {
+		std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
+		for (;info_it != m_groups[group].end(); ++info_it) {
+			(*info_it)->setStencil(stencil_ref, alpha_ref);
+		}
+	}
+	// Disable stencil test for the group
+	void LightRenderer::removeStencilTest(const std::string &group) {
+		std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
+		for (;info_it != m_groups[group].end(); ++info_it) {
+			(*info_it)->removeStencil();
+		}
+	}
+	// Return a list of all groups
+	std::list<std::string> LightRenderer::getGroups() {
+		std::list<std::string> groups;
+		std::map<std::string, std::vector<LightRendererElementInfo*> >::iterator group_it = m_groups.begin();
+		for(; group_it != m_groups.end(); ++group_it) {
+			groups.push_back(group_it->first);
+		}
+		groups.sort();
+		groups.unique();
+		return groups;
+	}
+	// Return a vector of all LightElementInfos
+	std::vector<LightRendererElementInfo*> LightRenderer::getLightInfo(const std::string &group) {
+		std::vector<LightRendererElementInfo*> info;
+		std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
+		for (;info_it != m_groups[group].end(); ++info_it) {
+			info.push_back(*info_it);
+		}
+		return info;
+	}
+	// Remove the group
+	void LightRenderer::removeAll(const std::string &group) {
+		std::vector<LightRendererElementInfo*>::const_iterator info_it = m_groups[group].begin();
+		for (;info_it != m_groups[group].end(); ++info_it) {
+			delete *info_it;
+		}
+		m_groups[group].clear();
+		m_groups.erase(group);
+	}
+	// Render
+	void LightRenderer::render(Camera* cam, Layer* layer, RenderList& instances) {
+		uint8_t lm = m_renderbackend->getLightingModel();
+		
+		if (!layer->areInstancesVisible()) {
+			return;
+		}
+		m_renderbackend->disableLighting();
+		std::map<std::string, std::vector<LightRendererElementInfo*> >::iterator group_it = m_groups.begin();
+		for (; group_it != m_groups.end(); ++group_it) {
+			std::vector<LightRendererElementInfo*>::const_iterator info_it = group_it->second.begin();
+			for (;info_it != group_it->second.end(); ++info_it) {
+				if (lm != 0) {
+					if ((*info_it)->getStencil() != -1) {
+						uint8_t sref = (*info_it)->getStencil();
+						float aref = (*info_it)->getAlpha();
+						if(info_it != group_it->second.begin())
+							sref += 1;
+						m_renderbackend->setStencilTest(sref, 3, 4);
+						m_renderbackend->setAlphaTest(aref);
+					} else if(lm == 1) {
+						m_renderbackend->setStencilTest(255, 0, 6);
+						m_renderbackend->setAlphaTest(0);
+					} else if(lm == 2) {
+						m_renderbackend->setStencilTest(1, 2, 4);
+						m_renderbackend->setAlphaTest(0);
+					}
+					(*info_it)->render(cam, layer, instances, m_renderbackend, m_imagepool, m_animationpool);
+					m_renderbackend->disableAlphaTest();
+					m_renderbackend->disableStencilTest();
+				} else {
+					(*info_it)->render(cam, layer, instances, m_renderbackend, m_imagepool, m_animationpool);
+				}
+			}
+		}
+		m_renderbackend->changeBlending(4, 5);
+		m_renderbackend->enableLighting();
+	}
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/core/view/renderers/lightrenderer.h	Fri Nov 05 15:21:10 2010 +0000
@@ -0,0 +1,255 @@
+/***************************************************************************
+ *   Copyright (C) 2005-2008 by the FIFE team                              *
+ *   http://www.fifengine.de                                               *
+ *   This file is part of FIFE.                                            *
+ *                                                                         *
+ *   FIFE is free software; you can redistribute it and/or                 *
+ *   modify it under the terms of the GNU Lesser General Public            *
+ *   License as published by the Free Software Foundation; either          *
+ *   version 2.1 of the License, or (at your option) any later version.    *
+ *                                                                         *
+ *   This library is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
+ *   Lesser General Public License for more details.                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU Lesser General Public      *
+ *   License along with this library; if not, write to the                 *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+#ifndef FIFE_LIGHTRENDERER_H
+#define FIFE_LIGHTRENDERER_H
+
+// Standard C++ library includes
+#include <vector>
+
+// 3rd party library includes
+
+// FIFE includes
+// These includes are split up in two parts, separated by one empty line
+// First block: files included from the FIFE root src directory
+// Second block: files included from the same folder
+#include "view/rendererbase.h"
+
+namespace FIFE {
+	class RenderBackend;
+	class AbstractFont;
+	class ImagePool;
+	class AnimationPool;
+
+	class LightRendererNode {
+	public:
+		LightRendererNode(Instance* attached_instance, const Location &relative_location, Layer* relative_layer, const Point &relative_point = Point(0,0));
+		LightRendererNode(Instance* attached_instance, const Location &relative_location, const Point &relative_point = Point(0,0));
+		LightRendererNode(Instance* attached_instance, Layer* relative_layer, const Point &relative_point = Point(0,0));
+		LightRendererNode(Instance* attached_instance, const Point &relative_point = Point(0,0));
+		LightRendererNode(const Location &attached_location, Layer* relative_layer, const Point &relative_point = Point(0,0));
+		LightRendererNode(const Location &attached_location, const Point &relative_point = Point(0,0));
+		LightRendererNode(Layer* attached_layer, const Point &relative_point = Point(0,0));
+		LightRendererNode(const Point &attached_point);
+		~LightRendererNode();
+		
+		void setAttached(Instance* attached_instance, const Location &relative_location, const Point &relative_point);
+		void setAttached(Instance* attached_instance, const Location &relative_location);
+		void setAttached(Instance* attached_instance, const Point &relative_point);
+		void setAttached(Instance* attached_instance);
+		void setAttached(const Location &attached_location, const Point &relative_point);
+		void setAttached(const Location &attached_location);
+		void setAttached(Layer* attached_layer);
+		void setAttached(const Point &attached_point);
+		
+		void setRelative(const Location &relative_location);
+		void setRelative(const Location &relative_location, Point relative_point);
+		void setRelative(const Point &relative_point);
+		
+		Instance* getAttachedInstance();
+		Location getAttachedLocation();
+		Layer* getAttachedLayer();
+		Point getAttachedPoint();
+		
+		Location getOffsetLocation();
+		Point getOffsetPoint();
+		
+		Instance* getInstance();
+		Location getLocation();
+		Layer* getLayer();
+		Point getPoint();
+
+		Point getCalculatedPoint(Camera* cam, Layer* layer);
+	private:
+		Instance* m_instance;
+		Location m_location;
+		Layer* m_layer;
+		Point m_point;
+	};
+
+	class LightRendererElementInfo {
+	public:
+		virtual void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool) {};
+		virtual std::string getName() { return 0; };
+		virtual LightRendererNode* getNode() { return NULL; };
+		virtual int getId() { return -1; };
+		virtual int getSrcBlend() { return -1; };
+		virtual int getDstBlend() { return -1; };
+		virtual void setStencil(uint8_t stencil_ref, float alpha_ref) {};
+		virtual int getStencil() { return 0; };
+		virtual float getAlpha() { return 0; };
+		virtual void removeStencil() {};
+		virtual std::vector<uint8_t> getColor() {};
+		virtual float getRadius() { return 0; };
+		virtual int getSubdivisions() { return 0; };
+		virtual float getXStretch() { return 0; };
+		virtual float getYStretch() { return 0; };
+		virtual ~LightRendererElementInfo() {};
+	};
+
+	class LightRendererImageInfo : public LightRendererElementInfo {
+	public:
+		void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool);
+		std::string getName() { return "image"; };
+		LightRendererNode* getNode() { return &m_anchor; };
+		int getId() { return m_image; };
+		int getSrcBlend() { return m_src; };
+		int getDstBlend() { return m_dst; };
+		void setStencil(uint8_t stencil_ref, float alpha_ref);
+		int getStencil();
+		float getAlpha();
+		void removeStencil();
+		LightRendererImageInfo(LightRendererNode n, int image, int src, int dst);
+		virtual ~LightRendererImageInfo() {};
+	private:
+		LightRendererNode m_anchor;
+		int m_image;
+		int m_src;
+		int m_dst;
+		bool m_stencil;
+		uint8_t m_stencil_ref;
+		float m_alpha_ref;
+	};
+	class LightRendererAnimationInfo : public LightRendererElementInfo {
+	public:
+		void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool);
+		std::string getName() { return "animation"; };
+		LightRendererNode* getNode() { return &m_anchor; };
+		int getId() { return m_animation; };
+		int getSrcBlend() { return m_src; };
+		int getDstBlend() { return m_dst; };
+		void setStencil(uint8_t stencil_ref, float alpha_ref);
+		int getStencil();
+		float getAlpha();
+		void removeStencil();
+		LightRendererAnimationInfo(LightRendererNode n, int animation, int src, int dst);
+		virtual ~LightRendererAnimationInfo() {};
+	private:
+		LightRendererNode m_anchor;
+		int m_animation;
+		int m_src;
+		int m_dst;
+		unsigned int m_start_time;
+		float m_time_scale;
+		bool m_stencil;
+		uint8_t m_stencil_ref;
+		float m_alpha_ref;
+	};
+	class LightRendererSimpleLightInfo : public LightRendererElementInfo {
+	public:
+		void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool);
+		std::string getName() { return "simple"; };
+		LightRendererNode* getNode() { return &m_anchor; };
+		int getSrcBlend() { return m_src; };
+		int getDstBlend() { return m_dst; };
+		void setStencil(uint8_t stencil_ref, float alpha_ref);
+		int getStencil();
+		float getAlpha();
+		void removeStencil();
+		std::vector<uint8_t> getColor();
+		float getRadius() { return m_radius; };
+		int getSubdivisions() { return m_subdivisions; };
+		float getXStretch() { return m_xstretch; };
+		float getYStretch() { return m_ystretch; };
+		LightRendererSimpleLightInfo(LightRendererNode n, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t r, uint8_t g, uint8_t b, int src, int dst);
+		virtual ~LightRendererSimpleLightInfo() {};
+	private:
+		LightRendererNode m_anchor;
+		uint8_t m_intensity;
+		float m_radius;
+		int m_subdivisions;
+		float m_xstretch;
+		float m_ystretch;
+		uint8_t m_red;
+		uint8_t m_green;
+		uint8_t m_blue;
+		int m_src;
+		int m_dst;
+		bool m_stencil;
+		uint8_t m_stencil_ref;
+		float m_alpha_ref;
+	};
+	class LightRendererResizeInfo : public LightRendererElementInfo {
+	public:
+		void render(Camera* cam, Layer* layer, RenderList& instances, RenderBackend* renderbackend, ImagePool* imagepool, AnimationPool* animpool);
+		std::string getName() { return "resize"; };
+		LightRendererNode* getNode() { return &m_anchor; };
+		int getId() { return m_image; };
+		int getSrcBlend() { return m_src; };
+		int getDstBlend() { return m_dst; };
+		void setStencil(uint8_t stencil_ref, float alpha_ref);
+		int getStencil();
+		float getAlpha();
+		void removeStencil();
+		LightRendererResizeInfo(LightRendererNode n, int image, int width, int height, int src, int dst);
+		virtual ~LightRendererResizeInfo() {};
+	private:
+		LightRendererNode m_anchor;
+		int m_image;
+		int m_width;
+		int m_height;
+		int m_src;
+		int m_dst;
+		bool m_stencil;
+		uint8_t m_stencil_ref;
+		float m_alpha_ref;
+	};
+	class LightRenderer: public RendererBase {
+	public:
+		/** constructor.
+		 * @param renderbackend to use
+		 * @param position position for this renderer in rendering pipeline
+		 */
+		LightRenderer(RenderBackend* renderbackend, int position, ImagePool* imagepool, AnimationPool* animpool);
+		
+		LightRenderer(const LightRenderer& old);
+		
+		RendererBase* clone();
+
+		/** Destructor.
+		 */
+		virtual ~LightRenderer();
+		void render(Camera* cam, Layer* layer, RenderList& instances);
+		std::string getName() { return "LightRenderer"; }
+
+		/** Gets instance for interface access
+		 */
+		static LightRenderer* getInstance(IRendererContainer* cnt);
+
+		void addImage(const std::string &group, LightRendererNode n, int image, int src=-1, int dst=-1);
+		void addAnimation(const std::string &group, LightRendererNode n, int animation, int src=-1, int dst=-1);
+		void addSimpleLight(const std::string &group, LightRendererNode n, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t r, uint8_t g, uint8_t b, int src=-1, int dst=-1);
+		void resizeImage(const std::string &group, LightRendererNode n, int image, int width, int height, int src=-1, int dst=-1);
+		void addStencilTest(const std::string &group, uint8_t stencil_ref=0, float alpha_ref=0.0);
+		void removeStencilTest(const std::string &group);
+		std::list<std::string> getGroups();
+		std::vector<LightRendererElementInfo*> getLightInfo(const std::string &group);
+		void removeAll(const std::string &group);
+
+	private:
+		ImagePool* m_imagepool;
+		AnimationPool* m_animationpool;
+		std::map<std::string, std::vector<LightRendererElementInfo*> > m_groups;
+	};
+
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/core/view/renderers/lightrenderer.i	Fri Nov 05 15:21:10 2010 +0000
@@ -0,0 +1,175 @@
+/***************************************************************************
+ *   Copyright (C) 2005-2008 by the FIFE team                              *
+ *   http://www.fifengine.de                                               *
+ *   This file is part of FIFE.                                            *
+ *                                                                         *
+ *   FIFE is free software; you can redistribute it and/or                 *
+ *   modify it under the terms of the GNU Lesser General Public            *
+ *   License as published by the Free Software Foundation; either          *
+ *   version 2.1 of the License, or (at your option) any later version.    *
+ *                                                                         *
+ *   This library is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
+ *   Lesser General Public License for more details.                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU Lesser General Public      *
+ *   License along with this library; if not, write to the                 *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+%module fife
+%{
+#include "view/renderers/lightrenderer.h"
+%}
+
+namespace FIFE {
+	class RenderBackend;
+	
+	class LightRendererNode {
+	public:
+		LightRendererNode(Instance* attached_instance, const Location &relative_location, Layer* relative_layer, const Point &relative_point = Point(0,0));
+		LightRendererNode(Instance* attached_instance, const Location &relative_location, const Point &relative_point = Point(0,0));
+		LightRendererNode(Instance* attached_instance, Layer* relative_layer, const Point &relative_point = Point(0,0));
+		LightRendererNode(Instance* attached_instance, const Point &relative_point = Point(0,0));
+		LightRendererNode(const Location &attached_location, Layer* relative_layer, const Point &relative_point = Point(0,0));
+		LightRendererNode(const Location &attached_location, const Point &relative_point = Point(0,0));
+		LightRendererNode(Layer* attached_layer, const Point &relative_point = Point(0,0));
+		LightRendererNode(const Point &attached_point);
+		~LightRendererNode();
+		
+		void setAttached(Instance* attached_instance, const Location &relative_location, const Point &relative_point);
+		void setAttached(Instance* attached_instance, const Location &relative_location);
+		void setAttached(Instance* attached_instance, const Point &relative_point);
+		void setAttached(Instance* attached_instance);
+		void setAttached(const Location &attached_location, const Point &relative_point);
+		void setAttached(const Location &attached_location);
+		void setAttached(Layer* attached_layer);
+		void setAttached(const Point &attached_point);
+		
+		void setRelative(const Location &relative_location);
+		void setRelative(const Location &relative_location, Point relative_point);
+		void setRelative(const Point &relative_point);
+		
+		Instance* getAttachedInstance();
+		Location getAttachedLocation();
+		Layer* getAttachedLayer();
+		Point getAttachedPoint();
+		
+		Location getOffsetLocation();
+		Point getOffsetPoint();
+		
+		Instance* getInstance();
+		Location getLocation();
+		Layer* getLayer();
+		Point getPoint();
+
+		Point getCalculatedPoint(Camera* cam, Layer* layer);
+	private:
+		Instance* m_instance;
+		Location m_location;
+		Layer* m_layer;
+		Point m_point;
+	};
+	class LightRendererElementInfo {
+	public:
+		virtual std::string getName() { return 0; };
+		virtual LightRendererNode* getNode() { return NULL; };
+		virtual int getId() { return -1; };
+		virtual int getSrcBlend() { return -1; };
+		virtual int getDstBlend() { return -1; };
+		virtual void setStencil(uint8_t stencil_ref, float alpha_ref) {};
+		virtual int getStencil() { return 0; };
+		virtual float getAlpha() { return 0; };
+		virtual void removeStencil() {};
+		virtual std::vector<uint8_t> getColor() {};
+		virtual float getRadius() { return 0; };
+		virtual int getSubdivisions() { return 0; };
+		virtual float getXStretch() { return 0; };
+		virtual float getYStretch() { return 0; };
+		virtual ~LightRendererElementInfo() {};
+	};
+
+	class LightRendererImageInfo : public LightRendererElementInfo {
+	public:
+		LightRendererImageInfo(LightRendererNode n, int image, int src, int dst);
+		virtual ~LightRendererImageInfo() {};
+	private:
+		LightRendererNode m_anchor;
+		int m_image;
+		int m_src;
+		int m_dst;
+		bool m_stencil;
+		uint8_t m_stencil_ref;
+		float m_alpha_ref;
+	};
+	class LightRendererAnimationInfo : public LightRendererElementInfo {
+	public:
+		LightRendererAnimationInfo(LightRendererNode n, int animation, int src, int dst);
+		virtual ~LightRendererAnimationInfo() {};
+	private:
+		LightRendererNode m_anchor;
+		int m_animation;
+		int m_src;
+		int m_dst;
+		bool m_stencil;
+		uint8_t m_stencil_ref;
+		float m_alpha_ref;
+	};
+	class LightRendererSimpleLightInfo : public LightRendererElementInfo {
+	public:
+		LightRendererSimpleLightInfo(LightRendererNode n, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t r, uint8_t g, uint8_t b, int src, int dst);
+		virtual ~LightRendererSimpleLightInfo() {};
+	private:
+		LightRendererNode m_anchor;
+		uint8_t m_intensity;
+		float m_radius;
+		int m_subdivisions;
+		float m_xstretch;
+		float m_ystretch;
+		uint8_t m_red;
+		uint8_t m_green;
+		uint8_t m_blue;
+		int m_src;
+		int m_dst;
+		bool m_stencil;
+		uint8_t m_stencil_ref;
+		float m_alpha_ref;
+	};
+	class LightRendererResizeInfo : public LightRendererElementInfo {
+	public:
+		LightRendererResizeInfo(LightRendererNode n, int image, int width, int height, int src, int dst);
+		virtual ~LightRendererResizeInfo() {};
+	private:
+		LightRendererNode m_anchor;
+		int m_image;
+		int m_width;
+		int m_height;
+		int m_src;
+		int m_dst;
+		bool m_stencil;
+		uint8_t m_stencil_ref;
+		float m_alpha_ref;
+	};
+	class LightRenderer: public RendererBase {
+	public:
+		LightRenderer(RenderBackend* renderbackend, int position, ImagePool* imagepool, AnimationPool* animpool);
+		~LightRenderer();
+		std::string getName();
+		static LightRenderer* getInstance(IRendererContainer* cnt);
+		void addImage(const std::string &group, LightRendererNode n, int image, int src=-1, int dst=-1);
+		void addAnimation(const std::string &group, LightRendererNode n, int animation, int src=-1, int dst=-1);
+		void addSimpleLight(const std::string &group, LightRendererNode n, uint8_t intensity, float radius, int subdivisions, float xstretch, float ystretch, uint8_t r, uint8_t g, uint8_t b, int src=-1, int dst=-1);
+		void resizeImage(const std::string &group, LightRendererNode n, int image, int width, int height, int src=-1, int dst=-1);
+		void addStencilTest(const std::string &group, uint8_t stencil_ref=0, float alpha_ref=0.0);
+		void removeStencilTest(const std::string &group);
+		std::list<std::string> getGroups();
+		std::vector<LightRendererElementInfo*> getLightInfo(const std::string &group);
+		void removeAll(const std::string &group);
+	};
+}
+
+namespace std {
+	%template(LightRendererElementInfoVector) vector<FIFE::LightRendererElementInfo*>;	
+}
\ No newline at end of file
--- a/engine/core/view/renderers/quadtreerenderer.cpp	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/renderers/quadtreerenderer.cpp	Fri Nov 05 15:21:10 2010 +0000
@@ -90,10 +90,12 @@
 		emc= cg->toMapCoordinates(ExactModelCoordinate( x+size,y+size) );
 		ScreenPoint scrpt4 =m_camera->toScreenCoordinates( emc );
 
+		m_renderbackend->disableLighting();
 		m_renderbackend->drawLine( Point(scrpt1.x,scrpt1.y) , Point(scrpt2.x,scrpt2.y), 255, 255, 255);
 		m_renderbackend->drawLine(Point(scrpt1.x,scrpt1.y), Point(scrpt3.x,scrpt3.y), 255, 255, 255);
 		m_renderbackend->drawLine(Point(scrpt3.x,scrpt3.y), Point(scrpt4.x,scrpt4.y), 255, 255, 255);
 		m_renderbackend->drawLine(Point(scrpt2.x,scrpt2.y), Point(scrpt4.x,scrpt4.y), 255, 255, 255);
+		m_renderbackend->enableLighting();
 
 		return true;
 	}
--- a/engine/core/view/visual.h	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/core/view/visual.h	Fri Nov 05 15:21:10 2010 +0000
@@ -127,6 +127,7 @@
 		type_angle2id m_angle2img;
 	};
 
+
 	/** Instance visual contains data that is needed to visualize the instance on screen
 	 */
 	class InstanceVisual: public Visual2DGfx {
--- a/engine/python/fife/extensions/basicapplication.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/python/fife/extensions/basicapplication.py	Fri Nov 05 15:21:10 2010 +0000
@@ -113,6 +113,7 @@
 		engineSetting.setRenderBackend(self._setting.get("FIFE", "RenderBackend", "OpenGL"))
 		engineSetting.setFullScreen(self._setting.get("FIFE", "FullScreen", False))
 		engineSetting.setVideoDriver(self._setting.get("FIFE", "VideoDriver", ""))
+		engineSetting.setLightingModel(self._setting.get("FIFE", "Lighting", 0))
 
 		try:
 			engineSetting.setColorKeyEnabled(self._setting.get("FIFE", "ColorKeyEnabled", False))
--- a/engine/python/fife/extensions/fife_settings.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/python/fife/extensions/fife_settings.py	Fri Nov 05 15:21:10 2010 +0000
@@ -44,10 +44,12 @@
 		<VBox>
 			<Label text="Resolution:" />
 			<Label text="Renderer:" />
+			<Label text="Light Model:" />
 		</VBox>
 		<VBox min_size="120,60">
 			<DropDown name="screen_resolution" min_size="120,0" />
 			<DropDown name="render_backend" min_size="120,0" />
+			<DropDown name="lighting_model" min_size="120,0" />
 		</VBox>
 	</HBox>
 	<CheckBox name="enable_fullscreen" text="Use the full screen mode" />
@@ -140,6 +142,7 @@
 		#default settings
 		self._resolutions = ['640x480', '800x600', '1024x768', '1280x800', '1440x900']
 		self._renderbackends = ['OpenGL', 'SDL']
+		self._lightingmodels = [0, 1, 2]
 
 		#Used to stylize the options gui
 		self._gui_style = "default"
@@ -168,6 +171,8 @@
 		              requiresrestart=True)
 		self.createAndAddEntry(FIFE_MODULE, "RenderBackend", "render_backend", initialdata = self._renderbackends,
 		              requiresrestart=True)
+		self.createAndAddEntry(FIFE_MODULE, "Lighting", "lighting_model", initialdata = self._lightingmodels,
+		              requiresrestart=True)
 
 	def createAndAddEntry(self, module, name, widgetname, applyfunction=None, initialdata=None, requiresrestart=False):
 		""""
--- a/engine/python/fife/extensions/loaders.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/python/fife/extensions/loaders.py	Fri Nov 05 15:21:10 2010 +0000
@@ -1,7 +1,6 @@
 # -*- coding: utf-8 -*-
-
 # ####################################################################
-#  Copyright (C) 2005-2009 by the FIFE team
+#  Copyright (C) 2005-2010 by the FIFE team
 #  http://www.fifengine.de
 #  This file is part of FIFE.
 #
@@ -21,113 +20,44 @@
 #  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 # ####################################################################
 
-# Loader interface for FIFE's native xml format.
+""" Loader interface for FIFE's native xml format """
 
 import os.path
 
 from fife import fife
-
 from fife.extensions.serializers.xmlmap import XMLMapLoader
-from fife.extensions.serializers import WrongFileType, NameClash
 
-from fife.extensions.serializers.xmlobject import XMLObjectLoader
-
-objectFileMapping = { 'xml' : XMLObjectLoader }
 mapFileMapping = { 'xml' : XMLMapLoader}
 fileExtensions = ('xml',)
 mapFileExtensions = ('xml',)
 
-def loadMapFile(path, engine, callback=None, debug=True):
+def loadMapFile(path, engine, callback=None, debug=True, extensions={}):
 	""" load map file and get (an optional) callback if major stuff is done:
-	- map creation
-	- parsed imports
-	- parsed layers
-	- parsed cameras
-	the callback will send both a string and a float (which shows
-	the overall process), callback(string, float)
-
+	
+		- map creation
+		- parsed imports
+		- parsed layers 
+		- parsed cameras
+		
+		the callback will send both a string and a float (which shows
+		the overall process), callback(string, float)
+	
 	@type	engine:		object
 	@param	engine: 	FIFE engine instance
 	@type	callback:	function
 	@param	callback:	callback for maploading progress
 	@type	debug:		bool
 	@param	debug:		flag to activate / deactivate print statements
-
+	
 	@type	map:	object
 	@return	map:	FIFE map object
 	"""
 	(filename, extension) = os.path.splitext(path)
-	map_loader = mapFileMapping[extension[1:]](engine, callback, debug)
+	map_loader = mapFileMapping[extension[1:]](engine, callback, debug, extensions)
 	map = map_loader.loadResource(fife.ResourceLocation(path))
 	if debug: print "--- Loading map took: ", map_loader.time_to_load, " seconds."
 	return map
 
-
-def loadImportFile(path, engine, debug=False):
-	""" uses XMLObjectLoader to load import files from path
-
-	@type	path:	string
-	@param	path:	path to import file
-	@type	engine:	object
-	@param	engine:	FIFE engine instance
-	@type	debug:	bool
-	@param	debug:	flag to activate / deactivate print statements
-	"""
-	(filename, extension) = os.path.splitext(path)
-	object_loader = objectFileMapping[extension[1:]](engine.getImagePool(), engine.getAnimationPool(), engine.getModel(), engine.getVFS())
-	res = None
-	try:
-		res = object_loader.loadResource(fife.ResourceLocation(path))
-		if debug: print 'imported object file ' + path
-	except WrongFileType:
-		pass
-#		print 'ignored non-object file ' + path
-	except NameClash:
-		pass
-#		print 'ignored already loaded file ' + path
-	return res
-
-def loadImportDir(path, engine, debug=False):
-	""" helper function to call loadImportFile on a directory
-
-	@type	path:	string
-	@param	path:	path to import directory
-	@type	engine:	object
-	@param	engine:	FIFE engine instance
-	@type	debug:	bool
-	@param	debug:	flag to activate / deactivate print statements
-	"""
-	for file in filter(lambda f: f.split('.')[-1] == 'xml', engine.getVFS().listFiles(path)):
-		loadImportFile('/'.join([path, file]), engine, debug)
-
-def loadImportDirRec(path, engine, debug=False):
-	""" helper function to call loadImportFile recursive on a directory
-
-	@type	path:	string
-	@param	path:	path to import directory
-	@type	engine:	object
-	@param	engine:	FIFE engine instance
-	@type	debug:	bool
-	@param	debug:	flag to activate / deactivate print statements
-	"""
-	loadImportDir(path, engine, debug)
-
-	for dir in filter(lambda d: not d.startswith('.'), engine.getVFS().listDirectories(path)):
-		loadImportDirRec('/'.join([path, dir]), engine, debug)
-
-
-def addObjectFileLoader(fileExtension, loaderClass):
-	"""Add a new loader for fileextension
-	@type   fileExtension: string
-	@param  fileExtension: The file extension the loader is registered for
-	@type   loaderClass:   object
-	@param  loaderClass:   A fife.ResourceLoader implementation that loads objects
-	                       from files with the given fileExtension
-	"""
-	objectFileMapping[fileExtension] = loaderClass
-	_updateFileExtenions()
-
-
 def addMapLoader(fileExtension, loaderClass):
 	"""Add a new loader for fileextension
 	@type   fileExtension: string
@@ -139,8 +69,5 @@
 	mapFileMapping[fileExtension] = loaderClass
 	_updateMapFileExtensions()
 
-def _updateFileExtensions():
-	fileExtensions = set(objectFileMapping.keys())
-
 def _updateMapFileExtensions():
 	mapFileExtensions = set(mapFileMapping.keys())
\ No newline at end of file
--- a/engine/python/fife/extensions/savers.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/python/fife/extensions/savers.py	Fri Nov 05 15:21:10 2010 +0000
@@ -174,6 +174,7 @@
 			attrs = AttributesNSImpl(attr_vals, attr_names)
 			self.startElement('layer', attrs)
 			self.write_instances(layer)
+			self.write_lights(layer)
 			self.endElement('layer')
 
 	def write_instances(self, layer):
@@ -222,6 +223,102 @@
 
 		self.endElement('instances')
 
+	def write_lights(self, layer):
+		attrs = AttributesNSImpl({}, {})
+		self.startElement('lights',  attrs)
+
+		cameras = layer.getMap().getCameras()
+		for cam in cameras:
+			hit = False
+			layers = cam.getRenderer("LightRenderer").getActiveLayers();
+			for lay in layers:
+				if lay.getId() == layer.getId():
+					hit = True
+
+			if hit == False: continue					
+			
+			renderer = fife.LightRenderer.getInstance(cam)
+			groups = renderer.getGroups()
+			for group in groups:
+				infos = renderer.getLightInfo(group)
+				for info in infos:
+					attr_vals = {}
+					attr_names = {}
+					type = info.getName()
+					attr_vals[(None, 'group')] = str(group)
+					attr_names[(None, 'group')] = 'group'
+					attr_vals[(None, 'type')] = str(type)
+					attr_names[(None, 'type')] = 'type'
+					attr_vals[(None, 'instance')] = str(info.getNode().getInstance().getId())
+					attr_names[(None, 'instance')] = 'instance'
+					if info.getSrcBlend() > -1:
+						attr_vals[(None, 'src')] = str(info.getSrcBlend())
+						attr_names[(None, 'src')] = 'src'
+					if info.getDstBlend() > -1:
+						attr_vals[(None, 'dst')] = str(info.getDstBlend())
+						attr_names[(None, 'dst')] = 'dst'
+					if info.getStencil() > -1:
+						attr_vals[(None, 's_ref')] = str(info.getStencil())
+						attr_names[(None, 's_ref')] = 's_ref'
+						attr_vals[(None, 'a_ref')] = str(info.getAlpha())
+						attr_names[(None, 'a_ref')] = 'a_ref'
+					
+					if type == 'simple':
+						if info.getRadius() > 0:
+							attr_vals[(None, 'radius')] = str(info.getRadius())
+							attr_names[(None, 'radius')] = 'radius'
+						if info.getColor():
+							color = info.getColor()
+							attr_vals[(None, 'color')] = '%d,%d,%d' % (color[0], color[1], color[2])
+							attr_vals[(None, 'intensity')] = str(color[3])
+							attr_names[(None, 'color')] = 'color'
+							attr_names[(None, 'intensity')] = 'intensity'
+
+						if info.getSubdivisions() is not 32:
+							attr_vals[(None, 'subdivisions')] = str(info.getSubdivisions())
+							attr_names[(None, 'subdivisions')] = 'subdivisions'
+						if info.getXStretch() > 1.001 or info.getXStretch() < 0.999:
+							attr_vals[(None, 'xstretch')] = str(info.getXStretch())
+							attr_names[(None, 'xstretch')] = 'xstretch'
+						if info.getYStretch() > 1.001 or info.getYStretch() < 0.999:
+							attr_vals[(None, 'ystretch')] = str(info.getYStretch())
+							attr_names[(None, 'ystretch')] = 'ystretch'
+
+					elif type == 'image':
+						if info.getId() == -1: continue
+						img = self.pool.getImage(info.getId());
+						name = img.getResourceFile()
+						attr_vals[(None, 'image')] = str('../' + name)
+						attr_names[(None, 'image')] = 'image'
+
+					elif type == 'animation':
+						if info.getId() == -1: continue
+						ani = self.anim_pool.getAnimation(info.getId());
+						count = 0
+						newstr = ''
+						image = ani.getFrame(ani.getActionFrame())
+						fname = image.getResourceFile()
+						strings = ([str(s) for s in fname.split('/')])
+						leng = len(strings) -1
+						while count < leng:
+							newstr = str(newstr + strings[count] + '/')
+							count += 1
+
+						name = str('../' + newstr + 'animation.' + fileExtensions[0])
+						attr_vals[(None, 'animation')] = str(name)
+						attr_names[(None, 'animation')] = 'animation'
+
+					else:
+						continue
+
+					attrs = AttributesNSImpl(attr_vals, attr_names)
+					self.file.write(self.indent_level)
+					self.xmlout.startElementNS((None, 'l'), 'l', attrs)
+					self.xmlout.endElementNS((None, 'l'), 'l')
+					self.file.write('\n')
+
+		self.endElement('lights')
+
 	# Save the linked camera of a map.
 	def write_camera( self, map ):
 		cameralist = map.getCameras()
@@ -256,6 +353,10 @@
 					attr_names[(None,'viewport')] = 'viewport'
 					attr_vals[(None,'viewport')] = '%d,%d,%d,%d' % (viewport.x, viewport.y, viewport.w, viewport.h)
 
+				colors = cam.getLightingColor()
+				if colors[0] < 1.0 or colors[1] < 1.0 or colors[2] < 1.0 or colors[3] < 1.0:
+					attr_names[(None,'light_color')] = 'light_color'
+					attr_vals[(None,'light_color')] = '%f,%f,%f,%f' % (colors[0], colors[1], colors[2], colors[3])
 				attrs = AttributesNSImpl( attr_vals, attr_names )
 				self.startElement( 'camera', attrs );
 				self.endElement( 'camera' );
--- a/engine/python/fife/extensions/serializers/__init__.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/python/fife/extensions/serializers/__init__.py	Fri Nov 05 15:21:10 2010 +0000
@@ -1,7 +1,6 @@
 # -*- coding: utf-8 -*-
-
 # ####################################################################
-#  Copyright (C) 2005-2009 by the FIFE team
+#  Copyright (C) 2005-2010 by the FIFE team
 #  http://www.fifengine.de
 #  This file is part of FIFE.
 #
@@ -28,7 +27,7 @@
 
 try:
 	import xml.etree.cElementTree as ET
-except:
+except ImportError:
 	import xml.etree.ElementTree as ET
 
 class SerializerError(Exception):
@@ -105,3 +104,70 @@
 		return path
 
 	return '/'.join(path.split(os.path.sep))	
+
+def loadImportFile(loader, path, engine, debug=False):
+	""" uses XMLObjectLoader to load import files from path
+	
+	@type	path:	string
+	@param	path:	path to import file
+	@type	debug:	bool
+	@param	debug:	flag to activate / deactivate print statements
+	"""
+	loader.loadResource(fife.ResourceLocation(path))
+	if debug: print 'imported object file ' + path
+
+def loadImportDir(loader, path, engine, debug=False):
+	""" helper function to call loadImportFile on a directory
+	
+	@type	path:	string
+	@param	path:	path to import directory
+	@type	debug:	bool
+	@param	debug:	flag to activate / deactivate print statements
+	"""
+	for _file in filter(lambda f: f.split('.')[-1] == 'xml', engine.getVFS().listFiles(path)):
+		loadImportFile(loader, '/'.join([path, _file]), engine, debug)
+
+def loadImportDirRec(loader, path, engine, debug=False):
+	""" helper function to call loadImportFile recursive on a directory
+
+	@type	path:	string
+	@param	path:	path to import directory
+	@type	debug:	bool
+	@param	debug:	flag to activate / deactivate print statements	
+	"""
+	loadImportDir(loader, path, engine, debug)
+
+	for _dir in filter(lambda d: not d.startswith('.'), engine.getVFS().listDirectories(path)):
+		loadImportDirRec(loader, '/'.join([path, _dir]), engine, debug)
+		
+def root_subfile(masterfile, subfile):
+	"""
+	Returns new path for given subfile (path), which is rooted against masterfile
+	E.g. if masterfile is ./../foo/bar.xml and subfile is ./../foo2/subfoo.xml,
+	returned path is ../foo2/subfoo.xml
+	NOTE: masterfile is expected to be *file*, not directory. subfile can be either
+	"""
+	s = '/'
+
+	masterfile = norm_path(os.path.abspath(masterfile))
+	subfile = norm_path(os.path.abspath(subfile))
+
+	master_fragments = masterfile.split(s)
+	sub_fragments = subfile.split(s)
+
+	master_leftovers = []
+	sub_leftovers = []
+
+	for i in xrange(len(master_fragments)):
+		try:
+			if master_fragments[i] == sub_fragments[i]:
+				master_leftovers = master_fragments[i+1:]
+				sub_leftovers = sub_fragments[i+1:]
+		except IndexError:
+			break
+
+	pathstr = ''
+	for f in master_leftovers[:-1]:
+		pathstr += '..' + s
+	pathstr += s.join(sub_leftovers)
+	return pathstr
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/engine/python/fife/extensions/serializers/xml_loader_tools.py	Fri Nov 05 15:21:10 2010 +0000
@@ -0,0 +1,144 @@
+# -*- coding: utf-8 -*-
+# ####################################################################
+#  Copyright (C) 2005-2010 by the FIFE team
+#  http://www.fifengine.de
+#  This file is part of FIFE.
+#
+#  FIFE is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License, or (at your option) any later version.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the
+#  Free Software Foundation, Inc.,
+#  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+# ####################################################################
+
+""" utilities for xml maploading process """
+
+import sys, os
+
+from fife import fife
+import math
+
+def loadImportFile(loader, path, engine, debug=False):
+	""" uses XMLObjectLoader to load import files from path
+	
+	@type	path:	string
+	@param	path:	path to import file
+	@type	debug:	bool
+	@param	debug:	flag to activate / deactivate print statements
+	"""
+	loader.loadResource(fife.ResourceLocation(path))
+	if debug: print 'imported object file ' + path
+
+def loadImportDir(loader, path, engine, debug=False):
+	""" helper function to call loadImportFile on a directory
+	
+	@type	path:	string
+	@param	path:	path to import directory
+	@type	debug:	bool
+	@param	debug:	flag to activate / deactivate print statements
+	"""
+	for _file in filter(lambda f: f.split('.')[-1] == 'xml', engine.getVFS().listFiles(path)):
+		loadImportFile(loader, '/'.join([path, _file]), engine, debug)
+
+def loadImportDirRec(loader, path, engine, debug=False):
+	""" helper function to call loadImportFile recursive on a directory
+
+	@type	path:	string
+	@param	path:	path to import directory
+	@type	debug:	bool
+	@param	debug:	flag to activate / deactivate print statements	
+	"""
+	loadImportDir(loader, path, engine, debug)
+
+	for _dir in filter(lambda d: not d.startswith('.'), engine.getVFS().listDirectories(path)):
+		loadImportDirRec(loader, '/'.join([path, _dir]), engine, debug)
+		
+def root_subfile(masterfile, subfile):
+	"""
+	Returns new path for given subfile (path), which is rooted against masterfile
+	E.g. if masterfile is ./../foo/bar.xml and subfile is ./../foo2/subfoo.xml,
+	returned path is ../foo2/subfoo.xml
+	NOTE: masterfile is expected to be *file*, not directory. subfile can be either
+	"""
+	s = '/'
+
+	masterfile = norm_path(os.path.abspath(masterfile))
+	subfile = norm_path(os.path.abspath(subfile))
+
+	master_fragments = masterfile.split(s)
+	sub_fragments = subfile.split(s)
+
+	master_leftovers = []
+	sub_leftovers = []
+
+	for i in xrange(len(master_fragments)):
+		try:
+			if master_fragments[i] == sub_fragments[i]:
+				master_leftovers = master_fragments[i+1:]
+				sub_leftovers = sub_fragments[i+1:]
+		except IndexError:
+			break
+
+	pathstr = ''
+	for f in master_leftovers[:-1]:
+		pathstr += '..' + s
+	pathstr += s.join(sub_leftovers)
+	return pathstr
+
+def reverse_root_subfile(masterfile, subfile):
+	"""
+	does inverse operation to root_subfile. E.g. 
+	E.g. if masterfile is ./../foo/bar.xml and subfile is ../foo2/subfoo.xml,
+	returned path ./../foo2/subfoo.xml
+	Usually this function is used to convert saved paths into engine relative paths
+	NOTE: masterfile is expected to be *file*, not directory. subfile can be either
+	"""
+	s = '/'
+
+	masterfile = norm_path(os.path.abspath(masterfile)).split(s)[:-1]
+	subfile = norm_path(os.path.abspath( s.join(masterfile) + s + subfile ))
+	masterfile = norm_path(os.getcwd()) + s + 'foo.bar' # cheat a little to satisfy root_subfile
+	return root_subfile(masterfile, subfile)
+
+def norm_path(path):
+	"""
+	Makes the path use '/' delimited separators. FIFE always uses these delimiters, but some os-related
+  routines will default to os.path.sep.
+	"""
+	if os.path.sep == '/':
+		return path
+
+	return '/'.join(path.split(os.path.sep))
+	
+
+def frange(limit1, limit2 = None, increment = 1.):
+  """ source:
+      http://code.activestate.com/recipes/66472-frange-a-range-function-with-float-increments/
+    
+	  Range function that accepts floats (and integers).
+
+	  Usage:
+	  frange(-2, 2, 0.1)
+	  frange(10)
+	  frange(10, increment = 0.5)
+
+	  The returned value is an iterator.  Use list(frange) for a list.
+  """
+
+  if limit2 is None:
+    limit2, limit1 = limit1, 0.
+  else:
+    limit1 = float(limit1)
+
+  count = int(math.ceil(limit2 - limit1)/increment)
+  return (limit1 + n*increment for n in range(count))
+	
--- a/engine/python/fife/extensions/serializers/xmlanimation.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/python/fife/extensions/serializers/xmlanimation.py	Fri Nov 05 15:21:10 2010 +0000
@@ -22,7 +22,7 @@
 # ####################################################################
 
 from fife import fife
-from fife.extensions.serializers import *
+from fife.extensions.serializers import ET
 
 class XMLAnimationLoader(fife.ResourceLoader):
 	def __init__(self, imagepool, vfs):
--- a/engine/python/fife/extensions/serializers/xmlmap.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/python/fife/extensions/serializers/xmlmap.py	Fri Nov 05 15:21:10 2010 +0000
@@ -1,7 +1,6 @@
 # -*- coding: utf-8 -*-
-
 # ####################################################################
-#  Copyright (C) 2005-2009 by the FIFE team
+#  Copyright (C) 2005-2010 by the FIFE team
 #  http://www.fifengine.de
 #  This file is part of FIFE.
 #
@@ -21,33 +20,43 @@
 #  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 # ####################################################################
 
-from fife import fife
-try:
-	import xml.etree.cElementTree as ET
-except:
-	import xml.etree.ElementTree as ET
-
-from fife.extensions.serializers import *
+""" main xml parser class for xml map loading """
 
 import time
 
+from fife import fife
+
+from fife.extensions.serializers import ET
+from fife.extensions.serializers import SerializerError, InvalidFormat 
+from fife.extensions.serializers import NameClash, NotFound, WrongFileType
+
+from fife.extensions.serializers.xmlobject import XMLObjectLoader
+from fife.extensions.serializers.xmlanimation import XMLAnimationLoader
+from fife.extensions.serializers.xml_loader_tools import loadImportFile, loadImportDir
+from fife.extensions.serializers.xml_loader_tools import loadImportDirRec
+from fife.extensions.serializers.xml_loader_tools import root_subfile, reverse_root_subfile	
+	
+
 FORMAT = '1.0'
 
 class XMLMapLoader(fife.ResourceLoader):
-	def __init__(self, engine, callback, debug):
-		""" The XMLMapLoader parses the xml map using several section. 
-		Each section fires a callback (if given) which can e. g. be
-		used to show a progress bar.
-		
-		The callback sends two values, a string and a float (which shows
-		the overall process): callback(string, float)
-
+	""" The B{XMLMapLoader} parses the xml map using several section. 
+	Each section fires a callback (if given) which can e. g. be
+	used to show a progress bar.
+	
+	The callback sends two values, a string and a float (which shows
+	the overall process): callback(string, float)
+	"""
+	def __init__(self, engine, callback, debug, extensions):
+		"""
 		@type	engine:		object
 		@param	engine:		a pointer to fife.engine
 		@type	callback:	function
 		@param	callback:	a callback with two arguments, optional
 		@type	debug:		bool
 		@param	debug:		flag to activate / deactivate print statements
+		@type	extensions:	dict
+		@param	extensions:	information package which extension should be activated (lights, sounds)
 		"""
 		fife.ResourceLoader.__init__(self)
 		self.thisown = 0
@@ -60,16 +69,45 @@
 		self.model = self.engine.getModel()
 		self.pool = self.engine.getImagePool()
 		self.anim_pool = self.engine.getAnimationPool()
+		
+		self.obj_loader = XMLObjectLoader(
+			engine.getImagePool(),
+			engine.getAnimationPool(),
+			engine.getModel(),
+			engine.getVFS()
+		)
+	
 		self.map = None
 		self.source = None
 		self.time_to_load = 0
 
 		self.nspace = None
+
+		self.msg = {}
+		self.msg['map'] = 'created map'
+		self.msg['imports'] = 'loaded imports'		
+		self.msg['layer'] = 'loaded layer: %s'
+		self.msg['camera'] = 'loaded camera: %s'
+
+		if 'sound' not in extensions:
+			extensions['sound'] = False
+		if 'lights' not in extensions:
+			extensions['lights'] = False
+			
+		self.light_data = {}
+		self.extensions = extensions
 		
 	def _err(self, msg):
 		raise SyntaxError(''.join(['File: ', self.source, ' . ', msg]))
 
 	def loadResource(self, location):
+		""" overwrite of B{fife.ResourceLoader}
+		
+		@type	location:	object
+		@param	location:	path to a map file as a fife.ResourceLocation
+		@type	map:	object
+		@return	map:	FIFE map object
+		"""
 		start_time = time.time()
 		self.source = location.getFilename()
 		f = self.vfs.open(self.source)
@@ -82,80 +120,108 @@
 		return map
 
 	def parse_map(self, mapelt):
+		""" start parsing the xml structure and
+		    call submethods for turning found tags
+		    into FIFE objects and create the map
+		
+		@type	mapelt:	object
+		@param	mapelt:	ElementTree root
+		@type	map:	object
+		@return	map:	FIFE map object		
+		"""
 		if not mapelt:
 			self._err('No <map> element found at top level of map file definition.')
-		id,format = mapelt.get('id'),mapelt.get('format')
+		_id, format = mapelt.get('id'), mapelt.get('format')
 
 		if not format == FORMAT: self._err(''.join(['This file has format ', format, ' but this loader has format ', FORMAT]))
-		if not id: self._err('Map declared without an identifier.')
+		if not _id: self._err('Map declared without an identifier.')
 
 		map = None
 		try:
-			self.map = self.model.createMap(str(id))
+			self.map = self.model.createMap(str(_id))
 			self.map.setResourceFile(self.source)
 		except fife.Exception, e: # NameClash appears as general fife.Exception; any ideas?
 			print e.getMessage()
-			print ''.join(['File: ', self.source, '. The map ', str(id), ' already exists! Ignoring map definition.'])
-			return None
+			print ''.join(['File: ', self.source, '. The map ', str(_id), ' already exists! Ignoring map definition.'])
+			return map
 
 		# xml-specific directory imports. This is used by xml savers.
 		self.map.importDirs = []
 
 		if self.callback is not None:
-			self.callback('created map', float(0.25) )
+			self.callback(self.msg['map'], float(0.25) )
 
 		self.parse_imports(mapelt, self.map)
+		self.parse_layers(mapelt, self.map)	
+		self.parse_cameras(mapelt, self.map)
 		
-		self.parse_layers(mapelt, self.map)	
-		
-		self.parse_cameras(mapelt, self.map)
+		# create light nodes
+		if self.light_data:
+			self.create_light_nodes(self.map)
 		
 		return self.map
 
 	def parse_imports(self, mapelt, map):
+		""" load all objects defined as import into memory
+		
+		@type	mapelt:	object
+		@param	mapelt:	ElementTree root
+		@type	map:	object
+		@map	map:	FIFE map object			
+		"""
 		parsedImports = {}
-		from fife.extensions import loaders
+
 		if self.callback:		
 			tmplist = mapelt.findall('import')
 			i = float(0)
 		
 		for item in mapelt.findall('import'):
-			file = item.get('file')
-			if file:
-				file = reverse_root_subfile(self.source, file)
-			dir = item.get('dir')
-			if dir:
-				dir = reverse_root_subfile(self.source, dir)
-
+			_file = item.get('file')
+			if _file:
+				_file = reverse_root_subfile(self.source, _file)
+			_dir = item.get('dir')
+			if _dir:
+				_dir = reverse_root_subfile(self.source, _dir)
+				
 			# Don't parse duplicate imports
-			if (dir,file) in parsedImports:
-				if self.debug: print "Duplicate import:" ,(dir,file)
+			if (_dir,_file) in parsedImports:
+				if self.debug: print "Duplicate import:" ,(_dir, _file)
 				continue
-			parsedImports[(dir,file)] = 1
+			parsedImports[(_dir,_file)] = 1
 
-			if file and dir:
-				loaders.loadImportFile('/'.join(dir, file), self.engine, self.debug)
-			elif file:
-				loaders.loadImportFile(file, self.engine, self.debug)
-			elif dir:
-				loaders.loadImportDirRec(dir, self.engine, self.debug)
-				map.importDirs.append(dir)
+			if _file and _dir:
+				loadImportFile(self.obj_loader, '/'.join(_dir, _file), self.engine, self.debug)
+			elif _file:
+				loadImportFile(self.obj_loader, _file, self.engine, self.debug)
+			elif _dir:
+				loadImportDirRec(self.obj_loader, _dir, self.engine, self.debug)
+				map.importDirs.append(_dir)
 			else:
 				if self.debug: print 'Empty import statement?'
 				
 			if self.callback:
 				i += 1				
-				self.callback('loaded imports', float( i / float(len(tmplist)) * 0.25 + 0.25 ) )
-
+				self.callback(self.msg['imports'], float( i / float(len(tmplist)) * 0.25 + 0.25 ) )
 
 	def parse_layers(self, mapelt, map):
+		""" create all layers and their instances
+		
+		@type	mapelt:	object
+		@param	mapelt:	ElementTree root
+		@type	map:	object
+		@map	map:	FIFE map object			
+		"""		
 		if self.callback is not None:		
 			tmplist = mapelt.findall('layer')
 			i = float(0)
 
 		for layer in mapelt.findall('layer'):
-			id = layer.get('id')
+			_id = layer.get('id')
 			grid_type = layer.get('grid_type')
+
+			if not _id: self._err('<layer> declared with no id attribute.')
+			if not grid_type: self._err(''.join(['Layer ', str(_id), ' has no grid_type attribute.']))
+
 			x_scale = layer.get('x_scale')
 			y_scale = layer.get('y_scale')
 			rotation = layer.get('rotation')
@@ -175,9 +241,6 @@
 			else:
 				transparency = int(transparency)
 
-			if not id: self._err('<layer> declared with no id attribute.')
-			if not grid_type: self._err(''.join(['Layer ', str(id), ' has no grid_type attribute.']))
-
 			cellgrid = self.model.getCellGrid(grid_type)
 			if not cellgrid: self._err('<layer> declared with invalid cellgrid type. (%s)' % grid_type)
 
@@ -189,10 +252,10 @@
 
 			layer_obj = None
 			try:
-				layer_obj = map.createLayer(str(id), cellgrid)
+				layer_obj = map.createLayer(str(_id), cellgrid)
 			except fife.Exception, e:
 				print e.getMessage()
-				print 'The layer ' + str(id) + ' already exists! Ignoring this layer.'
+				print 'The layer ' + str(_id) + ' already exists! Ignoring this layer.'
 				continue
 
 			strgy = fife.CELL_EDGES_ONLY
@@ -200,86 +263,240 @@
 				strgy = fife.CELL_EDGES_AND_DIAGONALS
 			if pathing == "freeform":
 				strgy = fife.FREEFORM
+
 			layer_obj.setPathingStrategy(strgy)
-
 			layer_obj.setLayerTransparency(transparency)
 
 			self.parse_instances(layer, layer_obj)
+			
+			if self.extensions['lights']:
+				self.parse_lights(layer, layer_obj)
+			if self.extensions['sound']:
+				self.parse_sounds(layer, layer_obj)
 
 			if self.callback is not None:
 				i += 1
-				self.callback('loaded layer :' + str(id), float( i / float(len(tmplist)) * 0.25 + 0.5 ) )
+				self.callback(self.msg['layer'] % str(_id), float( i / float(len(tmplist)) * 0.25 + 0.5 ) )
 
 		# cleanup
 		if self.callback is not None:
 			del tmplist
 			del i
 
+	def parse_lights(self, layerelt, layer):
+		""" create light nodes
+		
+		@type	layerelt:	object
+		@param	layerelt:	ElementTree layer branch
+		@type	layer:	object
+		@map	layer:	FIFE layer object
+		"""
+		_LIGHT_DEFAULT_BLENDING_SRC = -1
+		_LIGHT_DEFAULT_BLENDING_DST = -1
+		_LIGHT_DEFAULT_SUBDIVISIONS = 32
+		_LIGHT_DEFAULT_CAM_ID = 'default'
+		_LIGHT_DEFAULT_INTENSITY = 128
+		_LIGHT_DEFAULT_RADIUS = 10.0
+		
+		print "Processing lights ... "		
+		lightelt = layerelt.find('lights')
+		if not lightelt: 
+			print "\tno lights found on layer %s" % layer.getId()
+			return		
+		
+		lights = []
+		for attr in ('l', 'light', 'lgt'):
+			lights.extend(lightelt.findall(attr))
+		
+		for light in lights:
+			group = light.get('group')
+			if not group:
+				print "Light has no group. Omitting..."
+				continue
+				
+			blending_src = light.get('src')
+			if not blending_src:
+				blending_src = _LIGHT_DEFAULT_BLENDING_SRC
+			blending_dst = light.get('dst')
+			if not blending_dst:
+				blending_dst = _LIGHT_DEFAULT_BLENDING_DST
+				
+			_x = light.get('x')
+			if not _x: _x = 0
+			_y = light.get('y')
+			if not _y: _y = 0
+			_z = light.get('y')
+			if not _z: _z = 0
+
+			node = {}				
+			node['blending_src'] = int(blending_src)
+			node['blending_dst'] = int(blending_dst)
+			node['layer'] = layer.getId()
+			node['position'] = int(_x), int(_y), int(_z)
+
+			# where is the light? *sing*
+			instance_id = light.get('instance')
+			node['instance'] = None
+			if instance_id and layer.getInstance(instance_id):
+				node['instance'] = instance_id
+			
+			type = light.get('type')
+			if type:
+				s_ref = light.get('s_ref')
+				if not s_ref: s_ref = -1
+				node['s_ref'] = int(s_ref)
+				a_ref = light.get('a_ref')
+				if not a_ref: a_ref = 0.0
+				node['a_ref'] = float(a_ref)
+				
+				if type == 'image':
+					image = light.get('image')					
+					if not image:
+						print "Light has no image. Omitting..."
+						continue
+					node['type'] = 'image'
+					image = reverse_root_subfile(self.source, image)
+					img_id = self.pool.addResourceFromFile(image)
+					node['image'] = int(img_id)
+				elif type == 'animation':
+					animation = light.get('animation')					
+					if not animation:
+						print "Light has no animation. Omitting..."
+						continue
+					node['type'] = 'animation'
+					animation = reverse_root_subfile(self.source, animation)
+					rloc = fife.ResourceLocation(animation)
+					ani_id = self.anim_pool.addResourceFromLocation(rloc)
+					node['animation'] = int(ani_id)					
+				elif type == 'simple':
+					node['type'] = type
+					radius = light.get('radius')
+					if not radius: radius = _LIGHT_DEFAULT_RADIUS
+					node['radius'] = float(radius)
+
+					subdivisions = light.get('subdivisions')
+					if not subdivisions: 
+						subdivisions = _LIGHT_DEFAULT_SUBDIVISIONS
+					node['subdivisions'] = int(subdivisions)
+					
+					intensity = light.get('intensity')
+					if not intensity:
+						intensity = _LIGHT_DEFAULT_INTENSITY
+					node['intensity'] = int(intensity)
+
+					xstretch = light.get('xstretch')
+					if not xstretch: xstretch = 1.0
+					ystretch = light.get('ystretch')
+					if not ystretch: ystretch = 1.0
+					node['stretch'] = float(xstretch), float(ystretch)
+
+					color = light.get('color')
+					if not color: color = '%d,%d,%d' % (255, 255, 255)
+					node['color'] = ([int(c) for c in color.split(',')])
+
+			else:
+				continue
+			
+			cam_id = light.get('camera_id')
+			if not cam_id: cam_id = _LIGHT_DEFAULT_CAM_ID
+	
+			if not cam_id in self.light_data:
+				self.light_data[cam_id] = {}
+			if group not in self.light_data[cam_id]:
+				self.light_data[cam_id][group] = []
+			
+			self.light_data[cam_id][group].append(node)
+			
+		for camera, groups in self.light_data.iteritems():
+			print "Lights for camera %s" % camera
+			for group, lights in groups.iteritems():
+				print group, lights
+			
+	def parse_sounds(self, layerelt, layer):
+		""" create sound emitter
+		
+		FIXME:
+			- FIFE has a hard limit of sound emitters
+			  how should we load emitters here?
+			- my first thought: collect a list of sound
+			  files & data for emitter creation,
+			  then let the client decide what to do with it		  
+		
+		@type	layerelt:	object
+		@param	layerelt:	ElementTree layer branch
+		@type	layer:	object
+		@map	layer:	FIFE layer object
+		"""	
+		# to be continued		
+		pass
+		
 	def parse_instances(self, layerelt, layer):
+		""" create all layers and their instances
+		
+		@type	layerelt:	object
+		@param	layerelt:	ElementTree layer branch
+		@type	layer:	object
+		@map	layer:	FIFE layer object
+		"""			
 		instelt = layerelt.find('instances')
 
-		instances = instelt.findall('i')
-		instances.extend(instelt.findall('inst'))
-		instances.extend(instelt.findall('instance'))
+		instances = []
+		for attr in ('i', 'inst', 'instance'):
+			instances.extend(instelt.findall(attr))
+		
 		for instance in instances:
-
-			objectID = instance.get('object')
-			if not objectID:
-				objectID = instance.get('obj')
-			if not objectID:
-				objectID = instance.get('o')
-
-			if not objectID: self._err('<instance> does not specify an object attribute.')
-
-			nspace = instance.get('namespace')
-			if not nspace:
-				nspace = instance.get('ns')
-			if not nspace:
+			_id = instance.get('id')
+			# check for istance id name clashes
+			if _id:
+				if bool(layer.getInstance(_id)):
+					print "Instance with id=%s, already exists. Omitting..." % _id
+					continue
+				_id = str(_id)
+			else:
+				_id = ''
+			
+			objectID = ''
+			for attr in ('o', 'object', 'obj'):
+				objectID = instance.get(attr)
+				if objectID: break
+			if not objectID: self._err('<instance> %s does not specify an object attribute.' % str(objectID))
+			objectID = str(objectID)
+			
+			nspace = ''
+			for attr in ('namespace', 'ns'):
+				nspace = instance.get(attr)
+				if nspace: break
+			# try to reuse the previous namespace
+			if not nspace and self.nspace:
 				nspace = self.nspace
-
-			if not nspace: self._err('<instance> %s does not specify an object namespace, and no default is available.' % str(objectID))
-
+			if not nspace and not self.nspace: self._err('<instance> %s does not specify an object namespace, and no default is available.' % str(objectID))
+			nspace = str(nspace)
 			self.nspace = nspace
 
-			object = self.model.getObject(str(objectID), str(nspace))
+			# check if there is an object for this instance available, if not -> skip this one
+			object = self.model.getObject(objectID, nspace)
 			if not object:
-				print ''.join(['Object with id=', str(objectID), ' ns=', str(nspace), ' could not be found. Omitting...'])
+				print "Object with id=%s, ns=%s could not be found. Omitting..." % (objectID, nspace)
 				continue
 
 			x = instance.get('x')
-			y = instance.get('y')
-			z = instance.get('z')
-			stackpos = instance.get('stackpos')
-			id = instance.get('id')
+			if x: self.x = x = float(x)
+			else: x = self.x
 
-			if x:
-				x = float(x)
-				self.x = x
-			else:
-				self.x = self.x + 1
-				x = self.x
+			y = instance.get('y')
+			if y: self.y = y = float(y)
+			else: y = self.y
 
-			if y:
-				y = float(y)
-				self.y = y
-			else:
-				y = self.y
-
-			if z:
-				z = float(z)
-			else:
-				z = 0.0
+			z = instance.get('z')
+			if z: z = float(z)
+			else: z = 0.0
 
-			if not id:
-				id = ''
-			else:
-				id = str(id)
+			inst = layer.createInstance(object, fife.ExactModelCoordinate(x,y,z), _id)
 
-			inst = layer.createInstance(object, fife.ExactModelCoordinate(x,y,z), str(id))
-
-			rotation = instance.get('r')
-			if not rotation:
-				rotation = instance.get('rotation')
+			rotation = 0
+			for attr in ('r', 'rotation'):
+				rotation = instance.get(attr)
+				if rotation: break
 			if not rotation:
 				angles = object.get2dGfxVisual().getStaticImageAngles()
 				if angles:
@@ -291,7 +508,9 @@
 			inst.setRotation(rotation)
 
 			fife.InstanceVisual.create(inst)
-			if (stackpos):
+			
+			stackpos = instance.get('stackpos')
+			if stackpos:
 				inst.get2dGfxVisual().setStackPosition(int(stackpos))
 
 			if (object.getAction('default')):
@@ -299,12 +518,24 @@
 				inst.act('default', target, True)
 
 	def parse_cameras(self, mapelt, map):
+		""" create all cameras and activate them
+		
+			FIXME:
+				- should the cameras really be enabled here?
+				  IMO that's part of the setup within a client
+				  (we just _load_ things here)
+		
+		@type	mapelt:	object
+		@param	mapelt:	ElementTree root
+		@type	map:	object
+		@map	map:	FIFE map object			
+		"""				
 		if self.callback:		
 			tmplist = mapelt.findall('camera')
 			i = float(0)
 
 		for camera in mapelt.findall('camera'):
-			id = camera.get('id')
+			_id = camera.get('id')
 			zoom = camera.get('zoom')
 			tilt = camera.get('tilt')
 			rotation = camera.get('rotation')
@@ -312,35 +543,221 @@
 			ref_cell_width = camera.get('ref_cell_width')
 			ref_cell_height = camera.get('ref_cell_height')
 			viewport = camera.get('viewport')
+			light_color = camera.get('light_color')
 
 			if not zoom: zoom = 1
 			if not tilt: tilt = 0
 			if not rotation: rotation = 0
 
-			if not id: self._err('Camera declared without an id.')
-			if not ref_layer_id: self._err(''.join(['Camera ', str(id), ' declared with no reference layer.']))
-			if not (ref_cell_width and ref_cell_height): self._err(''.join(['Camera ', str(id), ' declared without reference cell dimensions.']))
+			if not _id: self._err('Camera declared without an id.')
+			if not ref_layer_id: self._err(''.join(['Camera ', str(_id), ' declared with no reference layer.']))
+			if not (ref_cell_width and ref_cell_height): self._err(''.join(['Camera ', str(_id), ' declared without reference cell dimensions.']))
 
 			try:
 				if viewport:
-					cam = map.addCamera(str(id), map.getLayer(str(ref_layer_id)),fife.Rect(*[int(c) for c in viewport.split(',')]))
+					cam = map.addCamera(str(_id), map.getLayer(str(ref_layer_id)),fife.Rect(*[int(c) for c in viewport.split(',')]))
 
 				else:
 					screen = self.engine.getRenderBackend()
-					cam = map.addCamera(str(id), map.getLayer(str(ref_layer_id)),fife.Rect(0,0,screen.getScreenWidth(),screen.getScreenHeight()))
-
-				cam.setCellImageDimensions(int(ref_cell_width), int(ref_cell_height))
-				cam.setRotation(float(rotation))
-				cam.setTilt(float(tilt))
-				cam.setZoom(float(zoom))
+					cam = map.addCamera(str(_id), map.getLayer(str(ref_layer_id)),fife.Rect(0,0,screen.getScreenWidth(),screen.getScreenHeight()))
 				
 				renderer = fife.InstanceRenderer.getInstance(cam)
 				renderer.activateAllLayers(map)
 				
 			except fife.Exception, e:
 				print e.getMessage()
+
+			if light_color: cam.setLightingColor(*[float(c) for c in light_color.split(',')])			
+			cam.setCellImageDimensions(int(ref_cell_width), int(ref_cell_height))
+			cam.setRotation(float(rotation))
+			cam.setTilt(float(tilt))
+			cam.setZoom(float(zoom))
+			
+			renderer = fife.InstanceRenderer.getInstance(cam)
+			renderer.activateAllLayers(map)
 				
 			if self.callback:
 				i += 1
-				self.callback('loaded camera: ' +  str(id), float( i / len(tmplist) * 0.25 + 0.75 ) )	
+				self.callback(self.msg['camera'] % str(_id), float( i / len(tmplist) * 0.25 + 0.75 ) )
+				
+	def create_light_nodes(self, map):
+		""" loop through all preloaded lights and create them
+			according to their data
+		
+		@type	map:	object
+		@param	map:	FIFE map object
+		"""
+		cameras = [i.getId() for i in map.getCameras()]
+		renderers = {}
+		default_cam = map.getCameras()[0].getId()
+		
+		def add_simple_light(group, renderer, node, data):
+			""" add a node as simple light to the renderer 
+			
+			@type	group:	string
+			@param	group:	name of the light group
+			@type	renderer:	object
+			@param	renderer:	fife.LightRenderer instance
+			@type	node:		object
+			@param	node:		fife.LightRendererNode instance
+			@type	data:		dict
+			@param	data:		all data for the light type creation
+			"""
+			if not node: return
+			if not group: return
+			renderer.addSimpleLight(
+				group,
+				node,
+				data['intensity'],
+				data['radius'],
+				data['subdivisions'],
+				data['stretch'][0],
+				data['stretch'][1],
+				data['color'][0],
+				data['color'][1],
+				data['color'][2],
+				data['blending_src'],
+				data['blending_dst'],												
+			)
+			if data['s_ref'] is not -1:
+				add_stencil_test(group, renderer, data)
+		def add_animated_lightmap(group, renderer, node, data):
+			""" add a node as animated lightmap to the renderer 
+			
+			@type	group:	string
+			@param	group:	name of the light group
+			@type	renderer:	object
+			@param	renderer:	fife.LightRenderer instance
+			@type	node:		object
+			@param	node:		fife.LightRendererNode instance
+			@type	data:		dict
+			@param	data:		all data for the light type creation
+			"""
+			if not node: return
+			if not group: return
+			renderer.addAnimation(
+				group,
+				node,
+				data['animation'],
+				data['blending_src'],
+				data['blending_dst'],
+			)
+			if data['s_ref'] is not -1:
+				add_stencil_test(group, renderer, data)
+		def add_lightmap(group, renderer, node, data):
+			""" add a node as lightmap to the renderer 
+			
+			@type	group:	string
+			@param	group:	name of the light group
+			@type	renderer:	object
+			@param	renderer:	fife.LightRenderer instance
+			@type	node:		object
+			@param	node:		fife.LightRendererNode instance
+			@type	data:		dict
+			@param	data:		all data for the light type creation
+			"""
+			if not node: return
+			if not group: return
+			renderer.addImage(
+				group,
+				node,
+				data['image'],
+				data['blending_src'],
+				data['blending_dst'],
+			)
+			if data['s_ref'] is not -1:
+				add_stencil_test(group, renderer, data)
+		def add_stencil_test(group, renderer, data):
+			""" add a stencil test to a group 
+			
+			@type	group:	string
+			@param	group:	name of the light group
+			@type	renderer:	object
+			@param	renderer:	fife.LightRenderer instance
+			@type	data:		dict
+			@param	data:		all data for the light type creation
+			"""
+			if not group: return
+			renderer.addStencilTest(
+				group,
+				data['s_ref'],
+				data['a_ref'],
+			)
+			
+		def create_node(instance=None, point=None, layer=None):
+			""" creates a node of one of these types:
+			
+				- attached to an instance
+				- attached to an instance with offset
+				- attached to a point
+			
+				FIXME:
+					- add location node
+			
+			@type:	instance:	object
+			@param	instance:	fife instance object
+			@type	point:		tuple
+			@param	point:		x,y,z tuple
+			@type	layer:		object
+			@param	layer:		fife layer object
+			"""
+			node = None
+			if not layer: return node
+			
+			# node at layer coordinates
+			if point and not instance:
+				point = fife.Point(point[0], point[1])
+				node = fife.LightRendererNode(point);
+			# node with offset
+			if instance and point:
+				node = fife.LightRendererNode(instance, layer, fife.Point(point[0], point[1]))
+			# node attached to instance
+			if instance and not point:
+				node = fife.LightRendererNode(instance, layer)
 
+			if node:
+				node.thisown = 0
+				
+			return node			
+		
+		def dump_data():
+			""" dump all loaded data """
+			for camera, groups in self.light_data.iteritems():
+				print "Lights for camera %s" % camera
+				for group, lights in groups.iteritems():
+					print group, lights		
+		
+		# fetch all renderer instances for available cameras
+		for _id in cameras:
+			camera = map.getCamera(_id)
+			renderers[_id] = fife.LightRenderer.getInstance(camera)
+		
+		# parse data and create the lights	
+		for camera, groups in self.light_data.iteritems():
+			for group, lights in groups.iteritems():
+				for light in lights:
+					instance = None
+					layer = map.getLayer(light['layer'])
+					if light['instance']:
+						instance = layer.getInstance(light['instance'])
+					position = light['position']
+					node = create_node(instance, position, layer)
+					
+					# some guards
+					if not node: continue
+					
+					if camera == 'default':
+						renderer = renderers[default_cam]
+					else:
+						renderer = renderers[camera]
+						
+					if light['type'] == 'simple':
+						add_simple_light(group, renderer, node, light)
+					elif light['type'] == 'image':
+						add_lightmap(group, renderer, node, light)
+					elif light['type'] == 'animation':
+						add_animated_lightmap(group, renderer, node, light)
+				
+#		dump_data()
+		
+
--- a/engine/python/fife/extensions/serializers/xmlobject.py	Wed Nov 03 13:44:12 2010 +0000
+++ b/engine/python/fife/extensions/serializers/xmlobject.py	Fri Nov 05 15:21:10 2010 +0000
@@ -1,7 +1,6 @@
 # -*- coding: utf-8 -*-
-
 # ####################################################################
-#  Copyright (C) 2005-2009 by the FIFE team
+#  Copyright (C) 2005-2010 by the FIFE team
 #  http://www.fifengine.de
 #  This file is part of FIFE.
 #
@@ -21,17 +20,34 @@
 #  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 # ####################################################################
 
+""" submodule for xml map parsing """
+
 from fife import fife
-from fife.extensions.serializers import *
-from fife.extensions.fife_utils import *
+
+from fife.extensions.serializers import ET
+from fife.extensions.serializers import SerializerError, InvalidFormat 
+from fife.extensions.serializers import NameClash, NotFound, WrongFileType
 
 class ObjectLocation(fife.ResourceLocation):
+	"""
+	
+	
+	"""
 	def __init__(self, file, node=None):
+		"""
+		
+		"""
 		fife.ResourceLocation.__init__(self, file)
 		self.node = node
 
 class XMLObjectLoader(fife.ResourceLoader):
+	"""
+	
+	"""
 	def __init__(self, image_pool, anim_pool, model, vfs=None):
+		"""
+		
+		"""
 		self.image_pool = image_pool
 		self.anim_pool = anim_pool
 		self.model = model
@@ -40,6 +56,9 @@
 		self.filename = ''
 
 	def loadResource(self, location):
+		"""
+		
+		"""
 		self.source = location
 		self.filename = self.source.getFilename()
 		self.node = None
@@ -61,26 +80,36 @@
 				isobjectfile = False
 
 			if not isobjectfile:
+				return
 				raise WrongFileType('Tried to open non-object file %s with XMLObjectLoader.' % self.filename)
+
 		self.do_load_resource(f)
 
 	def do_load_resource(self, file):
+		"""
+		
+		"""
 		if file:
 			tree = ET.parse(file)
 			self.node = tree.getroot()
 		self.parse_object(self.node)
 
 	def parse_object(self, object):
+		"""
+		
+		"""
 		if self.node.tag != 'object':
 			raise InvalidFormat('Expected <object> tag, but found <%s>.' % self.node.tag)
 
-		id = object.get('id')
-		if not id:
+		_id = object.get('id')
+		if not _id:
 			raise InvalidFormat('<object> declared without an id attribute.')
+		_id = str(_id)
 
 		nspace = object.get('namespace')
 		if not nspace:
-			raise InvalidFormat('<object> %s declared without a namespace attribute.' % str(id))
+			raise InvalidFormat('<object> %s declared without a namespace attribute.' % str(_id))
+		nspace = str(nspace)
 
 		obj = None
 		parent = object.get('parent', None)
@@ -92,12 +121,12 @@
 				raise NameClash('%d objects found with identifier %s.' % (len(query), str(parent)))
 			parent = query[0]
 
-		try:
-			obj = self.model.createObject(str(id), str(nspace), parent)
-		except RuntimeError, e:
-			if is_fife_exc(fife.NameClash, e):
-				raise NameClash('Tried to create already existing object, ignoring')
-			raise
+		# check if model already has this object
+		if not bool(self.model.getObject(_id, nspace)):
+			obj = self.model.createObject(_id, nspace, parent)
+		else:
+			print NameClash('Tried to create already existing object \n\t...ignoring: %s, %s' % (_id, nspace))
+			return
 
 		obj.setResourceLocation(self.source)
 		fife.ObjectVisual.create(obj)
@@ -111,6 +140,9 @@
 		self.parse_actions(object, obj)
 
 	def parse_images(self, objelt, object):
+		"""
+		
+		"""
 		for image in objelt.findall('image'):
 			source = image.get('source')
 			if not source:
@@ -126,9 +158,11 @@
 			image_location .setYShift(int( image.get('y_offset', 0) ))
 			id = self.image_pool.addResourceFromLocation(image_location)
 			object.get2dGfxVisual().addStaticImage(int( image.get('direction', 0) ), id)
-			#img = self.image_pool.getImage(id)
 
 	def parse_actions(self, objelt, object):
+		"""
+		
+		"""
 		for action in objelt.findall('action'):
 			id = action.get('id')
 			if not id:
@@ -139,6 +173,9 @@
 			self.parse_animations(action, act_obj)
 
 	def parse_animations(self, actelt, action):
+		"""
+		
+		"""
 		for anim in actelt.findall('animation'):
 			source = anim.get('source')
 			if not source: