Browse Source

Moved things around to fix template compile errors.

Got started writing the sample for Lua.
Nate Starkey 13 years ago
parent
commit
d9959b34f1
100 changed files with 4931 additions and 633 deletions
  1. 8 15
      Build/RocketLua.vcproj
  2. 4 2
      Include/Rocket/Core/Lua/Interpreter.h
  3. 21 8
      Include/Rocket/Core/Lua/LuaType.h
  4. 29 0
      Samples/luainvaders/LuaRocketInvaders.sln
  5. 284 0
      Samples/luainvaders/PyRocketInvaders.vcproj
  6. 65 0
      Samples/luainvaders/PyRocketInvaders.vcproj.user
  7. 35 0
      Samples/luainvaders/data/background.rml
  8. BIN
      Samples/luainvaders/data/background.tga
  9. 126 0
      Samples/luainvaders/data/game.rml
  10. 55 0
      Samples/luainvaders/data/help.rml
  11. BIN
      Samples/luainvaders/data/help_defender.tga
  12. BIN
      Samples/luainvaders/data/help_invader_mothership.tga
  13. BIN
      Samples/luainvaders/data/help_invader_rank1.tga
  14. BIN
      Samples/luainvaders/data/help_invader_rank2.tga
  15. BIN
      Samples/luainvaders/data/help_invader_rank3.tga
  16. 75 0
      Samples/luainvaders/data/high_score.rml
  17. BIN
      Samples/luainvaders/data/high_scores_defender.tga
  18. BIN
      Samples/luainvaders/data/invaders.tga
  19. 23 0
      Samples/luainvaders/data/logo.rml
  20. BIN
      Samples/luainvaders/data/logo.tga
  21. 37 0
      Samples/luainvaders/data/main_menu.rml
  22. 88 0
      Samples/luainvaders/data/options.rml
  23. 27 0
      Samples/luainvaders/data/pause.rml
  24. 71 0
      Samples/luainvaders/data/start_game.rml
  25. 24 0
      Samples/luainvaders/data/window.rml
  26. 16 0
      Samples/luainvaders/lua/start.lua
  27. 86 0
      Samples/luainvaders/src/DecoratorDefender.cpp
  28. 57 0
      Samples/luainvaders/src/DecoratorDefender.h
  29. 67 0
      Samples/luainvaders/src/DecoratorInstancerDefender.cpp
  30. 56 0
      Samples/luainvaders/src/DecoratorInstancerDefender.h
  31. 78 0
      Samples/luainvaders/src/DecoratorInstancerStarfield.cpp
  32. 57 0
      Samples/luainvaders/src/DecoratorInstancerStarfield.h
  33. 145 0
      Samples/luainvaders/src/DecoratorStarfield.cpp
  34. 82 0
      Samples/luainvaders/src/DecoratorStarfield.h
  35. 182 0
      Samples/luainvaders/src/Defender.cpp
  36. 81 0
      Samples/luainvaders/src/Defender.h
  37. 119 0
      Samples/luainvaders/src/ElementGame.cpp
  38. 67 0
      Samples/luainvaders/src/ElementGame.h
  39. 445 0
      Samples/luainvaders/src/Game.cpp
  40. 128 0
      Samples/luainvaders/src/Game.h
  41. 148 0
      Samples/luainvaders/src/GameDetails.cpp
  42. 107 0
      Samples/luainvaders/src/GameDetails.h
  43. 236 0
      Samples/luainvaders/src/HighScores.cpp
  44. 77 0
      Samples/luainvaders/src/HighScores.h
  45. 266 0
      Samples/luainvaders/src/Invader.cpp
  46. 114 0
      Samples/luainvaders/src/Invader.h
  47. 84 0
      Samples/luainvaders/src/Mothership.cpp
  48. 53 0
      Samples/luainvaders/src/Mothership.h
  49. 124 0
      Samples/luainvaders/src/PythonInterface.cpp
  50. 57 0
      Samples/luainvaders/src/PythonInterface.h
  51. 188 0
      Samples/luainvaders/src/Shield.cpp
  52. 90 0
      Samples/luainvaders/src/Shield.h
  53. 52 0
      Samples/luainvaders/src/Sprite.cpp
  54. 50 0
      Samples/luainvaders/src/Sprite.h
  55. 195 0
      Samples/luainvaders/src/main.cpp
  56. 2 9
      Source/Controls/Lua/ElementDataGrid.cpp
  57. 2 1
      Source/Controls/Lua/ElementDataGrid.h
  58. 2 9
      Source/Controls/Lua/ElementDataGridRow.cpp
  59. 2 0
      Source/Controls/Lua/ElementDataGridRow.h
  60. 0 11
      Source/Controls/Lua/ElementForm.cpp
  61. 8 5
      Source/Controls/Lua/ElementForm.h
  62. 0 12
      Source/Controls/Lua/ElementFormControl.cpp
  63. 9 8
      Source/Controls/Lua/ElementFormControl.h
  64. 3 8
      Source/Controls/Lua/ElementFormControlDataSelect.cpp
  65. 2 0
      Source/Controls/Lua/ElementFormControlDataSelect.h
  66. 2 9
      Source/Controls/Lua/ElementFormControlInput.cpp
  67. 2 0
      Source/Controls/Lua/ElementFormControlInput.h
  68. 3 9
      Source/Controls/Lua/ElementFormControlSelect.cpp
  69. 2 1
      Source/Controls/Lua/ElementFormControlSelect.h
  70. 3 7
      Source/Controls/Lua/ElementFormControlTextArea.cpp
  71. 2 1
      Source/Controls/Lua/ElementFormControlTextArea.h
  72. 2 5
      Source/Controls/Lua/ElementTabSet.cpp
  73. 2 1
      Source/Controls/Lua/ElementTabSet.h
  74. 0 27
      Source/Core/Lua/Colourb.cpp
  75. 11 8
      Source/Core/Lua/Colourb.h
  76. 1 14
      Source/Core/Lua/Colourf.cpp
  77. 11 9
      Source/Core/Lua/Colourf.h
  78. 2 1
      Source/Core/Lua/Context.cpp
  79. 2 2
      Source/Core/Lua/Context.h
  80. 2 6
      Source/Core/Lua/Document.cpp
  81. 2 0
      Source/Core/Lua/Document.h
  82. 2 2
      Source/Core/Lua/Element.cpp
  83. 2 0
      Source/Core/Lua/Element.h
  84. 2 9
      Source/Core/Lua/ElementStyle.cpp
  85. 2 3
      Source/Core/Lua/ElementStyle.h
  86. 2 2
      Source/Core/Lua/Event.cpp
  87. 2 1
      Source/Core/Lua/Event.h
  88. 6 0
      Source/Core/Lua/Interpreter.cpp
  89. 4 2
      Source/Core/Lua/Interpreter.h
  90. 2 35
      Source/Core/Lua/Log.cpp
  91. 2 0
      Source/Core/Lua/Log.h
  92. 5 10
      Source/Core/Lua/LuaType.cpp
  93. 21 8
      Source/Core/Lua/LuaType.h
  94. 0 289
      Source/Core/Lua/LuaType.inl
  95. 309 0
      Source/Core/Lua/LuaTypeTemplateSpec.inl
  96. 2 22
      Source/Core/Lua/Rocket.cpp
  97. 2 1
      Source/Core/Lua/Rocket.h
  98. 0 27
      Source/Core/Lua/Vector2f.cpp
  99. 8 6
      Source/Core/Lua/Vector2f.h
  100. 0 28
      Source/Core/Lua/Vector2i.cpp

+ 8 - 15
Build/RocketLua.vcproj

@@ -41,7 +41,7 @@
 			<Tool
 			<Tool
 				Name="VCCLCompilerTool"
 				Name="VCCLCompilerTool"
 				Optimization="0"
 				Optimization="0"
-				AdditionalIncludeDirectories="$(SolutionDir)..\Include;$(SolutionDir)..\Source\Core;$(SolutionDir)..\Dependencies\lua\src;"
+				AdditionalIncludeDirectories="&quot;$(SolutionDir)..\Include&quot;;&quot;$(SolutionDir)..\Source\Core&quot;;&quot;$(SolutionDir)..\Dependencies\lua\src&quot;;&quot;$(SolutionDir)..\Source\Controls\Lua&quot;"
 				PreprocessorDefinitions="_WIN32,_DEBUG,RocketLua_EXPORTS"
 				PreprocessorDefinitions="_WIN32,_DEBUG,RocketLua_EXPORTS"
 				MinimalRebuild="true"
 				MinimalRebuild="true"
 				BasicRuntimeChecks="3"
 				BasicRuntimeChecks="3"
@@ -122,7 +122,7 @@
 				Name="VCCLCompilerTool"
 				Name="VCCLCompilerTool"
 				Optimization="2"
 				Optimization="2"
 				EnableIntrinsicFunctions="true"
 				EnableIntrinsicFunctions="true"
-				AdditionalIncludeDirectories="$(SolutionDir)..\Include;$(SolutionDir)..\Source\Core;$(SolutionDir)..\Dependencies\lua\src;"
+				AdditionalIncludeDirectories="&quot;$(SolutionDir)..\Include&quot;;&quot;$(SolutionDir)..\Source\Core&quot;;&quot;$(SolutionDir)..\Dependencies\lua\src&quot;;&quot;$(SolutionDir)..\Source\Controls\Lua&quot;"
 				PreprocessorDefinitions="_WIN32,NDEBUG,RocketLua_EXPORTS"
 				PreprocessorDefinitions="_WIN32,NDEBUG,RocketLua_EXPORTS"
 				RuntimeLibrary="2"
 				RuntimeLibrary="2"
 				EnableFunctionLevelLinking="true"
 				EnableFunctionLevelLinking="true"
@@ -289,19 +289,8 @@
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\Source\Core\Lua\LuaType.h"
-				>
-			</File>
-			<File
-				RelativePath="..\Source\Core\Lua\LuaType.inl"
+				RelativePath="..\Source\Core\Lua\LuaType.cpp"
 				>
 				>
-				<FileConfiguration
-					Name="Debug|Win32"
-					>
-					<Tool
-						Name="VCCustomBuildTool"
-					/>
-				</FileConfiguration>
 				<FileConfiguration
 				<FileConfiguration
 					Name="Release|Win32"
 					Name="Release|Win32"
 					ExcludedFromBuild="true"
 					ExcludedFromBuild="true"
@@ -312,7 +301,11 @@
 				</FileConfiguration>
 				</FileConfiguration>
 			</File>
 			</File>
 			<File
 			<File
-				RelativePath="..\Source\Core\Lua\Register.h"
+				RelativePath="..\Source\Core\Lua\LuaType.h"
+				>
+			</File>
+			<File
+				RelativePath="..\Source\Core\Lua\LuaTypeTemplateSpec.inl"
 				>
 				>
 			</File>
 			</File>
 			<File
 			<File

+ 4 - 2
Include/Rocket/Core/Lua/Interpreter.h

@@ -4,7 +4,7 @@
     This initializes the lua interpreter, and has functions to load the scripts
     This initializes the lua interpreter, and has functions to load the scripts
     A glorified namespace, but I want the lua_State to be unchangeable
     A glorified namespace, but I want the lua_State to be unchangeable
 */
 */
-
+#include "Header.h"
 #include <Rocket/Core/Lua/lua.hpp>
 #include <Rocket/Core/Lua/lua.hpp>
 #include <Rocket/Core/Plugin.h>
 #include <Rocket/Core/Plugin.h>
 
 
@@ -12,7 +12,7 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 
 
-class Interpreter : public Plugin
+class ROCKETLUA_API Interpreter : public Plugin
 {
 {
 public:
 public:
     static void LoadFile(const Rocket::Core::String& file);
     static void LoadFile(const Rocket::Core::String& file);
@@ -24,6 +24,8 @@ public:
     static void EndCall(int res = 0);
     static void EndCall(int res = 0);
 
 
     static lua_State* GetLuaState();
     static lua_State* GetLuaState();
+
+    static void Initialise();
     
     
     //From Plugin
     //From Plugin
     virtual int GetEventClasses();
     virtual int GetEventClasses();

+ 21 - 8
Include/Rocket/Core/Lua/LuaType.h

@@ -32,6 +32,20 @@ namespace Lua {
 #define CHECK_BOOL(L,narg) (lua_toboolean((L),(narg)) > 0 ? true : false )
 #define CHECK_BOOL(L,narg) (lua_toboolean((L),(narg)) > 0 ? true : false )
 #define LUACHECKOBJ(obj) if(obj == NULL) { lua_pushnil(L); return 1; }
 #define LUACHECKOBJ(obj) if(obj == NULL) { lua_pushnil(L); return 1; }
 
 
+//put this in the type.cpp file
+#define LUATYPEDEFINE(type) \
+    template<> const char* GetTClassName<type>() { return #type; } \
+    template<> RegType<type>* GetMethodTable<type>() { return type##Methods; } \
+    template<> luaL_reg* GetAttrTable<type>() { return type##Getters; } \
+    template<> luaL_reg* SetAttrTable<type>() { return type##Setters; } \
+
+//put this in the type.h file
+#define LUATYPEDECLARE(type) \
+    template<> const char* GetTClassName<type>(); \
+    template<> RegType<type>* GetMethodTable<type>(); \
+    template<> luaL_reg* GetAttrTable<type>(); \
+    template<> luaL_reg* SetAttrTable<type>(); \
+
 
 
 //replacement for luaL_reg that uses a different function pointer signature, but similar syntax
 //replacement for luaL_reg that uses a different function pointer signature, but similar syntax
 template<typename T>
 template<typename T>
@@ -42,13 +56,13 @@ struct ROCKETLUA_API RegType
 };
 };
 
 
 //this is for all of the methods available from Lua that call to the C functions
 //this is for all of the methods available from Lua that call to the C functions
-template<typename T> ROCKETLUA_API RegType<T>* GetMethodTable();
+template<typename T> ROCKETLUA_API inline RegType<T>* GetMethodTable();
 //this is for all of the function that 'get' an attribute/property
 //this is for all of the function that 'get' an attribute/property
-template<typename T> ROCKETLUA_API luaL_reg* GetAttrTable();
+template<typename T> ROCKETLUA_API inline luaL_reg* GetAttrTable();
 //this is for all of the functions that 'set' an attribute/property
 //this is for all of the functions that 'set' an attribute/property
-template<typename T> ROCKETLUA_API luaL_reg* SetAttrTable();
+template<typename T> ROCKETLUA_API inline luaL_reg* SetAttrTable();
 //String representation of the class
 //String representation of the class
-template<typename T> ROCKETLUA_API const char* GetTClassName();
+template<typename T> ROCKETLUA_API inline const char* GetTClassName();
 
 
 template<typename T>
 template<typename T>
 class ROCKETLUA_API LuaType
 class ROCKETLUA_API LuaType
@@ -80,17 +94,16 @@ public:
     //to call _regfunctions<superclass>, where method is metatable_index - 1. Anything
     //to call _regfunctions<superclass>, where method is metatable_index - 1. Anything
     //that has the same name in the subclass will be overwrite whatever had the 
     //that has the same name in the subclass will be overwrite whatever had the 
     //same name in the superclass.
     //same name in the superclass.
-    static inline void extra_init(lua_State* L, int metatable_index);
+    static  void extra_init(lua_State* L, int metatable_index);
     //Registers methods,getters,and setters to the type
     //Registers methods,getters,and setters to the type
-    static inline void _regfunctions(lua_State* L, int meta, int method);
+    static void _regfunctions(lua_State* L, int meta, int method);
 private:
 private:
     LuaType(); //hide constructor
     LuaType(); //hide constructor
 
 
 };
 };
-
 }
 }
 }
 }
 }
 }
 
 
-#include "LuaType.inl"
+//#include "LuaType.inl"
 #endif
 #endif

+ 29 - 0
Samples/luainvaders/LuaRocketInvaders.sln

@@ -0,0 +1,29 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PyRocketInvaders", "PyRocketInvaders.vcproj", "{D343E357-BF62-424F-B22A-16D7B8A6422B}"
+	ProjectSection(ProjectDependencies) = postProject
+		{AF4FF882-AFD9-457B-979E-A5B482388D46} = {AF4FF882-AFD9-457B-979E-A5B482388D46}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Shell", "..\shell\Shell.vcproj", "{AF4FF882-AFD9-457B-979E-A5B482388D46}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{D343E357-BF62-424F-B22A-16D7B8A6422B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D343E357-BF62-424F-B22A-16D7B8A6422B}.Debug|Win32.Build.0 = Debug|Win32
+		{D343E357-BF62-424F-B22A-16D7B8A6422B}.Release|Win32.ActiveCfg = Release|Win32
+		{D343E357-BF62-424F-B22A-16D7B8A6422B}.Release|Win32.Build.0 = Release|Win32
+		{AF4FF882-AFD9-457B-979E-A5B482388D46}.Debug|Win32.ActiveCfg = Debug|Win32
+		{AF4FF882-AFD9-457B-979E-A5B482388D46}.Debug|Win32.Build.0 = Debug|Win32
+		{AF4FF882-AFD9-457B-979E-A5B482388D46}.Release|Win32.ActiveCfg = Release|Win32
+		{AF4FF882-AFD9-457B-979E-A5B482388D46}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

+ 284 - 0
Samples/luainvaders/PyRocketInvaders.vcproj

@@ -0,0 +1,284 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="LuaRocketInvaders"
+	ProjectGUID="{D343E357-BF62-424F-B22A-16D7B8A6422B}"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(ProjectDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\shell\include;..\..\include;..\..\..\support\python\include;..\..\..\support\python\pc;..\..\..\support\boost;..\..\Dependencies\lua\src"
+				PreprocessorDefinitions="WIN32"
+				RuntimeLibrary="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="RocketCore_d.lib RocketDebugger_d.lib RocketControls_d.lib opengl32.lib RocketLua_d.lib"
+				OutputFile="..\..\bin\$(ProjectName)_d.exe"
+				AdditionalLibraryDirectories="..\..\bin;..\..\..\support\lib"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(ProjectDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\shell\include;..\..\include;..\..\..\support\python\include;..\..\..\support\python\pc;..\..\..\support\boost;..\..\Dependencies\lua\src"
+				PreprocessorDefinitions="WIN32"
+				RuntimeLibrary="2"
+				WarningLevel="3"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="RocketCore.lib RocketDebugger.lib RocketControls.lib opengl32.lib boost_python-vc90-mt-1_44.lib"
+				OutputFile="..\..\bin\$(ProjectName).exe"
+				AdditionalLibraryDirectories="..\..\bin;..\..\..\support\lib"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Game"
+			>
+			<File
+				RelativePath=".\src\Defender.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Defender.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\ElementGame.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\ElementGame.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Game.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Game.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\GameDetails.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\GameDetails.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Invader.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Invader.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Mothership.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Mothership.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Shield.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Shield.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Sprite.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\Sprite.h"
+				>
+			</File>
+			<Filter
+				Name="High Scores"
+				>
+				<File
+					RelativePath=".\src\DecoratorDefender.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\DecoratorDefender.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\DecoratorInstancerDefender.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\DecoratorInstancerDefender.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\HighScores.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\HighScores.h"
+					>
+				</File>
+			</Filter>
+		</Filter>
+		<Filter
+			Name="Starfield"
+			>
+			<File
+				RelativePath=".\src\DecoratorInstancerStarfield.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\DecoratorInstancerStarfield.h"
+				>
+			</File>
+			<File
+				RelativePath=".\src\DecoratorStarfield.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\src\DecoratorStarfield.h"
+				>
+			</File>
+		</Filter>
+		<File
+			RelativePath=".\src\main.cpp"
+			>
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

+ 65 - 0
Samples/luainvaders/PyRocketInvaders.vcproj.user

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+	ProjectType="Visual C++"
+	Version="8.00"
+	ShowAllFiles="false"
+	>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory="..\..\bin"
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine=""
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment="PATH=%PATH%..\..\support\lib;&#x0A;PYTHONPATH=..\..\support\python\lib"
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			>
+			<DebugSettings
+				Command="$(TargetPath)"
+				WorkingDirectory="..\..\bin"
+				CommandArguments=""
+				Attach="false"
+				DebuggerType="3"
+				Remote="1"
+				RemoteMachine=""
+				RemoteCommand=""
+				HttpUrl=""
+				PDBPath=""
+				SQLDebugging=""
+				Environment="PATH=%PATH%..\..\support\lib;&#x0A;PYTHONPATH=..\..\support\python\lib"
+				EnvironmentMerge="true"
+				DebuggerFlavor="0"
+				MPIRunCommand=""
+				MPIRunArguments=""
+				MPIRunWorkingDirectory=""
+				ApplicationCommand=""
+				ApplicationArguments=""
+				ShimCommand=""
+				MPIAcceptMode=""
+				MPIAcceptFilter=""
+			/>
+		</Configuration>
+	</Configurations>
+</VisualStudioUserFile>

+ 35 - 0
Samples/luainvaders/data/background.rml

@@ -0,0 +1,35 @@
+<rml>
+	<head>
+		<style>
+			body
+			{
+				width: 100%;
+				height: 100%;
+				z-index: bottom;
+
+				z-index: -1;
+			}
+
+			starfield
+			{
+				display: block;
+				width: 100%;
+				height: 100%;
+				z-index: 1;
+
+				star-decorator: starfield;
+				star-num-layers: 5;
+				star-top-colour: #fffc;
+				star-bottom-colour: #fff3;
+				star-top-speed: 80.0;
+				star-bottom-speed: 20.0;
+				star-top-density: 8;
+				star-bottom-density: 20;
+			}
+		</style>
+	</head>
+	<body>
+		<img src="background.tga" />
+		<starfield />
+	</body>
+</rml>

BIN
Samples/luainvaders/data/background.tga


+ 126 - 0
Samples/luainvaders/data/game.rml

@@ -0,0 +1,126 @@
+<rml>
+	<head>
+		<title>game</title>
+		<link type="text/template" href="window.rml" />
+		<style>
+			body
+			{
+				padding: 0px;
+				margin: 0px;
+				width: 100%;
+				height: 100%;
+
+				z-index: -1;
+			}
+			
+			game
+			{
+				display: block;
+				width: 100%;
+				height: 100%;
+			}
+
+			div
+			{
+				height: 47px;
+				padding: 9px 0px 0px 65px;
+				margin: 0px 20px;
+
+				font-size: 20;
+
+				background-decorator: tiled-horizontal;
+				background-left-image: ../../assets/invader.tga 147px 55px 229px 0px;
+				background-center-image: ../../assets/invader.tga stretch 229px 55px 230px 0px;
+				background-right-image: ../../assets/invader.tga 231px 55px 246px 0px;
+			}
+
+			div#score_div
+			{
+				float: left;
+				width: 155px;
+			}
+
+			div#hiscore_div
+			{
+				float: left;
+				width: 205px;
+			}
+
+			div#waves_div
+			{
+				float: right;
+				width: 95px;
+			}
+
+			div#lives_div
+			{
+				float: right;
+				width: 80px;
+			}
+
+			icon
+			{
+				display: block;
+				position: absolute;
+				left: 14px;
+				top: 3px;
+
+				width: 51px;
+				height: 39px;
+				
+				icon-decorator: image;
+				icon-image-src: ../../assets/invader.tga;
+				icon-image-t: 152px 191px;
+			}
+
+			div#score_div icon
+			{
+				icon-image-s: 434px 485px;
+			}
+
+			div#hiscore_div icon
+			{
+				icon-image-s: 281px 332px;
+			}
+
+			div#waves_div icon
+			{
+				icon-image-s: 332px 383px;
+			}
+
+			div#lives_div icon
+			{
+				icon-image-s: 383px 434px;
+			}
+		</style>
+		<script>
+Game = Game or {} --namespace for functions
+
+function Game.OnKeyDown(event, document)
+	if event.parameters['key_identifier'] == rocket.key_identifier.ESCAPE then
+		document.context:LoadDocument('data/pause.rml'):Show()
+    end
+end
+		</script>
+	</head>
+	<body id="game_window" onkeydown="Game.OnKeyDown(event, document)" ongameover="Window.LoadMenu('high_score',document)">
+		<game id="game">
+			<div id="score_div">
+				<icon />
+				score: <span id="score" />
+			</div>
+			<div id="hiscore_div">
+				<icon />
+				high score: <span id="hiscore" />
+			</div>
+			<div id="lives_div">
+				<icon />
+				lives: <span id="lives" />
+			</div>
+			<div id="waves_div">
+				<icon />
+				wave: <span id="waves" />
+			</div>
+		</game>
+	</body>
+</rml>

+ 55 - 0
Samples/luainvaders/data/help.rml

@@ -0,0 +1,55 @@
+<rml>
+	<head>
+		<title>Help</title>
+		<link type="text/template" href="window.rml" />
+		<style>
+			body
+			{
+				width: 50%;
+				height: 70%;
+				margin: auto;
+			}
+			
+			div#content
+			{
+				overflow-y: scroll;
+			}
+			
+			div#title_bar div#icon
+			{
+				icon-image-s: 128px 179px;
+				icon-image-t: 152px 191px;
+			}
+		</style>
+	</head>
+	<body template="luawindow">
+		<h1>Story</h1>
+		<p>
+			One day, without warning, they came for us; endless waves of the invaders, numbers too vast to count, fresh from the Martian foundries. Earth's orbital defences took a heavy toll, but were inevitably overrun, buying enough time only for a single rocket ship to launch. The prototype X-42 'Defender'-class, not yet tested but piloted by the finest astronaut the Space Corps had to offer.
+		</p>
+		<p>
+			Do you have what it takes to defeat the invaders and save Earth?
+		</p>
+		<h1>The X-42</h1>
+		<p>
+			The culmination of <img src="help_defender.tga" style="float: left; margin: -6px -24px;" />decades of research and the pinnacle of Earth's technology, the X-42 'Defender' is the finest weapon mankind has to fight the alien menace. Equipped with the dual-layer ablative tridranium armour, low-velocity depleted-narconium chain-fed belt gun and state-of-the-art liquid-hydrangea turbo-thrusters, it is still going to be nearly impossible for its pilot to secure the safety of mankind.
+		</p>
+		<h1>The Invaders</h1>
+		<p>
+			The most numerous <img src="help_invader_rank1.tga" style="float: left; margin: -4px 0px;" />invader you'll face is a primitive drone that is primarily employed by its Martian overlords in the mines of Cydonia. It is large, ungainly and poorly-armed, so ill-suited to its new role as the backbone of the invasion fleet. However, whatever it lacks in pugilistic prowess it makes up for with numbers. Each drone is worth 10 points.
+		</p>
+		<p>
+			Behind the drones <img src="help_invader_rank2.tga" style="float: right; margin: -4px 0px;" />stand the formidable berserker units, encased in their zyterium battle-suits and wielding the dreaded Nimbus death-rods. A lone unit is no match for a skilled X-42 pilot, but in large groups they adopt complex flight patterns that can confuse even the best targetting computer. Pick them off and separate them when you can. Each berserker is worth 20 points.
+		</p>
+		<p>
+			The dreaded commander <img src="help_invader_rank3.tga" style="float: left; margin: -4px 0px;" />death-droids lie at the back of every Martian wave. Small, nimble and deadly, these ships are the true test of an X-42 pilot's abilities. Consider yourself warned, and watch out especially for their mind control attack! Each droid is worth 40 points.
+		</p>
+		<p>
+			Occasionally one of the <img src="help_invader_mothership.tga" style="float: right; margin: -6px -12px;" /> invasion motherships will drop into low-orbit to provide the Martian Overbrain with a close look at the progress of the battle; this is when they are most vulnerable, destroy them if you can! The loss of even a single mothership will be keenly felt by the fleet. The points value of each mothership is variable, depending on the seniority of its command synapse.
+		</p>
+		<p>
+			Destroy all the invaders in each wave before any get past your ship to invade Earth, unleash their deadly toxin and wipe out all of humanity!
+		</p>
+		<button onclick="Window.LoadMenu('main_menu',document)">Back</button>
+	</body>
+</rml>

BIN
Samples/luainvaders/data/help_defender.tga


BIN
Samples/luainvaders/data/help_invader_mothership.tga


BIN
Samples/luainvaders/data/help_invader_rank1.tga


BIN
Samples/luainvaders/data/help_invader_rank2.tga


BIN
Samples/luainvaders/data/help_invader_rank3.tga


+ 75 - 0
Samples/luainvaders/data/high_score.rml

@@ -0,0 +1,75 @@
+<rml>
+	<head>
+		<title>High Scores</title>
+		<link type="text/template" href="window.rml" />
+		<style>
+			body
+			{
+				width: 350px;
+				height: 350px;
+				
+				margin: auto;
+			}
+			
+			div#title_bar div#icon
+			{
+				icon-image-s: 281px 331px;
+				icon-image-t: 152px 191px;
+			}
+			
+			datagrid
+			{
+				margin-bottom: 20px;
+				min-rows: 10;
+			}
+			
+			datagrid data_grid_body
+			{
+				min-height: 200px;
+			}
+			
+			defender
+			{
+				display: block;
+				width: 64px;
+				height: 16px;
+				
+				defender-decorator: defender;
+				defender-image-src: high_scores_defender.tga;
+			}
+		</style>
+		<script>
+HighScore = HighScore or {}
+
+--because we pass it as a plain function in HighScore.OnLoad, we have to pay attention
+--to the order of arguments. We don't need the first two in this case, so the name doesn't matter
+function HighScore.OnRowAdd(_,_,document)
+	input = document:GetElementById('player_input')
+	if input then
+		input:Focus()
+    end
+end
+
+function HighScore.OnLoad(window)
+	Window.OnWindowLoad(window)
+	local datagrid = window:GetElementById('datagrid')
+	datagrid:AddEventListener('rowupdate', HighScore.OnRowAdd, False)
+end
+	
+function HighScore.OnKeyDown(event)
+	if event.parameters['key_identifier'] == rocket.key_identifier.RETURN then
+		game.SetHighScoreName(event.current_element.value)
+    end
+end
+		</script>
+	</head>
+	<body template="luawindow" onload="HighScore.OnLoad(element) game.SubmitHighScore()" onunload="game.SetHighScoreName('Anon')">
+		<datagrid id="datagrid" source="high_scores.scores">
+			<col fields="name,name_required" formatter="name" width="40%">Pilot:</col>
+			<col fields="colour" formatter="ship" width="20%">Ship:</col>
+			<col fields="wave" width="20%">Wave:</col>
+			<col fields="score" width="20%">Score:</col>
+		</datagrid>
+		<button onclick="Window.LoadMenu('main_menu')">Main Menu</button>
+	</body>
+</rml>

BIN
Samples/luainvaders/data/high_scores_defender.tga


BIN
Samples/luainvaders/data/invaders.tga


+ 23 - 0
Samples/luainvaders/data/logo.rml

@@ -0,0 +1,23 @@
+<rml>
+	<head>
+		<style>
+			body
+			{
+				width: 100%;
+				height: 100%;
+
+				z-index: -1;
+			}
+			
+			#rifm_logo
+			{
+				position: absolute;
+				left: 25px;
+				top: 25px;
+			}
+		</style>
+	</head>
+	<body id="logo">
+		<img id="rifm_logo" src="logo.tga" />
+	</body>
+</rml>

BIN
Samples/luainvaders/data/logo.tga


+ 37 - 0
Samples/luainvaders/data/main_menu.rml

@@ -0,0 +1,37 @@
+<rml>
+	<head>
+		<title>Main Menu</title>
+		<link type="text/template" href="window.rml" />
+		<style>
+			body
+			{
+				width: 300px;
+				height: 225px;
+
+				margin: auto;
+			}
+			
+			div#title_bar div#icon
+			{
+				icon-image-s: 179px 230px;
+				icon-image-t: 152px 191px;
+			}
+		</style>
+		<script>
+MainMenu = MainMenu or {}
+
+function MainMenu.CloseLogo(document)
+	if document.context then
+		document.context.documents['logo']:Close()
+    end
+end
+		</script>
+	</head>
+	<body template="luawindow" onload="Window.OnWindowLoad(element) document.context:LoadDocument('data/logo.rml'):Show()" onunload="MainMenu.CloseLogo(document)">
+		<button onclick="document.context:LoadDocument('data/start_game.rml'):Show() document:Close()">Start Game</button><br />
+		<button onclick="Window.LoadMenu('high_score')">High Scores</button><br />
+		<button onclick="Window.LoadMenu('options')">Options</button><br />
+		<button onclick="Window.LoadMenu('help')">Help</button><br />
+		<button onclick="game.Shutdown()">Exit</button>
+	</body>
+</rml>

+ 88 - 0
Samples/luainvaders/data/options.rml

@@ -0,0 +1,88 @@
+<rml>
+	<head>
+		<title>Options</title>
+		<link type="text/template" href="window.rml" />
+		<style>
+			body
+			{
+				width: 350px;
+				height: 350px;
+				
+				margin: auto;
+			}
+
+			div#title_bar div#icon
+			{
+				icon-image-s: 230px 281px;
+				icon-image-t: 152px 191px;
+
+				display: none;
+			}
+
+			form div
+			{
+				width: 200px;
+				margin: auto;
+			}
+		</style>
+		<script>
+Options = Options or {}
+        
+function Options.LoadOptions(document)
+    local f = io.open('options.dat', 'r')
+    --create the function below
+    local options = cPickle.loads(''.join(f:lines()))
+    
+    document:GetElementById(options['graphics']).checked = true
+    document:GetElementById('reverb').checked = options['reverb']
+    document:GetElementById("3d").checked = options['3d']
+end
+
+function Options.SaveOptions(event, document):
+    if event.parameters['button'] == 'cancel' then
+        return
+    end
+		
+    local options = {}
+    local params = event.parameters
+    options['graphics'] = params['graphics']
+    options['reverb'] = params['reverb']
+    options['3d'] = params['3d']
+    
+    local f = io.open('options.dat', 'w+')
+    --need the below function
+    f:write(cPickle.dumps(options))
+    f:close()
+end
+		
+function Options.DisplayBadGraphics(document, display):
+	if display then
+		document:GetElementById('bad_warning').style.display = 'block'
+	else
+		document:GetElementById('bad_warning').style.display = 'none'
+    end
+end
+
+	</script>
+	</head>
+	<body template="luawindow" onload="Window.OnWindowLoad(element) Options.LoadOptions(document)">
+		<form onsubmit="Options.SaveOptions(event, document) Window.LoadMenu('main_menu')">
+			<div>
+				<p>
+					Graphics:<br />
+					<input id="good" type="radio" name="graphics" value="good"/> Good<br />
+					<input id="ok" type="radio" name="graphics" value="ok" checked="true"/> OK<br />
+					<input id="bad" type="radio" name="graphics" value="bad" onchange="DisplayBadGraphics(document, self.checked)" /> Bad<br />
+				</p>
+				<p id="bad_warning" style="display: none;">Are you sure about this? Bad graphics are just plain <em>bad.</em></p>
+				<p>
+					Audio:<br />
+					<input id="reverb" type="checkbox" name="reverb" value="true" checked="true" /> Reverb<br />
+					<input id="3d" type="checkbox" name="3d" value="true" /> 3D Spatialisation
+				</p>
+			</div>
+			<input type="submit" name="button" value="accept">Accept</input>
+			<input type="submit" name="button" value="cancel">Cancel</input>
+		</form>
+	</body>
+</rml>

+ 27 - 0
Samples/luainvaders/data/pause.rml

@@ -0,0 +1,27 @@
+<rml>
+	<head>
+		<title>Quit?</title>
+		<link type="text/template" href="window.rml" />
+		<style>
+			body
+			{
+				width: 350px;
+				height: 135px;
+				
+				margin: auto;
+			}
+			
+			div#title_bar div#icon
+			{
+				icon-image-s: 332px 383px;
+				icon-image-t: 191px 231px;
+			}
+		</style>
+	</head>
+	<body template="luawindow" onload="Window.OnWindowLoad(element) game.SetPaused(true)" onunload="game.SetPaused(false)">
+		<br />
+		<p>Are you sure you want to end this game?</p>
+		<button onclick="Window.LoadMenu('high_score') document.context.documents['game_window']:Close()">Yes</button>
+		<button onclick="document:Close()">No!</button>
+	</body>
+</rml>

+ 71 - 0
Samples/luainvaders/data/start_game.rml

@@ -0,0 +1,71 @@
+<rml>
+	<head>
+		<title>Start Game</title>
+		<link type="text/template" href="window.rml" />
+		<style>
+			body
+			{
+				width: 300px;
+				height: 225px;
+				
+				margin: auto;
+			}
+			
+			div#title_bar div#icon
+			{
+				icon-image-s: 230px 281px;
+				icon-image-t: 152px 191px;
+			}
+			
+			form div
+			{
+				width: 200px;
+				margin: auto;
+			}
+		</style>
+		<script>
+StartGame = StartGame or {}
+
+function StartGame.SetupGame(event)
+	if event.parameters['difficulty'] == 'hard' then
+		game.SetDifficulty(game.difficulty.HARD)
+	else
+		game.SetDifficulty(game.difficulty.EASY)
+    end
+	
+    --some lua trickery coming up. Compiling a string at runtime that will return the values,
+    --because they are comma separated. For example, if the user chose "Denim", then the
+    --compiled string would look like "return 21,96,189"
+    local red,green,blue = loadstring('return '..event.parameters['colour'])
+	game.SetDefenderColour(Colourb(red,green,blue,255))
+	
+	local elem = Window.LoadMenu('game'):GetElementById('game')
+	elem:Focus()
+end
+		</script>
+	</head>
+	<body template="luawindow">
+		<form onsubmit="StartGame.SetupGame(event)">
+			<div>
+				<p>
+					Difficulty:<br />
+					<input type="radio" name="difficulty" value="easy" checked="true" /> Easy<br />
+					<input type="radio" name="difficulty" value="hard" /> Hard
+				</p>
+				<p>
+					Colour:<br />
+					<select name="colour">
+						<option value="233,116,81">Burnt Sienna</option>
+						<option value="127,255,0">Chartreuse</option>
+						<option value="21,96,189">Denim</option>
+						<option value="246,74,138">French Rose</option>
+						<option value="255,0,255">Fuschia</option>
+						<option value="218,165,32">Goldenrod</option>
+						<option selected value="255,255,240">Ivory</option>
+					</select>
+				</p>
+			</div>
+			<input type="submit">Start Game!</input>
+		</form>
+	</body>
+</rml>

+ 24 - 0
Samples/luainvaders/data/window.rml

@@ -0,0 +1,24 @@
+<template name="luawindow" content="content">
+<head>
+	<link type="text/template" href="../../assets/window.rml" />
+	<script>
+Window = Window or {} --namespace
+
+function Window.OnWindowLoad(element)
+	element.owner_document:GetElementById('title').inner_rml = element.title
+end
+	
+function Window.LoadMenu(name,document)
+	local doc = document.context:LoadDocument('data/' .. name .. '.rml')
+	if doc then
+		doc:Show()
+		document:Close()
+    end
+	
+	return doc
+end
+	</script>
+</head>
+<body template="window" onload="Window.OnWindowLoad(element)">
+</body>
+</template>

+ 16 - 0
Samples/luainvaders/lua/start.lua

@@ -0,0 +1,16 @@
+
+function Startup()
+    --for k,v in pairs(rocket) do Log(k) end
+    --yes, maincontext is supposed to be global
+    --rocket.CreateContext("notmain",Vector2i(20,15))
+    local escape = rocket.key_identifier["ESCAPE"]
+    if escape ~= nil then
+    
+        maincontext = rocket.contexts()["main"]
+        maincontext:LoadDocument("data/background.rml"):Show()
+        local doc = maincontext:LoadDocument("data/main_menu.rml")
+        doc:Show()
+    end
+end
+
+Startup()

+ 86 - 0
Samples/luainvaders/src/DecoratorDefender.cpp

@@ -0,0 +1,86 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "DecoratorDefender.h"
+#include <Rocket/Core/Element.h>
+#include <Rocket/Core/Texture.h>
+#include <Rocket/Core/Math.h>
+#include <ShellOpenGL.h>
+
+DecoratorDefender::~DecoratorDefender()
+{
+}
+
+bool DecoratorDefender::Initialise(const Rocket::Core::String& image_source, const Rocket::Core::String& image_path)
+{
+	image_index = LoadTexture(image_source, image_path);
+	if (image_index == -1)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+/// Called on a decorator to generate any required per-element data for a newly decorated element.
+Rocket::Core::DecoratorDataHandle DecoratorDefender::GenerateElementData(Rocket::Core::Element* ROCKET_UNUSED(element))
+{
+	return NULL;
+}
+
+// Called to release element data generated by this decorator.
+void DecoratorDefender::ReleaseElementData(Rocket::Core::DecoratorDataHandle ROCKET_UNUSED(element_data))
+{
+}
+
+// Called to render the decorator on an element.
+void DecoratorDefender::RenderElement(Rocket::Core::Element* element, Rocket::Core::DecoratorDataHandle ROCKET_UNUSED(element_data))
+{
+	Rocket::Core::Vector2f position = element->GetAbsoluteOffset(Rocket::Core::Box::PADDING);
+	Rocket::Core::Vector2f size = element->GetBox().GetSize(Rocket::Core::Box::PADDING);
+
+	glEnable(GL_TEXTURE_2D);
+	glBindTexture(GL_TEXTURE_2D, (GLuint) GetTexture(image_index)->GetHandle(element->GetRenderInterface()));
+	Rocket::Core::Colourb colour = element->GetProperty< Rocket::Core::Colourb >("color");
+	glColor4ubv(element->GetProperty< Rocket::Core::Colourb >("color"));
+	glBegin(GL_QUADS);
+
+		glVertex2f(position.x, position.y);
+		glTexCoord2f(0, 1);
+
+		glVertex2f(position.x, position.y + size.y);
+		glTexCoord2f(1, 1);
+
+		glVertex2f(position.x + size.x, position.y + size.y);
+		glTexCoord2f(1, 0);
+
+		glVertex2f(position.x + size.x, position.y);
+		glTexCoord2f(0, 0);
+
+	glEnd();
+	glColor4ub(255, 255, 255, 255);
+}

+ 57 - 0
Samples/luainvaders/src/DecoratorDefender.h

@@ -0,0 +1,57 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSDECORATORDEFENDER_H
+#define ROCKETINVADERSDECORATORDEFENDER_H
+
+#include <Rocket/Core/Decorator.h>
+
+class DecoratorDefender : public Rocket::Core::Decorator
+{
+public:
+	virtual ~DecoratorDefender();
+
+	bool Initialise(const Rocket::Core::String& image_source, const Rocket::Core::String& image_path);
+
+	/// Called on a decorator to generate any required per-element data for a newly decorated element.
+	/// @param element[in] The newly decorated element.
+	/// @return A handle to a decorator-defined data handle, or NULL if none is needed for the element.
+	virtual Rocket::Core::DecoratorDataHandle GenerateElementData(Rocket::Core::Element* element);
+	/// Called to release element data generated by this decorator.
+	/// @param element_data[in] The element data handle to release.
+	virtual void ReleaseElementData(Rocket::Core::DecoratorDataHandle element_data);
+
+	/// Called to render the decorator on an element.
+	/// @param element[in] The element to render the decorator on.
+	/// @param element_data[in] The handle to the data generated by the decorator for the element.
+	virtual void RenderElement(Rocket::Core::Element* element, Rocket::Core::DecoratorDataHandle element_data);
+
+private:
+	int image_index;
+};
+
+#endif

+ 67 - 0
Samples/luainvaders/src/DecoratorInstancerDefender.cpp

@@ -0,0 +1,67 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "DecoratorInstancerDefender.h"
+#include <Rocket/Core/Math.h>
+#include <Rocket/Core/String.h>
+#include "DecoratorDefender.h"
+
+DecoratorInstancerDefender::DecoratorInstancerDefender()
+{
+	RegisterProperty("image-src", "").AddParser("string");
+}
+
+DecoratorInstancerDefender::~DecoratorInstancerDefender()
+{
+}
+
+// Instances a decorator given the property tag and attributes from the RCSS file.
+Rocket::Core::Decorator* DecoratorInstancerDefender::InstanceDecorator(const Rocket::Core::String& ROCKET_UNUSED(name), const Rocket::Core::PropertyDictionary& properties)
+{
+	const Rocket::Core::Property* image_source_property = properties.GetProperty("image-src");
+	Rocket::Core::String image_source = image_source_property->Get< Rocket::Core::String >();
+
+	DecoratorDefender* decorator = new DecoratorDefender();
+	if (decorator->Initialise(image_source, image_source_property->source))
+		return decorator;
+
+	decorator->RemoveReference();
+	ReleaseDecorator(decorator);
+	return NULL;
+}
+
+// Releases the given decorator.
+void DecoratorInstancerDefender::ReleaseDecorator(Rocket::Core::Decorator* decorator)
+{
+	delete decorator;
+}
+
+// Releases the instancer.
+void DecoratorInstancerDefender::Release()
+{
+	delete this;
+}

+ 56 - 0
Samples/luainvaders/src/DecoratorInstancerDefender.h

@@ -0,0 +1,56 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSDECORATORINSTANCERDEFENDER_H
+#define ROCKETINVADERSDECORATORINSTANCERDEFENDER_H
+
+#include <Rocket/Core/DecoratorInstancer.h>
+
+/**
+	@author Robert Curry
+ */
+
+class DecoratorInstancerDefender : public Rocket::Core::DecoratorInstancer
+{
+public:
+	DecoratorInstancerDefender();
+	virtual ~DecoratorInstancerDefender();
+
+	/// Instances a decorator given the property tag and attributes from the RCSS file.
+	/// @param[in] name The type of decorator desired. For example, "background-decorator: simple;" is declared as type "simple".
+	/// @param[in] properties All RCSS properties associated with the decorator.
+	/// @return The decorator if it was instanced successful, NULL if an error occured.
+	Rocket::Core::Decorator* InstanceDecorator(const Rocket::Core::String& name, const Rocket::Core::PropertyDictionary& properties);
+	/// Releases the given decorator.
+	/// @param[in] decorator Decorator to release. This is guaranteed to have been constructed by this instancer.
+	void ReleaseDecorator(Rocket::Core::Decorator* decorator);
+
+	/// Releases the instancer.
+	void Release();
+};
+
+#endif

+ 78 - 0
Samples/luainvaders/src/DecoratorInstancerStarfield.cpp

@@ -0,0 +1,78 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "DecoratorStarfield.h"
+#include <Rocket/Core/Math.h>
+#include <Rocket/Core/Types.h>
+#include "DecoratorInstancerStarfield.h"
+
+DecoratorInstancerStarfield::DecoratorInstancerStarfield()
+{
+	RegisterProperty("num-layers", "3").AddParser("number");
+	RegisterProperty("top-colour", "#dddc").AddParser("color");
+	RegisterProperty("bottom-colour", "#333c").AddParser("color");
+	RegisterProperty("top-speed", "10.0").AddParser("number");
+	RegisterProperty("bottom-speed", "2.0").AddParser("number");
+	RegisterProperty("top-density", "15").AddParser("number");
+	RegisterProperty("bottom-density", "10").AddParser("number");
+}
+
+DecoratorInstancerStarfield::~DecoratorInstancerStarfield()
+{
+}
+
+// Instances a decorator given the property tag and attributes from the RCSS file.
+Rocket::Core::Decorator* DecoratorInstancerStarfield::InstanceDecorator(const Rocket::Core::String& ROCKET_UNUSED(name), const Rocket::Core::PropertyDictionary& properties)
+{
+	int num_layers = Rocket::Core::Math::RealToInteger(properties.GetProperty("num-layers")->Get< float >());
+	Rocket::Core::Colourb top_colour = properties.GetProperty("top-colour")->Get< Rocket::Core::Colourb >();
+	Rocket::Core::Colourb bottom_colour = properties.GetProperty("bottom-colour")->Get< Rocket::Core::Colourb >();
+	float top_speed = properties.GetProperty("top-speed")->Get< float >();
+	float bottom_speed = properties.GetProperty("bottom-speed")->Get< float >();
+	int top_density = Rocket::Core::Math::RealToInteger(properties.GetProperty("top-density")->Get< float >());
+	int bottom_density = Rocket::Core::Math::RealToInteger(properties.GetProperty("bottom-density")->Get< float >());
+
+	DecoratorStarfield* decorator = new DecoratorStarfield();
+	if (decorator->Initialise(num_layers, top_colour, bottom_colour, top_speed, bottom_speed, top_density, bottom_density))
+		return decorator;
+
+	decorator->RemoveReference();
+	ReleaseDecorator(decorator);
+	return NULL;
+}
+
+// Releases the given decorator.
+void DecoratorInstancerStarfield::ReleaseDecorator(Rocket::Core::Decorator* decorator)
+{
+	delete decorator;
+}
+
+// Releases the instancer.
+void DecoratorInstancerStarfield::Release()
+{
+	delete this;
+}

+ 57 - 0
Samples/luainvaders/src/DecoratorInstancerStarfield.h

@@ -0,0 +1,57 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSDECORATORINSTANCERSTARFIELD_H
+#define ROCKETINVADERSDECORATORINSTANCERSTARFIELD_H
+
+#include <Rocket/Core/DecoratorInstancer.h>
+#include "DecoratorStarfield.h"
+
+/**
+	@author Robert Curry
+ */
+
+class DecoratorInstancerStarfield : public Rocket::Core::DecoratorInstancer
+{
+public:
+	DecoratorInstancerStarfield();
+	virtual ~DecoratorInstancerStarfield();
+
+	/// Instances a decorator given the property tag and attributes from the RCSS file.
+	/// @param name The type of decorator desired. For example, "background-decorator: simple;" is declared as type "simple".
+	/// @param properties All RCSS properties associated with the decorator.
+	/// @return The decorator if it was instanced successful, NULL if an error occured.
+	Rocket::Core::Decorator* InstanceDecorator(const Rocket::Core::String& name, const Rocket::Core::PropertyDictionary& properties);
+	/// Releases the given decorator.
+	/// @param decorator Decorator to release. This is guaranteed to have been constructed by this instancer.
+	void ReleaseDecorator(Rocket::Core::Decorator* decorator);
+
+	/// Releases the instancer.
+	void Release();
+};
+
+#endif

+ 145 - 0
Samples/luainvaders/src/DecoratorStarfield.cpp

@@ -0,0 +1,145 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "DecoratorStarfield.h"
+#include <Rocket/Core/Math.h>
+#include <Rocket/Core/Element.h>
+#include <Shell.h>
+#include <ShellOpenGL.h>
+#include "GameDetails.h"
+
+float last_update_time = 0.0f;
+
+DecoratorStarfield::~DecoratorStarfield()
+{
+}
+
+bool DecoratorStarfield::Initialise(int _num_layers, const Rocket::Core::Colourb& _top_colour, const Rocket::Core::Colourb& _bottom_colour, float _top_speed, float _bottom_speed, int _top_density, int _bottom_density)
+{
+	num_layers = _num_layers;
+	top_colour = _top_colour;
+	bottom_colour = _bottom_colour;
+	top_speed = _top_speed;
+	bottom_speed = _bottom_speed;
+	top_density = _top_density;
+	bottom_density = _bottom_density;
+
+	return true;
+}
+
+/// Called on a decorator to generate any required per-element data for a newly decorated element.
+Rocket::Core::DecoratorDataHandle DecoratorStarfield::GenerateElementData(Rocket::Core::Element* element)
+{
+	StarField* star_field = new StarField();
+
+	star_field->star_layers.resize(num_layers);
+
+	for (int i = 0; i < num_layers; i++)
+	{
+		float layer_depth = i / (float)num_layers;
+
+		int density = Rocket::Core::Math::RealToInteger((top_density * layer_depth) + (bottom_density * (1.0f - layer_depth)));
+		star_field->star_layers[i].stars.resize(density);
+
+		Rocket::Core::Colourb colour = (top_colour * layer_depth) + (bottom_colour * (1.0f - layer_depth));
+		star_field->star_layers[i].colour = colour;
+
+		float speed = (top_speed * layer_depth) + (bottom_speed * (1.0f - layer_depth));
+		star_field->star_layers[i].speed = speed;
+
+		star_field->dimensions = element->GetBox().GetSize(Rocket::Core::Box::PADDING);
+
+		if (star_field->dimensions.x > 0)
+		{
+			for (int j = 0; j < density; j++)
+			{
+				star_field->star_layers[i].stars[j].x = (float) Rocket::Core::Math::RandomReal(star_field->dimensions.x);
+				star_field->star_layers[i].stars[j].y = (float) Rocket::Core::Math::RandomReal(star_field->dimensions.y);
+			}
+		}
+
+		star_field->last_update = Shell::GetElapsedTime();
+	}
+
+	return (Rocket::Core::DecoratorDataHandle)star_field;
+}
+
+// Called to release element data generated by this decorator.
+void DecoratorStarfield::ReleaseElementData(Rocket::Core::DecoratorDataHandle element_data)
+{
+	delete (StarField*)element_data;
+}
+
+// Called to render the decorator on an element.
+void DecoratorStarfield::RenderElement(Rocket::Core::Element* ROCKET_UNUSED(element), Rocket::Core::DecoratorDataHandle element_data)
+{
+	StarField* star_field = (StarField*)element_data;
+	star_field->Update();
+
+	glDisable(GL_TEXTURE_2D);
+	glPointSize(2);
+	glBegin(GL_POINTS);
+
+	for (size_t i = 0; i < star_field->star_layers.size(); i++)
+	{
+		glColor4ubv(star_field->star_layers[i].colour);
+		
+		for (size_t j = 0; j < star_field->star_layers[i].stars.size(); j++)
+		{
+			glVertex2f(star_field->star_layers[i].stars[j].x, star_field->star_layers[i].stars[j].y);
+		}
+	}
+
+	glEnd();
+
+	glColor4ub(255, 255, 255, 255);
+}
+
+void DecoratorStarfield::StarField::Update()
+{
+	float time = Shell::GetElapsedTime();
+	float delta_time = time - last_update;
+	last_update = time;
+
+	if (!GameDetails::GetPaused())
+	{
+		for (size_t i = 0; i < star_layers.size(); i++)
+		{
+			float movement = star_layers[i].speed * delta_time;
+
+			for (size_t j = 0; j < star_layers[i].stars.size(); j++)
+			{
+				star_layers[i].stars[j].y += movement;
+				if (star_layers[i].stars[j].y > dimensions.y)
+				{
+					star_layers[i].stars[j].y = 0;
+					star_layers[i].stars[j].x = Rocket::Core::Math::RandomReal(dimensions.x);
+				}
+			}
+		}
+	}
+}

+ 82 - 0
Samples/luainvaders/src/DecoratorStarfield.h

@@ -0,0 +1,82 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSDECORATORSTARFIELD_H
+#define ROCKETINVADERSDECORATORSTARFIELD_H
+
+#include <Rocket/Core/Decorator.h>
+#include <vector>
+
+class DecoratorStarfield : public Rocket::Core::Decorator
+{
+public:
+	virtual ~DecoratorStarfield();
+
+	bool Initialise(int num_layers, const Rocket::Core::Colourb& top_colour, const Rocket::Core::Colourb& bottom_colour, float top_speed, float bottom_speed, int top_density, int bottom_density);
+
+	/// Called on a decorator to generate any required per-element data for a newly decorated element.
+	/// @param[in] element The newly decorated element.
+	/// @return A handle to a decorator-defined data handle, or NULL if none is needed for the element.
+	virtual Rocket::Core::DecoratorDataHandle GenerateElementData(Rocket::Core::Element* element);
+	/// Called to release element data generated by this decorator.
+	/// @param[in] element_data The element data handle to release.
+	virtual void ReleaseElementData(Rocket::Core::DecoratorDataHandle element_data);
+
+	/// Called to render the decorator on an element.
+	/// @param[in] element The element to render the decorator on.
+	/// @param[in] element_data The handle to the data generated by the decorator for the element.
+	virtual void RenderElement(Rocket::Core::Element* element, Rocket::Core::DecoratorDataHandle element_data);
+
+private:
+	int num_layers;
+	Rocket::Core::Colourb top_colour;
+	Rocket::Core::Colourb bottom_colour;
+	float top_speed;
+	float bottom_speed;
+	int top_density;
+	int bottom_density;
+
+	struct StarLayer
+	{
+		typedef std::vector< Rocket::Core::Vector2f > StarList;
+		StarList stars;
+		Rocket::Core::Colourb colour;
+		float speed;
+	};
+
+	struct StarField
+	{
+		void Update();
+		float last_update;
+		Rocket::Core::Vector2f dimensions;
+
+		typedef std::vector< StarLayer > StarLayerList;
+		StarLayerList star_layers;
+	};
+};
+
+#endif

+ 182 - 0
Samples/luainvaders/src/Defender.cpp

@@ -0,0 +1,182 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "Defender.h"
+#include <Shell.h>
+#include <ShellOpenGL.h>
+#include "Game.h"
+#include "GameDetails.h"
+#include "Invader.h"
+#include "Mothership.h"
+#include "Shield.h"
+#include "Sprite.h"
+
+const float UPDATE_FREQ = 0.01f;
+const float MOVEMENT_SPEED = 15;
+const float BULLET_SPEED = 15;
+const int SPRITE_WIDTH = 64;
+const float RESPAWN_TIME = 1.0f;
+
+Sprite defender_sprite(Rocket::Core::Vector2f(60, 31), Rocket::Core::Vector2f(0, 0.5), Rocket::Core::Vector2f(0.23437500, 0.98437500));
+Sprite bullet_sprite(Rocket::Core::Vector2f(4, 20), Rocket::Core::Vector2f(0.4921875, 0.515625), Rocket::Core::Vector2f(0.5078125, 0.828125));
+Sprite explosion_sprite(Rocket::Core::Vector2f(52, 28), Rocket::Core::Vector2f(0.71484375f, 0.51562500f), Rocket::Core::Vector2f(0.91796875f, 0.95312500f));
+
+Defender::Defender(Game* _game)
+{
+	move_direction = 0;
+	defender_frame_start = 0;
+	bullet_in_flight = false;
+	game = _game;
+	position.x = game->GetWindowDimensions().x / 2;
+	position.y = game->GetWindowDimensions().y - 50;
+	state = ALIVE;
+	render = true;
+}
+	
+Defender::~Defender()
+{
+}
+
+void Defender::Update()
+{
+	if (Shell::GetElapsedTime() - defender_frame_start < UPDATE_FREQ)
+		return;
+	
+	defender_frame_start = Shell::GetElapsedTime();	
+
+	position.x += (move_direction * MOVEMENT_SPEED);
+
+	if (position.x < 5)
+		position.x = 5;
+	else if (position.x > (game->GetWindowDimensions().x - SPRITE_WIDTH - 5))
+		position.x = game->GetWindowDimensions().x - SPRITE_WIDTH - 5;
+
+	// Update the bullet
+	if (bullet_in_flight)
+	{
+		// Move it up and mark it dead if it flies off the top of the screen
+		bullet_position.y -= BULLET_SPEED;
+		if (bullet_position.y < 0)
+			bullet_in_flight = false;
+	}
+
+	if (state == RESPAWN)
+	{	
+		// Switch the render flag so the defender "flickers"
+		render = !render;
+
+		// Check if we should switch back to our alive state
+		if (Shell::GetElapsedTime() - respawn_start > RESPAWN_TIME)
+		{
+			state = ALIVE;
+			render = true;
+		}		
+	}
+}
+
+void Defender::Render()
+{
+	glColor4ubv(GameDetails::GetDefenderColour());
+
+	// Render our sprite if rendering is enabled
+	if (render)
+		defender_sprite.Render(Rocket::Core::Vector2f(position.x, position.y));
+
+	// Update the bullet, doing collision detection
+	if (bullet_in_flight)
+	{
+		bullet_sprite.Render(Rocket::Core::Vector2f(bullet_position.x, bullet_position.y));
+
+		// Check if we hit the shields
+		for (int i = 0; i < game->GetNumShields(); i++)
+		{
+			if (game->GetShield(i)->CheckHit(bullet_position))
+			{
+				bullet_in_flight = false;
+				break;
+			}
+		}
+
+		if (bullet_in_flight)
+		{
+			for (int i = 0; i < game->GetNumInvaders(); i++)
+			{
+				if (game->GetInvader(i)->CheckHit(bullet_position))
+				{
+					bullet_in_flight = false;
+					break;
+				}
+			}
+		}
+	}
+
+	glColor4ub(255, 255, 255, 255);
+}
+
+void Defender::StartMove(float direction)
+{
+	move_direction = direction > 0.0f ? 1.0f : -1.0f;
+}
+
+void Defender::StopMove(float direction)
+{
+	float stop_direction = direction > 0.0f ? 1.0f : -1.0f;
+	if (stop_direction == move_direction)
+		move_direction = 0.0f;
+}
+
+void Defender::Fire()
+{
+	if (!bullet_in_flight)
+	{
+		bullet_position = position + Rocket::Core::Vector2f((SPRITE_WIDTH/2) - 4, 0);
+		bullet_in_flight = true;
+	}
+}
+
+bool Defender::CheckHit(const Rocket::Core::Vector2f& check_position)
+{	
+	float sprite_width = defender_sprite.dimensions.x;
+	float sprite_height = defender_sprite.dimensions.y;
+
+	// If the position is within our bounds, set ourselves
+	// as exploding and return a valid hit.
+	if (state == ALIVE
+		&& check_position.x >= position.x
+		&& check_position.x <= position.x + sprite_width
+		&& check_position.y >= position.y
+		&& check_position.y <= position.y + sprite_height)
+	{
+		game->RemoveLife();
+		state = RESPAWN;
+		respawn_start = Shell::GetElapsedTime();
+
+		return true;
+	}	
+
+	return false;
+}

+ 81 - 0
Samples/luainvaders/src/Defender.h

@@ -0,0 +1,81 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSDEFENDER_H
+#define ROCKETINVADERSDEFENDER_H
+
+#include <Rocket/Core/Types.h>
+
+class Game;
+class Sprite;
+
+/**
+	Represents the Earth defender. Stores position and performs the update of the bullet position and collision detection.
+	@author Lloyd Weehuizen
+ */
+
+class Defender
+{
+public:
+	Defender(Game* game);
+	~Defender();
+
+	/// Update the defender state.
+	void Update();
+	/// Render the defender.
+	void Render();
+
+	/// Move the defender left.
+	void StartMove(float direction);	
+	/// Stop the movement.
+	void StopMove(float direction);
+	/// Fire a bullet (if one isn't already in flight).
+	void Fire();	
+
+	/// Check if an object at the given position would hit the defender.
+	bool CheckHit(const Rocket::Core::Vector2f& position);
+
+private:
+	Game* game;
+	Rocket::Core::Vector2f position;	
+	
+	float move_direction;
+	
+	bool bullet_in_flight;
+	Rocket::Core::Vector2f bullet_position;
+
+	float defender_frame_start;
+	float respawn_start;
+
+	bool render;
+
+	enum State { ALIVE, RESPAWN };
+	State state;
+};
+
+
+#endif

+ 119 - 0
Samples/luainvaders/src/ElementGame.cpp

@@ -0,0 +1,119 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "ElementGame.h"
+#include <Rocket/Core/ElementDocument.h>
+#include <Rocket/Core/Input.h>
+#include <Rocket/Core/Factory.h>
+/*
+#include <Rocket/Core/Python/ElementInstancer.h>
+#include <Rocket/Core/Python/ElementWrapper.h>
+#include <Rocket/Core/Python/Python.h>
+*/
+#include "Defender.h"
+#include "Game.h"
+
+ElementGame::ElementGame(const Rocket::Core::String& tag) : Rocket::Core::Element(tag)
+{
+	game = new Game();
+}
+
+ElementGame::~ElementGame()
+{		
+	delete game;
+}
+
+void ElementGame::InitialisePythonInterface()
+{
+    //not sure that this is needed for Lua
+    /*
+	PyObject* object = python::class_<ElementGame, Rocket::Core::Python::ElementWrapper<ElementGame>, python::bases<Rocket::Core::Element>, boost::noncopyable >("ElementGame", python::init<const char*>())
+		.ptr();
+
+	Rocket::Core::Factory::RegisterElementInstancer("game", new Rocket::Core::Python::ElementInstancer(object))->RemoveReference();
+    Rocket::Core::ElementInstancerGeneric<ElementGame>();
+    */
+}
+
+// Intercepts and handles key events.
+void ElementGame::ProcessEvent(Rocket::Core::Event& event)
+{
+	Rocket::Core::Element::ProcessEvent(event);
+
+	if (event == "keydown" ||
+		event == "keyup")
+	{
+		bool key_down = event == "keydown";
+		Rocket::Core::Input::KeyIdentifier key_identifier = (Rocket::Core::Input::KeyIdentifier) event.GetParameter< int >("key_identifier", 0);		
+
+		// Process left and right keys
+		if (key_down)
+		{
+			if (key_identifier == Rocket::Core::Input::KI_LEFT)
+				game->GetDefender()->StartMove(-1.0f);
+			if (key_identifier == Rocket::Core::Input::KI_RIGHT)
+				game->GetDefender()->StartMove(1.0f);
+			if (key_identifier == Rocket::Core::Input::KI_SPACE)
+				game->GetDefender()->Fire();
+		}		
+		else if (!key_down)
+		{
+			if (key_identifier == Rocket::Core::Input::KI_LEFT)
+				game->GetDefender()->StopMove(-1.0f);
+			if (key_identifier == Rocket::Core::Input::KI_RIGHT)
+				game->GetDefender()->StopMove(1.0f);				
+		}
+	}
+
+	if (event == "load")
+	{
+		game->Initialise();
+	}
+}
+
+// Updates the game.
+void ElementGame::OnUpdate()
+{
+	game->Update();
+
+	if (game->IsGameOver())
+		DispatchEvent("gameover", Rocket::Core::Dictionary(), false);
+}
+
+// Renders the game.
+void ElementGame::OnRender()
+{
+	game->Render();
+}
+
+void ElementGame::OnChildAdd(Rocket::Core::Element* element)
+{
+	Rocket::Core::Element::OnChildAdd(element);
+
+	if (element == this)
+		GetOwnerDocument()->AddEventListener("load", this);
+}

+ 67 - 0
Samples/luainvaders/src/ElementGame.h

@@ -0,0 +1,67 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSELEMENTGAME_H
+#define ROCKETINVADERSELEMENTGAME_H
+
+#include <Rocket/Core/Element.h>
+#include <Rocket/Core/EventListener.h>
+
+class Game;
+
+/**
+	@author Peter Curry
+ */
+
+class ElementGame : public Rocket::Core::Element, public Rocket::Core::EventListener
+{
+public:
+	ElementGame(const Rocket::Core::String& tag);
+	virtual ~ElementGame();
+
+	/// Initialises the python interface and registers the serialiser
+	static void InitialisePythonInterface();
+
+	/// Intercepts and handles key events.
+	void ProcessEvent(Rocket::Core::Event& event);
+
+	/// Receive notifications when child elements are added
+	/// This will only get called when we're added to the tree,
+	/// which allows us to bind to onload
+	void OnChildAdd(Rocket::Core::Element* element);
+
+protected:
+	/// Updates the game.
+	virtual void OnUpdate();
+	/// Renders the game.
+	virtual void OnRender();
+
+private:
+	Game* game;
+};
+
+#endif

+ 445 - 0
Samples/luainvaders/src/Game.cpp

@@ -0,0 +1,445 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "Game.h"
+#include <Rocket/Core.h>
+#include <Shell.h>
+#include <ShellOpenGL.h>
+#include "Defender.h"
+#include "GameDetails.h"
+#include "HighScores.h"
+#include "Invader.h"
+#include "Mothership.h"
+#include "Shield.h"
+
+const int WINDOW_WIDTH = 1024;
+const int WINDOW_HEIGHT = 768;
+
+const int NUM_LIVES = 3;
+
+const int NUM_INVADER_ROWS = 5;
+const int NUM_INVADERS_PER_ROW = 11;
+const int NUM_INVADERS = (NUM_INVADER_ROWS * NUM_INVADERS_PER_ROW);
+const int INVADER_SPACING_X = 64;
+const int INVADER_SPACING_Y = 48;
+const int INVADER_START_Y = 96;
+
+const float INVADER_MOVEMENT = 10;
+const float INVADER_START_MOVE_FREQ = 0.5f;
+const float INVADER_UPDATE_MODIFIER = 0.7f;
+
+const int MOTHERSHIP = NUM_INVADERS;
+
+const int NUM_SHIELD_ARRAYS = 4;
+const int NUM_SHIELDS_PER_ARRAY = 10;
+const int NUM_SHIELDS = (NUM_SHIELD_ARRAYS * NUM_SHIELDS_PER_ARRAY);
+const int SHIELD_SIZE = (NUM_SHIELD_CELLS * PIXEL_SIZE);
+const int SHIELD_SPACING_X = 192;
+const int SHIELD_START_X = 176;
+const int SHIELD_START_Y = 600;
+
+// The game's element context (declared in main.cpp).
+extern Rocket::Core::Context* context;
+
+Game::Game()
+{
+	invader_frame_start = 0;
+	defender_lives = 3;	
+	game_over = false;
+	current_invader_direction = 1.0f;	
+	invaders = new Invader*[NUM_INVADERS + 1];
+	for (int i = 0; i < NUM_INVADERS + 1; i++)
+		invaders[i] = NULL;	
+
+	shields = new Shield*[NUM_SHIELDS];
+	for (int i = 0; i < NUM_SHIELDS; i++)
+		shields[i] = NULL;
+
+	// Use the OpenGL render interface to load our texture.
+	Rocket::Core::Vector2i texture_dimensions;
+	Rocket::Core::GetRenderInterface()->LoadTexture(texture, texture_dimensions, "data/invaders.tga");
+
+	defender = new Defender(this);
+}
+
+Game::~Game()
+{
+	delete defender;
+
+	for (int i = 0; i < NUM_INVADERS + 1; i++)
+		delete invaders[i];
+
+	delete [] invaders;	
+
+	for (int i = 0; i < NUM_SHIELDS; i++)
+		delete shields[i];
+
+	delete [] shields;
+}
+
+void Game::Initialise()
+{
+	// Initialise the scores and wave information
+	SetScore(0);
+	SetWave(1);
+	SetHighScore(HighScores::GetHighScore());
+	SetLives(NUM_LIVES);
+
+	// Initialise the shields.
+	InitialiseShields();
+
+	// Create a new wave
+	InitialiseWave();
+}
+
+void Game::Update()
+{
+	if (!GameDetails::GetPaused())
+	{
+		if (defender_lives <= 0)
+			return;
+
+		// Determine if we should advance the invaders
+		if (Shell::GetElapsedTime() - invader_frame_start >= invader_move_freq)
+		{
+			MoveInvaders();		
+
+			invader_frame_start = Shell::GetElapsedTime();
+		}
+
+		// Update all invaders
+		for (int i = 0; i < NUM_INVADERS + 1; i++)
+			invaders[i]->Update();	
+
+		defender->Update();
+	}
+}
+
+void Game::Render()
+{	
+	if (defender_lives <= 0)
+		return;
+
+	// Render all available shields
+	for (int i = 0; i < NUM_SHIELDS; i++)
+	{
+		shields[i]->Render();
+	}
+
+	glEnable(GL_TEXTURE_2D);
+	glBindTexture(GL_TEXTURE_2D, (GLuint) texture);
+	glColor4ub(255, 255, 255, 255);
+	glBegin(GL_QUADS);
+
+	// Render all available invaders
+	for (int i = 0; i < NUM_INVADERS + 1; i++)
+	{
+		invaders[i]->Render();
+	}
+	
+	defender->Render();
+
+	glEnd();
+}
+
+Defender* Game::GetDefender()
+{
+	return defender;
+}
+
+Invader* Game::GetInvader(int index)
+{
+	return invaders[index];
+}
+
+int Game::GetNumInvaders()
+{
+	return NUM_INVADERS + 1;
+}
+
+bool Game::CanDropBomb(int index)
+{
+	// Determines if the given invader can drop a bomb by checking if theres any other invaders under it
+	int y = (index / NUM_INVADERS_PER_ROW);
+	int x = index - (y * NUM_INVADERS_PER_ROW);
+
+	// The mothership can never drop bombs
+	if (index == MOTHERSHIP)
+		return false;
+
+	// Check each row under the given invader to see if there is space
+	for (int i = y + 1; i < NUM_INVADER_ROWS; i++)
+	{
+		if (invaders[(i * NUM_INVADERS_PER_ROW) + x]->GetState() == Invader::ALIVE)
+			return false;
+	}
+
+	return true;
+}
+
+// Access the shields.
+Shield* Game::GetShield(int index)
+{
+	return shields[index];
+}
+
+// Get the total number of shields
+int Game::GetNumShields()
+{
+	return NUM_SHIELDS;
+}
+
+// Adds a score onto the player's score.
+void Game::AddScore(int score)
+{
+	SetScore(GameDetails::GetScore() + score);
+}
+
+// Sets the player's score.
+void Game::SetScore(int score)
+{
+	GameDetails::SetScore(score);
+
+	Rocket::Core::Element* score_element = context->GetDocument("game_window")->GetElementById("score");
+	if (score_element != NULL)
+		score_element->SetInnerRML(Rocket::Core::String(128, "%d", score).CString());
+
+	// Update the high score if we've beaten it.
+	if (score > HighScores::GetHighScore())
+		SetHighScore(score);
+}
+
+// Sets the player's high-score.
+void Game::SetHighScore(int score)
+{
+	Rocket::Core::Element* high_score_element = context->GetDocument("game_window")->GetElementById("hiscore");
+	if (high_score_element != NULL)
+		high_score_element->SetInnerRML(Rocket::Core::String(128, "%d", score).CString());
+}
+
+void Game::SetLives(int lives)
+{
+	defender_lives = lives;
+
+	Rocket::Core::Element* score_element = context->GetDocument("game_window")->GetElementById("lives");
+	if (score_element != NULL)
+		score_element->SetInnerRML(Rocket::Core::String(128, "%d", defender_lives).CString());
+}
+
+void Game::SetWave(int wave)
+{
+	GameDetails::SetWave(wave);
+
+	Rocket::Core::Element* waves_element = context->GetDocument("game_window")->GetElementById("waves");
+	if (waves_element != NULL)
+		waves_element->SetInnerRML(Rocket::Core::String(128, "%d", wave).CString());
+}
+
+void Game::RemoveLife()
+{	
+	if (defender_lives > 0)
+	{
+		SetLives(defender_lives - 1);
+
+		if (defender_lives == 0)
+		{
+			OnGameOver();
+		}
+	}
+}
+
+bool Game::IsGameOver() const
+{
+	return game_over;
+}
+
+const Rocket::Core::Vector2f Game::GetWindowDimensions()
+{
+	return Rocket::Core::Vector2f((float) WINDOW_WIDTH, (float) WINDOW_HEIGHT);
+}
+
+void Game::MoveInvaders()
+{
+	Rocket::Core::Vector2f new_positions[NUM_INVADERS];
+
+	// We loop through all invaders, calculating their new positions, if any of them go over the screen bounds,
+	// then we switch direction, move the invaders down and start at 0 again
+	for (int i = 0; i < NUM_INVADERS; i++)
+	{
+		if (invaders[i]->GetState() == Invader::DEAD)
+			continue;
+
+		new_positions[i] = invaders[i]->GetPosition();
+		new_positions[i].x += INVADER_MOVEMENT * current_invader_direction;
+		if (new_positions[i].x < 0 || new_positions[i].x + INVADER_SPACING_X > WINDOW_WIDTH)
+		{
+			// Switch direction and start back at 0 (-1 as the for loop increments)
+			current_invader_direction *= -1.0f;
+			i = -1;
+
+			// Move all invaders down
+			for (int j = 0; j < NUM_INVADERS; j++)
+			{
+				if (invaders[j]->GetState() == Invader::DEAD)
+					continue;
+
+				Rocket::Core::Vector2f position = invaders[j]->GetPosition();
+				position.y += INVADER_SPACING_Y;
+				invaders[j]->SetPosition(position);
+			}
+
+			// Increase speed of invaders
+			invader_move_freq *= INVADER_UPDATE_MODIFIER;			
+		}
+	}
+
+	// Assign invaders their new position and advance their animation frame
+	bool invaders_alive = false;
+
+	for (int i = 0; i < NUM_INVADERS; i++)
+	{
+		if (invaders[i]->GetState() == Invader::DEAD)
+			continue;
+
+		invaders[i]->SetPosition(new_positions[i]);
+		invaders[i]->UpdateAnimation();
+
+		// If an invader hits the bottom, instant death
+		if (new_positions[i].y >= GetWindowDimensions().y - INVADER_SPACING_Y)
+		{
+			OnGameOver();
+			return;
+		}
+
+		invaders_alive = true;
+	}
+
+	if (!invaders_alive)
+	{
+		SetWave(GameDetails::GetWave() + 1);
+		InitialiseWave();
+	}
+}
+
+void Game::OnGameOver()
+{
+	// Set lives to zero and continue to the high scores
+	defender_lives = 0;
+	game_over = true;
+}
+
+void Game::InitialiseShields()
+{
+	Rocket::Core::Vector2f shield_array_start_position((float) SHIELD_START_X, (float) SHIELD_START_Y);
+
+	for (int x = 0; x < NUM_SHIELD_ARRAYS; x++)
+	{
+		// Top row (row of 4)
+		for (int i = 0; i < 4; i++)
+		{
+			Shield::ShieldType type = Shield::REGULAR;
+			if (i == 0)
+				type = Shield::TOP_LEFT;
+			else if (i == 3)
+			{
+				type = Shield::TOP_RIGHT;
+			}
+
+			shields[(x * NUM_SHIELDS_PER_ARRAY) + i] = new Shield(this, type);
+			shields[(x * NUM_SHIELDS_PER_ARRAY) + i]->SetPosition(shield_array_start_position + Rocket::Core::Vector2f((float) SHIELD_SIZE * i, 0));
+		}
+
+		// Middle row (row of 4)
+		for (int i = 0; i < 4; i++)
+		{
+			
+			Shield::ShieldType type = Shield::REGULAR;
+			if (i == 1)
+				type = Shield::BOTTOM_RIGHT;
+			else if (i == 2)
+			{
+				type = Shield::BOTTOM_LEFT;
+			}
+
+			shields[(x * NUM_SHIELDS_PER_ARRAY) + 4 + i] = new Shield(this, type);
+			shields[(x * NUM_SHIELDS_PER_ARRAY) + 4 + i]->SetPosition(shield_array_start_position + Rocket::Core::Vector2f((float) SHIELD_SIZE * i, (float) SHIELD_SIZE));
+		}
+
+		// Bottom row (2, one on each end)
+		shields[(x * NUM_SHIELDS_PER_ARRAY) + 8] = new Shield(this, Shield::REGULAR);
+		shields[(x * NUM_SHIELDS_PER_ARRAY) + 8]->SetPosition(shield_array_start_position + Rocket::Core::Vector2f(0, (float) SHIELD_SIZE * 2));
+
+		shields[(x * NUM_SHIELDS_PER_ARRAY) + 9] = new Shield(this, Shield::REGULAR);
+		shields[(x * NUM_SHIELDS_PER_ARRAY) + 9]->SetPosition(shield_array_start_position + Rocket::Core::Vector2f((float) SHIELD_SIZE * 3, (float) SHIELD_SIZE * 2));
+
+		shield_array_start_position.x += SHIELD_SPACING_X;
+	}
+}
+
+void Game::InitialiseWave()
+{
+	// Set up the rows
+	for (int y = 0; y < NUM_INVADER_ROWS; y++)
+	{
+		// Determine invader type
+		Invader::InvaderType type = Invader::UNKNOWN;
+		switch (y)
+		{
+		case 0:
+			type = Invader::RANK3; break;
+		case 1:
+		case 2:		
+			type = Invader::RANK2; break;
+		default:
+			type = Invader::RANK1; break;
+		}
+
+		// Determine position of top left invader
+		Rocket::Core::Vector2f invader_position((float) (WINDOW_WIDTH - (NUM_INVADERS_PER_ROW * INVADER_SPACING_X)) / 2, (float) (INVADER_START_Y + (y * INVADER_SPACING_Y)));
+	
+		for (int x = 0; x < NUM_INVADERS_PER_ROW; x++)
+		{
+			// Determine invader type based on row position
+			int index = (y * NUM_INVADERS_PER_ROW) + x;
+
+			delete invaders[index];
+			invaders[index] = new Invader(this, type, (y * NUM_INVADERS_PER_ROW) + x);			
+			invaders[index]->SetPosition(invader_position);			
+
+			// Increase invader position
+			invader_position.x += INVADER_SPACING_X;
+		}
+	}
+
+	// Reset mother ship
+	delete invaders[MOTHERSHIP];
+	invaders[MOTHERSHIP] = new Mothership(this, MOTHERSHIP);
+
+	// Update the move frequency	
+	invader_move_freq = ((((float)GameDetails::GetWave())-100.0f)/140.0f);
+	invader_move_freq *= invader_move_freq;
+}

+ 128 - 0
Samples/luainvaders/src/Game.h

@@ -0,0 +1,128 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSGAME_H
+#define ROCKETINVADERSGAME_H
+
+#include <Rocket/Core/Types.h>
+#include <Rocket/Core/Texture.h>
+
+class Shield;
+class Invader;
+class Defender;
+class Mothership;
+
+/**
+	Runs the game.
+	- Updates the Invader positions, animations and bombs.
+	- Updates the player position and bullets
+
+	@author Lloyd Weehuizen
+ */
+
+class Game
+{
+public:
+	Game();
+	~Game();
+
+	/// Initialise a new game
+	void Initialise();
+
+	/// Update the game
+	void Update();
+
+	/// Render the game
+	void Render();
+
+	/// Access the defender
+	Defender* GetDefender();
+	/// Access the invaders
+	Invader* GetInvader(int index);
+	/// Get the total number of invaders
+	int GetNumInvaders();
+
+	/// Returns true if the given invader can drop bomb
+	bool CanDropBomb(int invader_index);
+
+	/// Access the shields.
+	Shield* GetShield(int index);
+	/// Get the total number of shields
+	int GetNumShields();
+
+	/// Adds a score onto the player's score.
+	void AddScore(int score);
+	/// Sets the player's score.
+	void SetScore(int score);
+	/// Sets the player's high-score.
+	void SetHighScore(int score);
+	/// Set the number of defender lives.
+	void SetLives(int lives);
+	/// Set the current wave
+	void SetWave(int wave);
+	/// Remove a defender life
+	void RemoveLife();
+	/// Checks if the game is over
+	bool IsGameOver() const;
+
+	/// Get the dimensions of the game window.
+	const Rocket::Core::Vector2f GetWindowDimensions();	
+
+private:
+
+	// The current invaders
+	Invader** invaders;
+	// The direction they're moving
+	float current_invader_direction;
+	// Time of the last invader update
+	Rocket::Core::Time invader_frame_start;
+	// How often the invaders move
+	Rocket::Core::Time invader_move_freq;
+	// Is the game over
+	bool game_over;
+
+	// Helper function to move the invaders
+	void MoveInvaders();
+
+	// Our current defener
+	Defender* defender;
+
+	// Number of lives the defender has left
+	int defender_lives;
+
+	// The current shields
+	Shield** shields;
+
+	// Texture that contains the sprites
+	Rocket::Core::TextureHandle texture;
+
+	void InitialiseShields();
+	void InitialiseWave();
+	void OnGameOver();
+};
+
+#endif

+ 148 - 0
Samples/luainvaders/src/GameDetails.cpp

@@ -0,0 +1,148 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "GameDetails.h"
+
+static GameDetails::Difficulty difficulty = GameDetails::EASY;
+static Rocket::Core::Colourb colour = Rocket::Core::Colourb(255, 0, 0);
+static int score = -1;
+static int wave = 0;
+static bool paused = false;
+
+static GameDetails::GraphicsQuality graphics_quality = GameDetails::OK;
+static bool reverb = true;
+static bool spatialisation = false;
+
+GameDetails::GameDetails()
+{
+}
+
+GameDetails::~GameDetails()
+{
+}
+
+// Sets the game difficulty.
+void GameDetails::SetDifficulty(Difficulty _difficulty)
+{
+	difficulty = _difficulty;
+}
+
+// Returns the game difficulty.
+GameDetails::Difficulty GameDetails::GetDifficulty()
+{
+	return difficulty;
+}
+
+// Sets the colour of the player's ship.
+void GameDetails::SetDefenderColour(const Rocket::Core::Colourb& _colour)
+{
+	colour = _colour;
+}
+
+// Returns the player's ship colour.
+const Rocket::Core::Colourb& GameDetails::GetDefenderColour()
+{
+	return colour;
+}
+
+// Sets the score the player achieved in the last game.
+void GameDetails::SetScore(int _score)
+{
+	score = _score;
+}
+
+// Resets the player's score.
+void GameDetails::ResetScore()
+{
+	score = -1;
+}
+
+// Returns the score the player achieved in the last game.
+int GameDetails::GetScore()
+{
+	return score;
+}
+
+// Set the current wave number
+void GameDetails::SetWave(int _wave)
+{
+	wave = _wave;
+}
+
+// Get the current wave number
+int GameDetails::GetWave()
+{
+	return wave;
+}
+
+// Sets the pauses state of the game
+void GameDetails::SetPaused(bool _paused)
+{
+	paused = _paused;
+}
+
+// Gets if the game is paused or not
+bool GameDetails::GetPaused()
+{
+	return paused;
+}
+
+// Sets the quality of the graphics used in-game.
+void GameDetails::SetGraphicsQuality(GraphicsQuality quality)
+{
+	graphics_quality = quality;
+}
+
+// Returns the quality of the graphics to use in-game.
+GameDetails::GraphicsQuality GameDetails::GetGraphicsQuality()
+{
+	return graphics_quality;
+}
+
+// Enables or disables reverb.
+void GameDetails::SetReverb(bool enabled)
+{
+	reverb = enabled;
+}
+
+// Returns the current state of reverb.
+bool GameDetails::GetReverb()
+{
+	return reverb;
+}
+
+// Enables or disables 3D spatialisation in the audio engine.
+void GameDetails::Set3DSpatialisation(bool enabled)
+{
+	spatialisation = enabled;
+}
+
+// Returns the current state of audio spatialisation.
+bool GameDetails::Get3DSpatialisation()
+{
+	return spatialisation;
+}

+ 107 - 0
Samples/luainvaders/src/GameDetails.h

@@ -0,0 +1,107 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSGAMEDETAILS_H
+#define ROCKETINVADERSGAMEDETAILS_H
+
+#include <Rocket/Core/Types.h>
+
+/**
+	@author Peter Curry
+ */
+
+class GameDetails
+{
+public:
+	enum Difficulty { EASY, HARD };
+
+	/// Sets the game difficulty.
+	/// @param[in] difficulty The new game difficulty.
+	static void SetDifficulty(Difficulty difficulty);
+	/// Returns the game difficulty.
+	/// @return The current game difficulty.
+	static Difficulty GetDifficulty();
+
+	/// Sets the colour of the player's ship.
+	/// @param[in] colour The new ship colour.
+	static void SetDefenderColour(const Rocket::Core::Colourb& colour);
+	/// Returns the player's ship colour.
+	/// @return The colour of the player's ship.
+	static const Rocket::Core::Colourb& GetDefenderColour();
+
+	/// Sets the score the player achieved in the last game.
+	/// @param[in] score The player's score.
+	static void SetScore(int score);
+	/// Resets the player's score.
+	static void ResetScore();
+	/// Returns the score the player achieved in the last game.
+	/// @return The player's score.
+	static int GetScore();
+
+	/// Sets the current wave number
+	/// @param[in] wave The wave number
+	static void SetWave(int wave);
+	/// Get the current wave number
+	/// @return The wave number
+	static int GetWave();
+
+	/// Sets the pauses state of the game
+	/// @param[in] paused Whether the game is paused or not
+	static void SetPaused(bool paused);
+	/// Gets if the game is paused or not
+	/// @return True if the game is paused, false otherwise.
+	static bool GetPaused();
+
+	enum GraphicsQuality { GOOD, OK, BAD };
+
+	/// Sets the quality of the graphics used in-game.
+	/// @param[in] quality The new graphics quality.
+	static void SetGraphicsQuality(GraphicsQuality quality);
+	/// Returns the quality of the graphics to use in-game.
+	/// @return The currently-set graphical quality.
+	static GraphicsQuality GetGraphicsQuality();
+
+	/// Enables or disables reverb.
+	/// @param[in] enabled True to enable reverb, false to disable.
+	static void SetReverb(bool enabled);
+	/// Returns the current state of reverb.
+	/// @return The current reverb state.
+	static bool GetReverb();
+
+	/// Enables or disables 3D spatialisation in the audio engine.
+	/// @param[in] enabled True to enable spatialisation, false to disable.
+	static void Set3DSpatialisation(bool enabled);
+	/// Returns the current state of audio spatialisation.
+	/// @return The current audio spatialisation state.
+	static bool Get3DSpatialisation();
+
+private:
+	GameDetails();
+	~GameDetails();
+};
+
+#endif

+ 236 - 0
Samples/luainvaders/src/HighScores.cpp

@@ -0,0 +1,236 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "HighScores.h"
+#include <Rocket/Core/TypeConverter.h>
+#include <stdio.h>
+
+HighScores* HighScores::instance = NULL;
+
+HighScores::HighScores() : Rocket::Controls::DataSource("high_scores")
+{
+	ROCKET_ASSERT(instance == NULL);
+	instance = this;
+
+	for (int i = 0; i < NUM_SCORES; i++)
+	{
+		scores[i].score = -1;
+	}
+
+	LoadScores();
+}
+
+HighScores::~HighScores()
+{
+	ROCKET_ASSERT(instance == this);
+
+	SaveScores();
+
+	instance = NULL;
+}
+
+void HighScores::Initialise()
+{
+	new HighScores();
+}
+
+void HighScores::Shutdown()
+{
+	delete instance;
+}
+
+void HighScores::GetRow(Rocket::Core::StringList& row, const Rocket::Core::String& table, int row_index, const Rocket::Core::StringList& columns)
+{
+	if (table == "scores")
+	{
+		for (size_t i = 0; i < columns.size(); i++)
+		{
+			if (columns[i] == "name")
+			{
+				row.push_back(scores[row_index].name);
+			}
+			else if (columns[i] == "name_required")
+			{
+				row.push_back(Rocket::Core::String(4, "%d", scores[row_index].name_required));
+			}
+			else if (columns[i] == "score")
+			{
+				row.push_back(Rocket::Core::String(32, "%d", scores[row_index].score));
+			}
+			else if (columns[i] == "colour")
+			{
+				Rocket::Core::String colour_string;
+				Rocket::Core::TypeConverter< Rocket::Core::Colourb, Rocket::Core::String >::Convert(scores[row_index].colour, colour_string);
+				row.push_back(colour_string);
+			}
+			else if (columns[i] == "wave")
+			{
+				row.push_back(Rocket::Core::String(8, "%d", scores[row_index].wave));
+			}
+		}
+	}
+}
+
+int HighScores::GetNumRows(const Rocket::Core::String& table)
+{
+	if (table == "scores")
+	{
+		for (int i = 0; i < NUM_SCORES; i++)
+		{
+			if (scores[i].score == -1)
+			{
+				return i;
+			}
+		}
+
+		return NUM_SCORES;
+	}
+
+	return 0;
+}
+
+int HighScores::GetHighScore()
+{
+	if (instance->GetNumRows("scores") == 0)
+	{
+		return 0;
+	}
+
+	return instance->scores[0].score;
+}
+
+void HighScores::SubmitScore(const Rocket::Core::String& name, const Rocket::Core::Colourb& colour, int wave, int score)
+{
+	instance->SubmitScore(name, colour, wave, score, false);
+}
+
+void HighScores::SubmitScore(const Rocket::Core::Colourb& colour, int wave, int score)
+{
+	instance->SubmitScore("", colour, wave, score, true);
+}
+
+// Sets the name of the last player to submit their score.
+void HighScores::SubmitName(const Rocket::Core::String& name)
+{
+	for (int i = 0; i < instance->GetNumRows("scores"); i++)
+	{
+		if (instance->scores[i].name_required)
+		{
+			instance->scores[i].name = name;
+			instance->scores[i].name_required = false;
+			instance->NotifyRowChange("scores", i, 1);
+		}
+	}
+}
+
+void HighScores::SubmitScore(const Rocket::Core::String& name, const Rocket::Core::Colourb& colour, int wave, int score, bool name_required)
+{
+	for (int i = 0; i < NUM_SCORES; i++)
+	{
+		if (score > scores[i].score)
+		{
+			// If we've already got the maximum number of scores, then we have
+			// to send a RowsRemoved message as we're going to delete the last
+			// row from the data source.
+			bool max_rows = scores[NUM_SCORES - 1].score != -1;
+
+			// Push down all the other scores.
+			for (int j = NUM_SCORES - 1; j > i; j--)
+			{
+				scores[j] = scores[j - 1];
+			}
+
+			// Insert our new score.
+			scores[i].name = name;
+			scores[i].colour = colour;
+			scores[i].wave = wave;
+			scores[i].score = score;
+			scores[i].name_required = name_required;
+
+			// Send the row removal message (if necessary).
+			if (max_rows)
+			{
+				NotifyRowRemove("scores", NUM_SCORES - 1, 1);
+			}
+
+			// Then send the rows added message.
+			NotifyRowAdd("scores", i, 1);
+
+			return;
+		}
+	}
+}
+
+void HighScores::LoadScores()
+{
+	// Open and read the high score file.
+	FILE* scores_file = fopen("scores.txt", "rt");
+
+	if (scores_file)
+	{
+		char buffer[1024];
+		while (fgets(buffer, 1024, scores_file))
+		{
+			Rocket::Core::StringList score_parts;
+			Rocket::Core::StringUtilities::ExpandString(score_parts, Rocket::Core::String(buffer), '\t');
+			if (score_parts.size() == 4)
+			{
+				Rocket::Core::Colourb colour;
+				int wave;
+				int score;
+
+				if (Rocket::Core::TypeConverter< Rocket::Core::String , Rocket::Core::Colourb >::Convert(score_parts[1], colour) &&
+					Rocket::Core::TypeConverter< Rocket::Core::String, int >::Convert(score_parts[2], wave) &&
+					Rocket::Core::TypeConverter< Rocket::Core::String, int >::Convert(score_parts[3], score))
+				{
+					SubmitScore(score_parts[0], colour, wave, score);
+				}
+			}
+		}
+
+		fclose(scores_file);
+	}
+}
+
+void HighScores::SaveScores()
+{
+	FILE* scores_file = fopen("scores.txt", "wt");
+
+	if (scores_file)
+	{
+		for (int i = 0; i < GetNumRows("scores"); i++)
+		{
+			Rocket::Core::String colour_string;
+			Rocket::Core::TypeConverter< Rocket::Core::Colourb, Rocket::Core::String >::Convert(scores[i].colour, colour_string);
+
+			Rocket::Core::String score(1024, "%s\t%s\t%d\t%d\n", scores[i].name.CString(), colour_string.CString(), scores[i].wave, scores[i].score);
+			fputs(score.CString(), scores_file);		
+		}
+
+		fclose(scores_file);
+	}
+}

+ 77 - 0
Samples/luainvaders/src/HighScores.h

@@ -0,0 +1,77 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSHIGHSCORES_H
+#define ROCKETINVADERSHIGHSCORES_H
+
+#include <Rocket/Controls/DataSource.h>
+#include <Rocket/Core/Types.h>
+
+const int NUM_SCORES = 10;
+
+class HighScores : public Rocket::Controls::DataSource
+{
+public:
+	static void Initialise();
+	static void Shutdown();
+
+	void GetRow(Rocket::Core::StringList& row, const Rocket::Core::String& table, int row_index, const Rocket::Core::StringList& columns);
+	int GetNumRows(const Rocket::Core::String& table);
+
+	static int GetHighScore();
+
+	/// Two functions to add a score to the chart.
+	/// Adds a full score, including a name. This won't prompt the user to enter their name.
+	static void SubmitScore(const Rocket::Core::String& name, const Rocket::Core::Colourb& colour, int wave, int score);
+	/// Adds a score, and causes an input field to appear to request the user for their name.
+	static void SubmitScore(const Rocket::Core::Colourb& colour, int wave, int score);
+	/// Sets the name of the last player to submit their score.
+	static void SubmitName(const Rocket::Core::String& name);
+
+private:
+	HighScores();
+	~HighScores();
+
+	static HighScores* instance;
+
+	void SubmitScore(const Rocket::Core::String& name, const Rocket::Core::Colourb& colour, int wave, int score, bool name_required);
+	void LoadScores();
+	void SaveScores();
+
+	struct Score
+	{
+		Rocket::Core::String name;
+		bool name_required;
+		Rocket::Core::Colourb colour;
+		int score;
+		int wave;
+	};
+
+	Score scores[NUM_SCORES];
+};
+
+#endif

+ 266 - 0
Samples/luainvaders/src/Invader.cpp

@@ -0,0 +1,266 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "Invader.h"
+#include <Rocket/Core/Math.h>
+#include <Shell.h>
+#include <ShellOpenGL.h>
+#include "Defender.h"
+#include "Game.h"
+#include "GameDetails.h"
+#include "Shield.h"
+#include "Sprite.h"
+
+const float BOMB_UPDATE_FREQ = 0.04f;
+const float BOMB_RAY_SPEED = 10;
+const float BOMB_MISSILE_SPEED = 7;
+const float BOMB_PROBABILITY_EASY = 0.002f;
+const float BOMB_PROBABILITY_HARD = 0.005f;
+const float EXPLOSION_TIME = 0.25f;
+const Rocket::Core::Colourb MOTHERSHIP_COLOUR = Rocket::Core::Colourb(255, 0, 0, 255);
+
+Sprite invader_sprites[] =
+{
+	// Rank 1
+	Sprite(Rocket::Core::Vector2f(48, 32), Rocket::Core::Vector2f(0.609375f, 0), Rocket::Core::Vector2f(0.796875f, 0.5f)),
+	Sprite(Rocket::Core::Vector2f(48, 32), Rocket::Core::Vector2f(0.80078125f, 0), Rocket::Core::Vector2f(0.98828125f, 0.5f)),
+	// Rank 2
+	Sprite(Rocket::Core::Vector2f(44, 32), Rocket::Core::Vector2f(0.2578125f, 0), Rocket::Core::Vector2f(0.4296875f, 0.5f)),
+	Sprite(Rocket::Core::Vector2f(44, 32), Rocket::Core::Vector2f(0.43359375f, 0), Rocket::Core::Vector2f(0.60546875f, 0.5f)),
+	// Rank 3
+	Sprite(Rocket::Core::Vector2f(32, 32), Rocket::Core::Vector2f(0, 0), Rocket::Core::Vector2f(0.125f, 0.5f)),
+	Sprite(Rocket::Core::Vector2f(32, 32), Rocket::Core::Vector2f(0.12890625f, 0), Rocket::Core::Vector2f(0.25390625f, 0.5f)),
+	// Mothership
+	Sprite(Rocket::Core::Vector2f(64, 28), Rocket::Core::Vector2f(0.23828125f, 0.515625f), Rocket::Core::Vector2f(0.48828125f, 0.953125f)),
+	// Explosion
+	Sprite(Rocket::Core::Vector2f(52, 28), Rocket::Core::Vector2f(0.71484375f, 0.51562500f), Rocket::Core::Vector2f(0.91796875f, 0.95312500f))	
+};
+
+Sprite bomb_sprites[] =
+{
+	// Ray
+	Sprite(Rocket::Core::Vector2f(12, 20), Rocket::Core::Vector2f(0.51171875f, 0.51562500f), Rocket::Core::Vector2f(0.55859375f, 0.82812500f)),
+	Sprite(Rocket::Core::Vector2f(12, 20), Rocket::Core::Vector2f(0.56250000, 0.51562500), Rocket::Core::Vector2f(0.60937500, 0.82812500)),
+	Sprite(Rocket::Core::Vector2f(12, 20), Rocket::Core::Vector2f(0.61328125, 0.51562500), Rocket::Core::Vector2f(0.66015625, 0.82812500)),
+	Sprite(Rocket::Core::Vector2f(12, 20), Rocket::Core::Vector2f(0.66406250, 0.51562500), Rocket::Core::Vector2f(0.71093750, 0.82812500)),
+	// Missile
+	Sprite(Rocket::Core::Vector2f(12, 20), Rocket::Core::Vector2f(0.92578125, 0.51562500), Rocket::Core::Vector2f(0.97265625, 0.82812500))
+};
+
+Invader::Invader(Game* _game, InvaderType _type, int _index) : position(0,0)
+{
+	type = UNKNOWN;
+	animation_frame = 0;
+	bomb_animation_frame = 0;
+	bomb_frame_start = 0;
+	death_time = 0;
+	state = ALIVE;
+	bomb = NONE;
+	game = _game;
+	type = _type;
+	death_time = 0;
+	invader_index = _index;
+
+	bomb_probability = GameDetails::GetDifficulty() == GameDetails::EASY ? BOMB_PROBABILITY_EASY : BOMB_PROBABILITY_HARD;
+	bomb_probability *= type;
+}
+
+Invader::~Invader()
+{
+}
+
+void Invader::SetPosition(const Rocket::Core::Vector2f& _position)
+{
+	position = _position;
+}
+
+const Rocket::Core::Vector2f& Invader::GetPosition() const
+{
+	return position;
+}
+
+void Invader::Update()
+{
+	// Update the bombs
+	if (Shell::GetElapsedTime() - bomb_frame_start > BOMB_UPDATE_FREQ)
+	{	
+
+		// Update the bomb position if its in flight, or check if we should drop one
+		if (bomb != NONE)
+		{
+			if (bomb == RAY)
+			{
+				bomb_animation_frame++;
+				if (bomb_animation_frame > 3)
+					bomb_animation_frame = 0;
+
+				bomb_position.y += BOMB_RAY_SPEED;
+			}
+			else
+			{
+				bomb_position.y += BOMB_MISSILE_SPEED;
+			}
+			
+			if (bomb_position.y > game->GetWindowDimensions().y)
+				bomb = NONE;
+
+			// Check if we hit the shields
+			for (int i = 0; i < game->GetNumShields(); i++)
+			{
+				if (game->GetShield(i)->CheckHit(bomb_position))
+				{
+					bomb = NONE;
+					break;
+				}
+			}
+
+			// Check if we hit the defender
+			if (bomb != NONE)
+			{
+				if (game->GetDefender()->CheckHit(bomb_position))
+					bomb = NONE;
+			}
+		}
+		else if (state == ALIVE &&
+				 Rocket::Core::Math::RandomReal(1.0f) < bomb_probability &&
+				 game->CanDropBomb(invader_index))
+		{
+			bomb = Rocket::Core::Math::RandomInteger(2) == 0 ? RAY : MISSILE;
+			bomb_position = position;
+			bomb_position.x += invader_sprites[GetSpriteIndex()].dimensions.x / 2;
+
+			if (bomb == RAY)
+				bomb_animation_frame = 0;
+			else
+				bomb_animation_frame = 4;
+		}	
+
+		bomb_frame_start = Shell::GetElapsedTime();
+	}
+
+	if (state == EXPLODING && Shell::GetElapsedTime() > death_time)
+		state = DEAD;
+}
+
+void Invader::UpdateAnimation()
+{
+	switch (state)
+	{
+	case ALIVE:
+		animation_frame++;
+		if (animation_frame > 1)
+			animation_frame = 0;
+		break;
+
+	default:
+		break;
+	}
+}
+
+void Invader::Render()
+{
+	if (type == MOTHERSHIP)
+	{
+		glColor4ubv(MOTHERSHIP_COLOUR);
+	}
+	int sprite_index = GetSpriteIndex();
+	int sprite_offset = Rocket::Core::Math::RealToInteger((invader_sprites[sprite_index].dimensions.x - 48) / 2);
+
+	if (state != DEAD)
+		invader_sprites[sprite_index].Render(Rocket::Core::Vector2f(position.x - sprite_offset, position.y));
+	
+	if (bomb != NONE)
+	{
+		bomb_sprites[bomb_animation_frame].Render(bomb_position);
+	}
+
+	if (type == MOTHERSHIP)
+	{
+		glColor4ub(255, 255, 255, 255);
+	}
+}
+
+Invader::InvaderState Invader::GetState()
+{
+	return state;
+}
+
+bool Invader::CheckHit(const Rocket::Core::Vector2f& check_position)
+{
+	// Get the sprite index we're currently using for collision detection
+	int sprite_index = GetSpriteIndex();
+	int sprite_offset = Rocket::Core::Math::RealToInteger((invader_sprites[sprite_index].dimensions.x - 48) / 2);
+	float sprite_width = invader_sprites[sprite_index].dimensions.x;
+	float sprite_height = invader_sprites[sprite_index].dimensions.y;
+
+	// If we're alive and the position is within our bounds, set ourselves
+	// as exploding and return a valid hit
+	if (state == ALIVE
+		&& check_position.x >= position.x - sprite_offset
+		&& check_position.x <= position.x - sprite_offset + sprite_width
+		&& check_position.y >= position.y
+		&& check_position.y <= position.y + sprite_height)
+	{
+		int score = 0;
+		switch (type)
+		{
+			case MOTHERSHIP: score = (Rocket::Core::Math::RandomInteger(6) + 1) * 50; break;	// 50 -> 300
+			case RANK3: score = 40; break;
+			case RANK2: score = 20; break;
+			case RANK1: score = 10; break;
+		}
+
+		// Add the number of points
+		game->AddScore(score);
+
+		// Set our state to exploding and start the timer to our doom
+		state = EXPLODING;
+		death_time = Shell::GetElapsedTime() + EXPLOSION_TIME;	
+
+		return true;
+	}
+
+	return false;
+}
+
+int Invader::GetSpriteIndex() const
+{
+	// Calculate our sprite index based on animation and type
+	int index = animation_frame;
+	switch (type)
+	{
+		case RANK2:	index += 2; break;
+		case RANK3:	index += 4; break;
+		case MOTHERSHIP: index = 6; break;
+	}
+
+	// If we're in exploding state, use the exploding sprite
+	if (state == EXPLODING)
+		index = 7;
+
+	return index;
+}

+ 114 - 0
Samples/luainvaders/src/Invader.h

@@ -0,0 +1,114 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSINVADER_H
+#define ROCKETINVADERSINVADER_H
+
+#include <Rocket/Core/Types.h>
+
+class Game;
+
+/**
+	An alien invader.
+
+	@author Lloyd Weehuizen
+ */
+
+class Invader
+{
+public:	
+	enum InvaderType { UNKNOWN, RANK1, RANK2, RANK3, MOTHERSHIP };
+	enum BombType { NONE, RAY, MISSILE };
+
+	/// Construct the invader
+	Invader(Game* game, InvaderType type, int index);
+	~Invader();	
+
+	/// Set the invaders screen position
+	/// @param position Position in screen space
+	void SetPosition(const Rocket::Core::Vector2f& position);
+	/// Get the current invader position
+	/// @returns The invaders position in screen space
+	const Rocket::Core::Vector2f& GetPosition() const;
+
+	/// Update the invader
+	virtual void Update();	
+
+	/// Render the invader
+	void Render();
+
+	/// Update the invaders animation
+	void UpdateAnimation();
+
+	/// The current invaders state
+	enum InvaderState { ALIVE, EXPLODING, DEAD };
+	/// Get the current invader state
+	/// @returns Invader state
+	InvaderState GetState();
+
+	/// Returns true if the position hits the invader
+	/// If a hit is detected, will explode and start the death timer
+	/// @param position Position to do the hit check at
+	/// @returns If the invader was hit
+	bool CheckHit(const Rocket::Core::Vector2f& position);
+
+protected:
+	// Game this invader is in
+	Game* game;
+	// The index/id of this invader
+	int invader_index;
+
+	// The invader type we represent
+	InvaderType type;
+	// The current position in screen space of the invader
+	Rocket::Core::Vector2f position;
+	// Our current animation frame
+	int animation_frame;
+
+	// Our current state
+	InvaderState state;
+
+	// Our current in-flight bomb, or none. (may be not none if we're dead.)
+	BombType bomb;
+	// The current position of the bomb in screen space
+	Rocket::Core::Vector2f bomb_position;
+	// The animation frame the bomb is on
+	int bomb_animation_frame;
+	// When the last bomb update occured
+	float bomb_frame_start;
+	// Probability of us dropping a bomb - this is calculated
+	// at construction time and based on our rank and the game
+	// difficulty level
+	float bomb_probability;
+
+	// Time when we should die - 0, until we're hit
+	float death_time;	
+
+	int GetSpriteIndex() const;
+};
+
+#endif

+ 84 - 0
Samples/luainvaders/src/Mothership.cpp

@@ -0,0 +1,84 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "Mothership.h"
+#include <Rocket/Core/Math.h>
+#include "Shell.h"
+#include "Game.h"
+#include "Sprite.h"
+
+const int SPRITE_WIDTH = 64;
+const int SPRITE_HEIGHT = 28;
+
+const float APPEARANCE_PROBABILITY = 0.001f;
+const float UPDATE_FREQ = 0.025f;
+const float MOVEMENT_SPEED = 5;
+
+Mothership::Mothership(Game* game, int index) : Invader(game, Invader::MOTHERSHIP, index)
+{
+	// Start off dead, and set up our position
+	state = DEAD;
+	update_frame_start = 0;
+	position = Rocket::Core::Vector2f(-SPRITE_WIDTH, 64.0f);
+}
+
+Mothership::~Mothership()
+{
+}
+
+void Mothership::Update()
+{
+	// Generic Invader update
+	Invader::Update();
+
+	if (Shell::GetElapsedTime() - update_frame_start < UPDATE_FREQ)
+		return;
+
+	// We're alive, keep moving!
+	if (state == ALIVE)
+	{
+		position.x += (direction * MOVEMENT_SPEED);
+
+		if ((direction < 0.0f && position.x < -SPRITE_WIDTH)
+			|| (direction > 0.0f && position.x > game->GetWindowDimensions().x))
+			state = DEAD;
+
+		update_frame_start = Shell::GetElapsedTime();
+	}
+	// Determine if we should come out of hiding
+	else if (Rocket::Core::Math::RandomReal(1.0f) < APPEARANCE_PROBABILITY)
+	{
+		direction = Rocket::Core::Math::RandomReal(1.0f) < 0.5 ? -1.0f : 1.0f;
+
+		if (direction < 0)
+			position.x = game->GetWindowDimensions().x + SPRITE_WIDTH;
+		else
+			position.x = -SPRITE_WIDTH;
+
+		state = ALIVE;
+	}
+}

+ 53 - 0
Samples/luainvaders/src/Mothership.h

@@ -0,0 +1,53 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSMOTHERSHIP_H
+#define ROCKETINVADERSMOTHERSHIP_H
+
+#include "Invader.h"
+
+/**
+ */
+
+class Mothership : public Invader
+{
+public:
+	Mothership(Game* game, int index);
+	~Mothership();
+
+	/// Update the mothership
+	virtual void Update();	
+
+private:
+	// Time of the last update
+	float update_frame_start;
+
+	// Direction mothership is flying in
+	float direction;
+};
+
+#endif

+ 124 - 0
Samples/luainvaders/src/PythonInterface.cpp

@@ -0,0 +1,124 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "PythonInterface.h"
+#include <Shell.h>
+#include "GameDetails.h"
+#include "ElementGame.h"
+#include "HighScores.h"
+
+void SubmitHighScore()
+{
+	int score = GameDetails::GetScore();
+	if (score > 0)
+	{
+		// Submit the score the player just got to the high scores chart.
+		HighScores::SubmitScore(GameDetails::GetDefenderColour(), GameDetails::GetWave(), GameDetails::GetScore());
+		// Reset the score so the chart won't get confused next time we enter.
+		GameDetails::ResetScore();
+	}
+}
+
+BOOST_PYTHON_MODULE(game)
+{
+	python::def("Shutdown", &Shell::RequestExit);
+	python::def("SetPaused", &GameDetails::SetPaused);
+	python::def("SetDifficulty", &GameDetails::SetDifficulty);
+	python::def("SetDefenderColour", &GameDetails::SetDefenderColour);
+	python::def("SubmitHighScore", &SubmitHighScore);
+	python::def("SetHighScoreName", &HighScores::SubmitName);
+
+	python::enum_<GameDetails::Difficulty>("difficulty")
+		.value("HARD", GameDetails::HARD)
+		.value("EASY", GameDetails::EASY)
+	;
+
+	ElementGame::InitialisePythonInterface();
+}
+
+PythonInterface::PythonInterface()
+{
+}
+
+PythonInterface::~PythonInterface()
+{
+}
+
+bool PythonInterface::Initialise(const char* path)
+{
+	// Initialise Python.
+	Py_Initialize();
+
+	// Setup the Python search path.
+	const char* python_path = Py_GetPath();
+	char buffer[1024];
+	snprintf(buffer, 1024, "%s%s%s", path, PATH_SEPARATOR, python_path);
+	buffer[1023] = '\0';
+	PySys_SetPath(buffer);
+
+	// Import Rocket.
+	if (!Import("rocket"))
+		return false;
+
+	// Define our game specific interface.
+	initgame();
+
+	return true;
+}
+
+void PythonInterface::Shutdown()
+{
+	Py_Finalize();
+}
+
+bool PythonInterface::Import(const Rocket::Core::String& name)
+{
+	PyObject* module = PyImport_ImportModule(name.CString());
+	if (!module)
+	{
+		PrintError(true);
+		return false;
+	}
+
+	Py_DECREF(module);
+	return true;
+}
+
+// Print the pending python error to stderr, optionally clearing it
+void PythonInterface::PrintError(bool clear_error)
+{
+	// Print the error and restore it to the caller
+	PyObject *type, *value, *traceback;
+	PyErr_Fetch(&type, &value, &traceback);
+	Py_XINCREF(type);
+	Py_XINCREF(value);
+	Py_XINCREF(traceback);
+	PyErr_Restore(type, value, traceback);	
+	PyErr_Print();
+	if (!clear_error)
+		PyErr_Restore(type, value, traceback);
+}

+ 57 - 0
Samples/luainvaders/src/PythonInterface.h

@@ -0,0 +1,57 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef PYTHONINTERFACE_H
+#define PYTHONINTERFACE_H
+
+#include <Rocket/Core/String.h>
+#include <Rocket/Core/Python/Python.h>
+
+/**
+	Creates and maintains the python interface to Invaders.
+
+	@author Lloyd Weehuizen
+ */
+
+class PythonInterface
+{
+public:
+	static bool Initialise(const char* python_path);
+	static void Shutdown();
+
+	/// Import a python module
+	static bool Import(const Rocket::Core::String& name);
+
+	/// Print out current errors
+	static void PrintError(bool clear_error = false);
+
+private:
+	PythonInterface();
+	~PythonInterface();
+};
+
+#endif

+ 188 - 0
Samples/luainvaders/src/Shield.cpp

@@ -0,0 +1,188 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "Shield.h"
+#include <Rocket/Core/Math.h>
+#include <ShellOpenGL.h>
+#include "Game.h"
+#include "GameDetails.h"
+#include "Sprite.h"
+
+const int MAX_HEALTH = 4;
+
+Shield::Shield(Game* _game, ShieldType _type) : position(0,0)
+{
+	game = _game;
+	type = _type;
+	health = MAX_HEALTH;
+
+	InitialiseCells();
+}
+
+Shield::~Shield()
+{
+}
+
+void Shield::InitialiseCells()
+{
+	if (type == REGULAR || type == TOP_LEFT || type == TOP_RIGHT)
+	{
+		for (int i = 0; i < NUM_SHIELD_CELLS; i++)
+		{
+			for (int j = 0; j < NUM_SHIELD_CELLS; j++)
+			{
+				shield_cells[i][j] = ON;
+			}
+		}
+
+		// Take the bites out of the cells if they're a corner cell:
+		if (type == TOP_LEFT)
+		{
+			for (int x = 0; x < NUM_SHIELD_CELLS - 1; x++)
+			{
+				for (int y = 0; y < (NUM_SHIELD_CELLS - 1) - x; y++)
+					shield_cells[x][y] = OFF;
+			}
+		}
+
+		else if (type == TOP_RIGHT)
+		{
+			for (int x = 0; x < NUM_SHIELD_CELLS - 1; x++)
+			{
+				for (int y = 0; y < (NUM_SHIELD_CELLS - 1) - x; y++)
+					shield_cells[(NUM_SHIELD_CELLS - 1) - x][y] = OFF;
+			}
+		}
+	}
+	else
+	{
+		for (int i = 0; i < NUM_SHIELD_CELLS; i++)
+		{
+			for (int j = 0; j < NUM_SHIELD_CELLS; j++)
+			{
+				shield_cells[i][j] = OFF;
+			}
+		}
+
+		if (type == BOTTOM_LEFT)
+		{
+			for (int x = 0; x < NUM_SHIELD_CELLS - 1; x++)
+			{
+				for (int y = 0; y < (NUM_SHIELD_CELLS - 1) - x; y++)
+					shield_cells[(NUM_SHIELD_CELLS - 1) - x][y] = ON;
+			}
+		}
+
+		else if (type == BOTTOM_RIGHT)
+		{
+			for (int x = 0; x < NUM_SHIELD_CELLS - 1; x++)
+			{
+				for (int y = 0; y < (NUM_SHIELD_CELLS - 1) - x; y++)
+					shield_cells[x][y] = ON;
+			}
+		}
+	}
+}
+
+void Shield::SetPosition(const Rocket::Core::Vector2f& _position)
+{
+	position = _position;
+}
+
+const Rocket::Core::Vector2f& Shield::GetPosition() const
+{
+	return position;
+}
+
+void Shield::Render()
+{
+	if (health > 0)
+	{
+		glPointSize((GLfloat) PIXEL_SIZE);
+		glDisable(GL_TEXTURE_2D);
+		glColor4ubv(GameDetails::GetDefenderColour());
+
+		glBegin(GL_POINTS);
+
+		for (int i = 0; i < NUM_SHIELD_CELLS; i++)
+		{
+			for (int j = 0; j < NUM_SHIELD_CELLS; j++)
+			{
+				if (shield_cells[i][j] == ON)
+				{
+					Rocket::Core::Vector2f cell_position = position + Rocket::Core::Vector2f((float) (PIXEL_SIZE * i), (float) (PIXEL_SIZE * j));
+					glVertex2f(cell_position.x, cell_position.y);
+				}
+			}
+		}
+
+		glEnd();
+
+		glEnable(GL_TEXTURE_2D);
+	}
+}
+
+bool Shield::CheckHit(const Rocket::Core::Vector2f& check_position)
+{
+	float sprite_size = PIXEL_SIZE * NUM_SHIELD_CELLS;
+
+	// If we're alive and the position is within our bounds, set ourselves
+	// as exploding and return a valid hit
+	if (health > 0
+		&& check_position.x >= position.x
+		&& check_position.x <= position.x + sprite_size
+		&& check_position.y >= position.y
+		&& check_position.y <= position.y + sprite_size)
+	{
+		// Take damage.
+		SustainDamage();
+
+		return true;
+	}
+
+	return false;
+}
+
+void Shield::SustainDamage()
+{
+	health--;
+
+	if (health > 0)
+	{
+		int num_shields_to_lose = (NUM_SHIELD_CELLS * NUM_SHIELD_CELLS) / MAX_HEALTH;
+		while (num_shields_to_lose > 0)
+		{
+			int x = Rocket::Core::Math::RandomInteger(NUM_SHIELD_CELLS);
+			int y = Rocket::Core::Math::RandomInteger(NUM_SHIELD_CELLS);
+			if (shield_cells[x][y] != DESTROYED)
+			{
+				shield_cells[x][y] = DESTROYED;
+				num_shields_to_lose--;
+			}
+		}
+	}
+}

+ 90 - 0
Samples/luainvaders/src/Shield.h

@@ -0,0 +1,90 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSSHIELD_H
+#define ROCKETINVADERSSHIELD_H
+
+#include <Rocket/Core/Types.h>
+
+class Game;
+
+const int NUM_SHIELD_CELLS = 6;
+const int PIXEL_SIZE = 4;
+
+/**
+	A shield, protecting the player.
+
+	@author Robert Curry
+ */
+
+class Shield
+{
+public:
+	enum ShieldType { REGULAR, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT };
+
+	/// Construct the invader
+	Shield(Game* game, ShieldType type);
+	~Shield();
+
+	/// Sets up which cells are on and off, based on the type.
+	void InitialiseCells();
+
+	/// Set the shield's screen position
+	/// @param position Position in screen space
+	void SetPosition(const Rocket::Core::Vector2f& position);
+	/// Get the current shield position
+	/// @returns The shield's position in screen space
+	const Rocket::Core::Vector2f& GetPosition() const;
+
+	/// Render the shield.
+	void Render();
+
+	/// Returns true if the position hits the shield
+	/// If a hit is detected, will degrade the shield.
+	/// @param position Position to do the hit check at
+	/// @returns If the shield was hit
+	bool CheckHit(const Rocket::Core::Vector2f& position);
+
+protected:
+	void SustainDamage();
+
+	// Game this shield is in
+	Game* game;
+
+	// The invader type we represent
+	ShieldType type;
+	// The current position in screen space of the shield
+	Rocket::Core::Vector2f position;
+
+	// Our current state - starts at 4, degrades once per hit.
+	int health;
+
+	enum ShieldCellState { ON, OFF, DESTROYED };
+	ShieldCellState shield_cells[NUM_SHIELD_CELLS][NUM_SHIELD_CELLS];
+};
+
+#endif

+ 52 - 0
Samples/luainvaders/src/Sprite.cpp

@@ -0,0 +1,52 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#include "Sprite.h"
+#include <ShellOpenGL.h>
+
+Sprite::Sprite(const Rocket::Core::Vector2f& dimensions, const Rocket::Core::Vector2f& top_left_texcoord, const Rocket::Core::Vector2f& bottom_right_texcoord) : dimensions(dimensions), top_left_texcoord(top_left_texcoord), bottom_right_texcoord(bottom_right_texcoord)
+{
+}
+
+Sprite::~Sprite()
+{
+}
+
+void Sprite::Render(const Rocket::Core::Vector2f& position)
+{
+	glTexCoord2f(top_left_texcoord.x, top_left_texcoord.y);
+	glVertex2f(position.x, position.y);
+
+	glTexCoord2f(top_left_texcoord.x, bottom_right_texcoord.y);
+	glVertex2f(position.x, position.y + dimensions.y);
+
+	glTexCoord2f(bottom_right_texcoord.x, bottom_right_texcoord.y);
+	glVertex2f(position.x + dimensions.x, position.y + dimensions.y);
+
+	glTexCoord2f(bottom_right_texcoord.x, top_left_texcoord.y);
+	glVertex2f(position.x + dimensions.x, position.y);
+}

+ 50 - 0
Samples/luainvaders/src/Sprite.h

@@ -0,0 +1,50 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#ifndef ROCKETINVADERSSPRITE_H
+#define ROCKETINVADERSSPRITE_H
+
+#include <Rocket/Core/Types.h>
+
+/**
+	@author Peter Curry
+ */
+
+class Sprite
+{
+public:
+	Sprite(const Rocket::Core::Vector2f& dimensions, const Rocket::Core::Vector2f& top_left_texcoord, const Rocket::Core::Vector2f& bottom_right_texcoord);
+	~Sprite();
+
+	void Render(const Rocket::Core::Vector2f& position);
+
+	Rocket::Core::Vector2f dimensions;
+	Rocket::Core::Vector2f top_left_texcoord;
+	Rocket::Core::Vector2f bottom_right_texcoord;
+};
+
+#endif

+ 195 - 0
Samples/luainvaders/src/main.cpp

@@ -0,0 +1,195 @@
+/*
+ * This source file is part of libRocket, the HTML/CSS Interface Middleware
+ *
+ * For the latest information, see http://www.librocket.com
+ *
+ * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ */
+
+#define _WIN32_WINNT 0x0500
+#include <Rocket/Core.h>
+#include <Rocket/Controls.h>
+#include <Rocket/Debugger.h>
+
+#include <Input.h>
+#include <Shell.h>
+#include "DecoratorInstancerDefender.h"
+#include "DecoratorInstancerStarfield.h"
+#include "ElementGame.h"
+#include "HighScores.h"
+#include <Rocket/Core/Lua/Interpreter.h>
+
+Rocket::Core::Context* context = NULL;
+
+void DoAllocConsole();
+
+void GameLoop()
+{
+	context->Update();
+
+	glClear(GL_COLOR_BUFFER_BIT);
+	context->Render();
+	Shell::FlipBuffers();
+}
+
+#if defined ROCKET_PLATFORM_WIN32
+#include <windows.h>
+int APIENTRY WinMain(HINSTANCE, HINSTANCE, char*, int)
+#else
+int main(int, char**)
+#endif
+{
+	#ifdef ROCKET_PLATFORM_MACOSX
+	#define APP_PATH "../"
+	#define ROCKET_PATH "../../bin/"
+	#else
+	#define APP_PATH "../Samples/luainvaders/"
+	#define ROCKET_PATH "."
+	#endif
+
+	#ifdef ROCKET_PLATFORM_WIN32
+	DoAllocConsole();
+	#endif
+
+	// Generic OS initialisation, creates a window and attaches OpenGL.
+	if (!Shell::Initialise("../Samples/luainvaders/") ||
+		!Shell::OpenWindow("Rocket Invaders from Mars (Lua Powered)", true))
+	{
+		Shell::Shutdown();
+		return -1;
+	}
+
+	// Rocket initialisation.
+	ShellRenderInterfaceOpenGL opengl_renderer;
+	Rocket::Core::SetRenderInterface(&opengl_renderer);
+
+	ShellSystemInterface system_interface;
+	Rocket::Core::SetSystemInterface(&system_interface);
+
+	Rocket::Core::Initialise();
+	// Initialise the Rocket Controls library.
+	Rocket::Controls::Initialise();
+
+	// Initialise the Python interface.
+	//PythonInterface::Initialise((Shell::GetExecutablePath() + (APP_PATH "python") + PATH_SEPARATOR + Shell::GetExecutablePath() + ROCKET_PATH).CString());
+    Rocket::Core::Lua::Interpreter::Initialise();
+
+	// Create the main Rocket context and set it on the shell's input layer.
+	context = Rocket::Core::CreateContext("main", Rocket::Core::Vector2i(1024, 768));
+	if (context == NULL)
+	{
+		Rocket::Core::Shutdown();
+		Shell::Shutdown();
+		return -1;
+	}
+
+	Rocket::Debugger::Initialise(context);
+	Input::SetContext(context);
+
+	// Load the font faces required for Invaders.
+	Shell::LoadFonts("../assets/");
+
+	// Register Invader's custom decorator instancers.
+	Rocket::Core::DecoratorInstancer* decorator_instancer = new DecoratorInstancerStarfield();
+	Rocket::Core::Factory::RegisterDecoratorInstancer("starfield", decorator_instancer);
+	decorator_instancer->RemoveReference();
+
+	decorator_instancer = new DecoratorInstancerDefender();
+	Rocket::Core::Factory::RegisterDecoratorInstancer("defender", decorator_instancer);
+	decorator_instancer->RemoveReference();	
+
+	// Construct the game singletons.
+	HighScores::Initialise();
+
+	// Fire off the startup script.
+	//PythonInterface::Import("autoexec");
+    Rocket::Core::Lua::Interpreter::LoadFile(Rocket::Core::String(APP_PATH).Append("lua/start.lua"));
+
+	Shell::EventLoop(GameLoop);	
+
+	// Shutdown the Rocket contexts.	
+	context->RemoveReference();
+	
+	// Shutdown Python before we shut down Rocket.
+	//PythonInterface::Shutdown();
+
+	// Shut down the game singletons.
+	HighScores::Shutdown();
+
+	// Shutdown Rocket.
+	Rocket::Core::Shutdown();
+
+	Shell::CloseWindow();
+	Shell::Shutdown();
+
+	return 0;
+}
+
+#ifdef ROCKET_PLATFORM_WIN32
+
+#include <windows.h>
+#include <fcntl.h>
+#include <io.h>
+#include <process.h>
+
+void DoAllocConsole()
+{
+	static const WORD MAX_CONSOLE_LINES = 500;
+	int hConHandle;
+	long lStdHandle;
+	CONSOLE_SCREEN_BUFFER_INFO coninfo;
+	FILE *fp;
+
+	// allocate a console for this app
+	AllocConsole();
+
+	// set the screen buffer to be big enough to let us scroll text
+	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
+	coninfo.dwSize.Y = MAX_CONSOLE_LINES;
+	SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);
+
+	// redirect unbuffered STDOUT to the console
+	lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
+	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
+	fp = _fdopen( hConHandle, "w" );
+
+	*stdout = *fp;
+	setvbuf( stdout, NULL, _IONBF, 0 );
+
+	// redirect unbuffered STDIN to the console
+	lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
+	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
+	fp = _fdopen( hConHandle, "r" );
+
+	*stdin = *fp;
+	setvbuf( stdin, NULL, _IONBF, 0 );
+
+	// redirect unbuffered STDERR to the console
+	lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
+	hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
+	fp = _fdopen( hConHandle, "w" );
+	*stderr = *fp;
+
+	setvbuf( stderr, NULL, _IONBF, 0 );
+	ShowWindow(GetConsoleWindow(), SW_SHOW);
+}
+#endif

+ 2 - 9
Source/Controls/Lua/ElementDataGrid.cpp

@@ -7,13 +7,6 @@ using Rocket::Controls::ElementDataGridRow;
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-//this will be used to "inherit" from Element
-template<> void LuaType<ElementDataGrid>::extra_init(lua_State* L, int metatable_index)
-{
-    LuaType<Element>::extra_init(L,metatable_index);
-    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
-}
-
 //methods
 //methods
 int ElementDataGridAddColumn(lua_State* L, ElementDataGrid* obj)
 int ElementDataGridAddColumn(lua_State* L, ElementDataGrid* obj)
 {
 {
@@ -76,12 +69,12 @@ luaL_reg ElementDataGridSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-
+/*
 template<> const char* GetTClassName<ElementDataGrid>() { return "ElementDataGrid"; }
 template<> const char* GetTClassName<ElementDataGrid>() { return "ElementDataGrid"; }
 template<> RegType<ElementDataGrid>* GetMethodTable<ElementDataGrid>() { return ElementDataGridMethods; }
 template<> RegType<ElementDataGrid>* GetMethodTable<ElementDataGrid>() { return ElementDataGridMethods; }
 template<> luaL_reg* GetAttrTable<ElementDataGrid>() { return ElementDataGridGetters; }
 template<> luaL_reg* GetAttrTable<ElementDataGrid>() { return ElementDataGridGetters; }
 template<> luaL_reg* SetAttrTable<ElementDataGrid>() { return ElementDataGridSetters; }
 template<> luaL_reg* SetAttrTable<ElementDataGrid>() { return ElementDataGridSetters; }
-
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 1
Source/Controls/Lua/ElementDataGrid.h

@@ -36,11 +36,12 @@ RegType<ElementDataGrid> ElementDataGridMethods[];
 luaL_reg ElementDataGridGetters[];
 luaL_reg ElementDataGridGetters[];
 luaL_reg ElementDataGridSetters[];
 luaL_reg ElementDataGridSetters[];
 
 
+/*
 template<> const char* GetTClassName<ElementDataGrid>();
 template<> const char* GetTClassName<ElementDataGrid>();
 template<> RegType<ElementDataGrid>* GetMethodTable<ElementDataGrid>();
 template<> RegType<ElementDataGrid>* GetMethodTable<ElementDataGrid>();
 template<> luaL_reg* GetAttrTable<ElementDataGrid>();
 template<> luaL_reg* GetAttrTable<ElementDataGrid>();
 template<> luaL_reg* SetAttrTable<ElementDataGrid>();
 template<> luaL_reg* SetAttrTable<ElementDataGrid>();
-
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 9
Source/Controls/Lua/ElementDataGridRow.cpp

@@ -6,13 +6,6 @@ using Rocket::Controls::ElementDataGrid;
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-//this will be used to "inherit" from Element
-template<> void LuaType<ElementDataGridRow>::extra_init(lua_State* L, int metatable_index)
-{
-    LuaType<Element>::extra_init(L,metatable_index);
-    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
-}
-
 //getters
 //getters
 int ElementDataGridRowGetAttrrow_expanded(lua_State* L)
 int ElementDataGridRowGetAttrrow_expanded(lua_State* L)
 {
 {
@@ -90,12 +83,12 @@ luaL_reg ElementDataGridRowSetters[] =
     LUASETTER(ElementDataGridRow,row_expanded)
     LUASETTER(ElementDataGridRow,row_expanded)
     { NULL, NULL },
     { NULL, NULL },
 };
 };
-
+/*
 template<> const char* GetTClassName<ElementDataGridRow>() { return "ElementDataGridRow"; }
 template<> const char* GetTClassName<ElementDataGridRow>() { return "ElementDataGridRow"; }
 template<> RegType<ElementDataGridRow>* GetMethodTable<ElementDataGridRow>() { return ElementDataGridRowMethods; }
 template<> RegType<ElementDataGridRow>* GetMethodTable<ElementDataGridRow>() { return ElementDataGridRowMethods; }
 template<> luaL_reg* GetAttrTable<ElementDataGridRow>() { return ElementDataGridRowGetters; }
 template<> luaL_reg* GetAttrTable<ElementDataGridRow>() { return ElementDataGridRowGetters; }
 template<> luaL_reg* SetAttrTable<ElementDataGridRow>() { return ElementDataGridRowSetters; }
 template<> luaL_reg* SetAttrTable<ElementDataGridRow>() { return ElementDataGridRowSetters; }
-
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 0
Source/Controls/Lua/ElementDataGridRow.h

@@ -43,10 +43,12 @@ RegType<ElementDataGridRow> ElementDataGridRowMethods[];
 luaL_reg ElementDataGridRowGetters[];
 luaL_reg ElementDataGridRowGetters[];
 luaL_reg ElementDataGridRowSetters[];
 luaL_reg ElementDataGridRowSetters[];
 
 
+/*
 template<> const char* GetTClassName<ElementDataGridRow>();
 template<> const char* GetTClassName<ElementDataGridRow>();
 template<> RegType<ElementDataGridRow>* GetMethodTable<ElementDataGridRow>();
 template<> RegType<ElementDataGridRow>* GetMethodTable<ElementDataGridRow>();
 template<> luaL_reg* GetAttrTable<ElementDataGridRow>();
 template<> luaL_reg* GetAttrTable<ElementDataGridRow>();
 template<> luaL_reg* SetAttrTable<ElementDataGridRow>();
 template<> luaL_reg* SetAttrTable<ElementDataGridRow>();
+*/
 
 
 }
 }
 }
 }

+ 0 - 11
Source/Controls/Lua/ElementForm.cpp

@@ -6,13 +6,6 @@
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-
-template<> void LuaType<ElementForm>::extra_init(lua_State* L, int metatable_index)
-{
-    //inherit from Element
-    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
-}
-
 //method
 //method
 int ElementFormSubmit(lua_State* L, ElementForm* obj)
 int ElementFormSubmit(lua_State* L, ElementForm* obj)
 {
 {
@@ -39,10 +32,6 @@ luaL_reg ElementFormSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-template<> const char* GetTClassName<ElementForm>() { return "ElementForm"; }
-template<> RegType<ElementForm>* GetMethodTable<ElementForm>() { return ElementFormMethods; }
-template<> luaL_reg* GetAttrTable<ElementForm>() { return ElementFormGetters; }
-template<> luaL_reg* SetAttrTable<ElementForm>() { return ElementFormSetters; }
 
 
 }
 }
 }
 }

+ 8 - 5
Source/Controls/Lua/ElementForm.h

@@ -26,11 +26,14 @@ RegType<ElementForm> ElementFormMethods[];
 luaL_reg ElementFormGetters[];
 luaL_reg ElementFormGetters[];
 luaL_reg ElementFormSetters[];
 luaL_reg ElementFormSetters[];
 
 
-template<> const char* GetTClassName<ElementForm>();
-template<> RegType<ElementForm>* GetMethodTable<ElementForm>();
-template<> luaL_reg* GetAttrTable<ElementForm>();
-template<> luaL_reg* SetAttrTable<ElementForm>();
 
 
+/*
+template<> const char* GetTClassName<ElementForm>() { return "ElementForm"; }
+template<> RegType<ElementForm>* GetMethodTable<ElementForm>() { return ElementFormMethods; }
+template<> luaL_reg* GetAttrTable<ElementForm>() { return ElementFormGetters; }
+template<> luaL_reg* SetAttrTable<ElementForm>() { return ElementFormSetters; }
+
+*/
+}
 }
 }
 }
 }
-}

+ 0 - 12
Source/Controls/Lua/ElementFormControl.cpp

@@ -3,16 +3,9 @@
 #include <Rocket/Controls/ElementFormControl.h>
 #include <Rocket/Controls/ElementFormControl.h>
 #include <Rocket/Core/Element.h>
 #include <Rocket/Core/Element.h>
 
 
-using Rocket::Controls::ElementFormControl;
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-//this will be used to "inherit" from Element
-template<> void LuaType<ElementFormControl>::extra_init(lua_State* L, int metatable_index)
-{
-    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
-}
-
 //getters
 //getters
 int ElementFormControlGetAttrdisabled(lua_State* L)
 int ElementFormControlGetAttrdisabled(lua_State* L)
 {
 {
@@ -89,11 +82,6 @@ luaL_reg ElementFormControlSetters[] =
 };
 };
 
 
 
 
-template<> const char* GetTClassName<ElementFormControl>() { return "ElementFormControl"; }
-template<> RegType<ElementFormControl>* GetMethodTable<ElementFormControl>() { return ElementFormControlMethods; }
-template<> luaL_reg* GetAttrTable<ElementFormControl>() { return ElementFormControlGetters; }
-template<> luaL_reg* SetAttrTable<ElementFormControl>() { return ElementFormControlSetters; }
-
 }
 }
 }
 }
 }
 }

+ 9 - 8
Source/Controls/Lua/ElementFormControl.h

@@ -16,9 +16,7 @@ using Rocket::Controls::ElementFormControl;
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-//this will be used to "inherit" from Element
 template<> void LuaType<ElementFormControl>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<ElementFormControl>::extra_init(lua_State* L, int metatable_index);
-
 //getters
 //getters
 int ElementFormControlGetAttrdisabled(lua_State* L);
 int ElementFormControlGetAttrdisabled(lua_State* L);
 int ElementFormControlGetAttrname(lua_State* L);
 int ElementFormControlGetAttrname(lua_State* L);
@@ -33,11 +31,14 @@ RegType<ElementFormControl> ElementFormControlMethods[];
 luaL_reg ElementFormControlGetters[];
 luaL_reg ElementFormControlGetters[];
 luaL_reg ElementFormControlSetters[];
 luaL_reg ElementFormControlSetters[];
 
 
-template<> const char* GetTClassName<ElementFormControl>();
-template<> RegType<ElementFormControl>* GetMethodTable<ElementFormControl>();
-template<> luaL_reg* GetAttrTable<ElementFormControl>();
-template<> luaL_reg* SetAttrTable<ElementFormControl>();
-
+/*
+template<> const char* GetTClassName<ElementFormControl>() { return "ElementFormControl"; }
+template<> RegType<ElementFormControl>* GetMethodTable<ElementFormControl>() { return ElementFormControlMethods; }
+template<> luaL_reg* GetAttrTable<ElementFormControl>() { return ElementFormControlGetters; }
+template<> luaL_reg* SetAttrTable<ElementFormControl>() { return ElementFormControlSetters; }
+*/
 }
 }
 }
 }
-}
+}
+
+

+ 3 - 8
Source/Controls/Lua/ElementFormControlDataSelect.cpp

@@ -7,13 +7,7 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 //inherits from ElementFormControl which inherits from Element
 //inherits from ElementFormControl which inherits from Element
-template<> void LuaType<ElementFormControlDataSelect>::extra_init(lua_State* L, int metatable_index)
-{
-    //do whatever ElementFormControlSelect did as far as inheritance
-    LuaType<ElementFormControlSelect>::extra_init(L,metatable_index);
-    //then inherit from ElementFromControlSelect
-    LuaType<ElementFormControlSelect>::_regfunctions(L,metatable_index,metatable_index-1);
-}
+
 
 
 //method
 //method
 int ElementFormControlDataSelectSetDataSource(lua_State* L, ElementFormControlDataSelect* obj)
 int ElementFormControlDataSelectSetDataSource(lua_State* L, ElementFormControlDataSelect* obj)
@@ -40,11 +34,12 @@ luaL_reg ElementFormControlDataSelectSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-
+/*
 template<> const char* GetTClassName<ElementFormControlDataSelect>() { return "ElementFormControlDataSelect"; }
 template<> const char* GetTClassName<ElementFormControlDataSelect>() { return "ElementFormControlDataSelect"; }
 template<> RegType<ElementFormControlDataSelect>* GetMethodTable<ElementFormControlDataSelect>() { return ElementFormControlDataSelectMethods; }
 template<> RegType<ElementFormControlDataSelect>* GetMethodTable<ElementFormControlDataSelect>() { return ElementFormControlDataSelectMethods; }
 template<> luaL_reg* GetAttrTable<ElementFormControlDataSelect>() { return ElementFormControlDataSelectGetters; }
 template<> luaL_reg* GetAttrTable<ElementFormControlDataSelect>() { return ElementFormControlDataSelectGetters; }
 template<> luaL_reg* SetAttrTable<ElementFormControlDataSelect>() { return ElementFormControlDataSelectSetters; }
 template<> luaL_reg* SetAttrTable<ElementFormControlDataSelect>() { return ElementFormControlDataSelectSetters; }
+*/
 
 
 }
 }
 }
 }

+ 2 - 0
Source/Controls/Lua/ElementFormControlDataSelect.h

@@ -28,10 +28,12 @@ RegType<ElementFormControlDataSelect> ElementFormControlDataSelectMethods[];
 luaL_reg ElementFormControlDataSelectGetters[];
 luaL_reg ElementFormControlDataSelectGetters[];
 luaL_reg ElementFormControlDataSelectSetters[];
 luaL_reg ElementFormControlDataSelectSetters[];
 
 
+/*
 template<> const char* GetTClassName<ElementFormControlDataSelect>();
 template<> const char* GetTClassName<ElementFormControlDataSelect>();
 template<> RegType<ElementFormControlDataSelect>* GetMethodTable<ElementFormControlDataSelect>();
 template<> RegType<ElementFormControlDataSelect>* GetMethodTable<ElementFormControlDataSelect>();
 template<> luaL_reg* GetAttrTable<ElementFormControlDataSelect>();
 template<> luaL_reg* GetAttrTable<ElementFormControlDataSelect>();
 template<> luaL_reg* SetAttrTable<ElementFormControlDataSelect>();
 template<> luaL_reg* SetAttrTable<ElementFormControlDataSelect>();
+*/
 
 
 }
 }
 }
 }

+ 2 - 9
Source/Controls/Lua/ElementFormControlInput.cpp

@@ -6,13 +6,6 @@ using Rocket::Controls::ElementFormControl;
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-//inherits from ElementFormControl which inherits from Element
-template<> void LuaType<ElementFormControlInput>::extra_init(lua_State* L, int metatable_index)
-{
-    LuaType<ElementFormControl>::extra_init(L,metatable_index);
-    LuaType<ElementFormControl>::_regfunctions(L,metatable_index,metatable_index-1);
-}
-
 //getters
 //getters
 int ElementFormControlInputGetAttrchecked(lua_State* L)
 int ElementFormControlInputGetAttrchecked(lua_State* L)
 {
 {
@@ -149,12 +142,12 @@ luaL_reg ElementFormControlInputSetters[] =
     {NULL,NULL},
     {NULL,NULL},
 };
 };
 
 
-
+/*
 template<> const char* GetTClassName<ElementFormControlInput>() { return "ElementFormControlInput"; }
 template<> const char* GetTClassName<ElementFormControlInput>() { return "ElementFormControlInput"; }
 template<> RegType<ElementFormControlInput>* GetMethodTable<ElementFormControlInput>() { return ElementFormControlInputMethods; }
 template<> RegType<ElementFormControlInput>* GetMethodTable<ElementFormControlInput>() { return ElementFormControlInputMethods; }
 template<> luaL_reg* GetAttrTable<ElementFormControlInput>() { return ElementFormControlInputGetters; }
 template<> luaL_reg* GetAttrTable<ElementFormControlInput>() { return ElementFormControlInputGetters; }
 template<> luaL_reg* SetAttrTable<ElementFormControlInput>() { return ElementFormControlInputSetters; }
 template<> luaL_reg* SetAttrTable<ElementFormControlInput>() { return ElementFormControlInputSetters; }
-
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 0
Source/Controls/Lua/ElementFormControlInput.h

@@ -44,10 +44,12 @@ RegType<ElementFormControlInput> ElementFormControlInputMethods[];
 luaL_reg ElementFormControlInputGetters[];
 luaL_reg ElementFormControlInputGetters[];
 luaL_reg ElementFormControlInputSetters[];
 luaL_reg ElementFormControlInputSetters[];
 
 
+/*
 template<> const char* GetTClassName<ElementFormControlInput>();
 template<> const char* GetTClassName<ElementFormControlInput>();
 template<> RegType<ElementFormControlInput>* GetMethodTable<ElementFormControlInput>();
 template<> RegType<ElementFormControlInput>* GetMethodTable<ElementFormControlInput>();
 template<> luaL_reg* GetAttrTable<ElementFormControlInput>();
 template<> luaL_reg* GetAttrTable<ElementFormControlInput>();
 template<> luaL_reg* SetAttrTable<ElementFormControlInput>();
 template<> luaL_reg* SetAttrTable<ElementFormControlInput>();
+*/
 
 
 }
 }
 }
 }

+ 3 - 9
Source/Controls/Lua/ElementFormControlSelect.cpp

@@ -10,13 +10,7 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 //inherits from ElementFormControl which inherits from Element
 //inherits from ElementFormControl which inherits from Element
-template<> void LuaType<ElementFormControlSelect>::extra_init(lua_State* L, int metatable_index)
-{
-    //init whatever elementformcontrol did extra, like inheritance
-    LuaType<ElementFormControl>::extra_init(L,metatable_index);
-    //then inherit from elementformcontrol
-    LuaType<ElementFormControl>::_regfunctions(L,metatable_index,metatable_index-1);
-}
+
 
 
 //methods
 //methods
 int ElementFormControlSelectAdd(lua_State* L, ElementFormControlSelect* obj)
 int ElementFormControlSelectAdd(lua_State* L, ElementFormControlSelect* obj)
@@ -130,12 +124,12 @@ luaL_reg ElementFormControlSelectSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-
+/*
 template<> const char* GetTClassName<ElementFormControlSelect>() { return "ElementFormControlSelect"; }
 template<> const char* GetTClassName<ElementFormControlSelect>() { return "ElementFormControlSelect"; }
 template<> RegType<ElementFormControlSelect>* GetMethodTable<ElementFormControlSelect>() { return ElementFormControlSelectMethods; }
 template<> RegType<ElementFormControlSelect>* GetMethodTable<ElementFormControlSelect>() { return ElementFormControlSelectMethods; }
 template<> luaL_reg* GetAttrTable<ElementFormControlSelect>() { return ElementFormControlSelectGetters; }
 template<> luaL_reg* GetAttrTable<ElementFormControlSelect>() { return ElementFormControlSelectGetters; }
 template<> luaL_reg* SetAttrTable<ElementFormControlSelect>() { return ElementFormControlSelectSetters; }
 template<> luaL_reg* SetAttrTable<ElementFormControlSelect>() { return ElementFormControlSelectSetters; }
-
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 1
Source/Controls/Lua/ElementFormControlSelect.h

@@ -46,11 +46,12 @@ RegType<ElementFormControlSelect> ElementFormControlSelectMethods[];
 luaL_reg ElementFormControlSelectGetters[];
 luaL_reg ElementFormControlSelectGetters[];
 luaL_reg ElementFormControlSelectSetters[];
 luaL_reg ElementFormControlSelectSetters[];
 
 
+/*
 template<> const char* GetTClassName<ElementFormControlSelect>();
 template<> const char* GetTClassName<ElementFormControlSelect>();
 template<> RegType<ElementFormControlSelect>* GetMethodTable<ElementFormControlSelect>();
 template<> RegType<ElementFormControlSelect>* GetMethodTable<ElementFormControlSelect>();
 template<> luaL_reg* GetAttrTable<ElementFormControlSelect>();
 template<> luaL_reg* GetAttrTable<ElementFormControlSelect>();
 template<> luaL_reg* SetAttrTable<ElementFormControlSelect>();
 template<> luaL_reg* SetAttrTable<ElementFormControlSelect>();
-
+*/
 }
 }
 }
 }
 }
 }

+ 3 - 7
Source/Controls/Lua/ElementFormControlTextArea.cpp

@@ -6,12 +6,7 @@ using Rocket::Controls::ElementFormControl;
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-//inherits from ElementFormControl which inherits from Element
-template<> void LuaType<ElementFormControlTextArea>::extra_init(lua_State* L, int metatable_index)
-{
-    LuaType<ElementFormControl>::extra_init(L,metatable_index);
-    LuaType<ElementFormControl>::_regfunctions(L,metatable_index,metatable_index-1);
-}
+
 
 
 //getters
 //getters
 int ElementFormControlTextAreaGetAttrcols(lua_State* L)
 int ElementFormControlTextAreaGetAttrcols(lua_State* L)
@@ -108,11 +103,12 @@ luaL_reg ElementFormControlTextAreaSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-
+/*
 template<> const char* GetTClassName<ElementFormControlTextArea>() { return "ElementFormControlTextArea"; }
 template<> const char* GetTClassName<ElementFormControlTextArea>() { return "ElementFormControlTextArea"; }
 template<> RegType<ElementFormControlTextArea>* GetMethodTable<ElementFormControlTextArea>() { return ElementFormControlTextAreaMethods; }
 template<> RegType<ElementFormControlTextArea>* GetMethodTable<ElementFormControlTextArea>() { return ElementFormControlTextAreaMethods; }
 template<> luaL_reg* GetAttrTable<ElementFormControlTextArea>() { return ElementFormControlTextAreaGetters; }
 template<> luaL_reg* GetAttrTable<ElementFormControlTextArea>() { return ElementFormControlTextAreaGetters; }
 template<> luaL_reg* SetAttrTable<ElementFormControlTextArea>() { return ElementFormControlTextAreaSetters; }
 template<> luaL_reg* SetAttrTable<ElementFormControlTextArea>() { return ElementFormControlTextAreaSetters; }
+*/
 
 
 }
 }
 }
 }

+ 2 - 1
Source/Controls/Lua/ElementFormControlTextArea.h

@@ -37,11 +37,12 @@ RegType<ElementFormControlTextArea> ElementFormControlTextAreaMethods[];
 luaL_reg ElementFormControlTextAreaGetters[];
 luaL_reg ElementFormControlTextAreaGetters[];
 luaL_reg ElementFormControlTextAreaSetters[];
 luaL_reg ElementFormControlTextAreaSetters[];
 
 
+/*
 template<> const char* GetTClassName<ElementFormControlTextArea>();
 template<> const char* GetTClassName<ElementFormControlTextArea>();
 template<> RegType<ElementFormControlTextArea>* GetMethodTable<ElementFormControlTextArea>();
 template<> RegType<ElementFormControlTextArea>* GetMethodTable<ElementFormControlTextArea>();
 template<> luaL_reg* GetAttrTable<ElementFormControlTextArea>();
 template<> luaL_reg* GetAttrTable<ElementFormControlTextArea>();
 template<> luaL_reg* SetAttrTable<ElementFormControlTextArea>();
 template<> luaL_reg* SetAttrTable<ElementFormControlTextArea>();
-
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 5
Source/Controls/Lua/ElementTabSet.cpp

@@ -7,11 +7,6 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 //this will be used to "inherit" from Element
 //this will be used to "inherit" from Element
-template<> void LuaType<ElementTabSet>::extra_init(lua_State* L, int metatable_index)
-{
-    LuaType<Element>::extra_init(L,metatable_index);
-    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
-}
 
 
 //methods
 //methods
 int ElementTabSetSetPanel(lua_State* L, ElementTabSet* obj)
 int ElementTabSetSetPanel(lua_State* L, ElementTabSet* obj)
@@ -86,10 +81,12 @@ luaL_reg ElementTabSetSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
+/*
 template<> const char* GetTClassName<ElementTabSet>() { return "ElementTabSet"; }
 template<> const char* GetTClassName<ElementTabSet>() { return "ElementTabSet"; }
 template<> RegType<ElementTabSet>* GetMethodTable<ElementTabSet>() { return ElementTabSetMethods; }
 template<> RegType<ElementTabSet>* GetMethodTable<ElementTabSet>() { return ElementTabSetMethods; }
 template<> luaL_reg* GetAttrTable<ElementTabSet>() { return ElementTabSetGetters; }
 template<> luaL_reg* GetAttrTable<ElementTabSet>() { return ElementTabSetGetters; }
 template<> luaL_reg* SetAttrTable<ElementTabSet>() { return ElementTabSetSetters; }
 template<> luaL_reg* SetAttrTable<ElementTabSet>() { return ElementTabSetSetters; }
+*/
 
 
 }
 }
 }
 }

+ 2 - 1
Source/Controls/Lua/ElementTabSet.h

@@ -42,11 +42,12 @@ RegType<ElementTabSet> ElementTabSetMethods[];
 luaL_reg ElementTabSetGetters[];
 luaL_reg ElementTabSetGetters[];
 luaL_reg ElementTabSetSetters[];
 luaL_reg ElementTabSetSetters[];
 
 
+/*
 template<> const char* GetTClassName<ElementTabSet>();
 template<> const char* GetTClassName<ElementTabSet>();
 template<> RegType<ElementTabSet>* GetMethodTable<ElementTabSet>();
 template<> RegType<ElementTabSet>* GetMethodTable<ElementTabSet>();
 template<> luaL_reg* GetAttrTable<ElementTabSet>();
 template<> luaL_reg* GetAttrTable<ElementTabSet>();
 template<> luaL_reg* SetAttrTable<ElementTabSet>();
 template<> luaL_reg* SetAttrTable<ElementTabSet>();
-
+*/
 }
 }
 }
 }
 }
 }

+ 0 - 27
Source/Core/Lua/Colourb.cpp

@@ -5,25 +5,6 @@
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-
-
-template<> void LuaType<Colourb>::extra_init(lua_State* L, int metatable_index)
-{
-    lua_pushcfunction(L,Colourb__call);
-    lua_setfield(L,metatable_index,"__call");
-
-    lua_pushcfunction(L,Colourb__eq);
-    lua_setfield(L,metatable_index,"__eq");
-
-    lua_pushcfunction(L,Colourb__add);
-    lua_setfield(L,metatable_index,"__add");
-
-    lua_pushcfunction(L,Colourb__mul);
-    lua_setfield(L,metatable_index,"__mul");
-
-    return;
-}
-
 int Colourb__call(lua_State* L)
 int Colourb__call(lua_State* L)
 {
 {
     byte red = (byte)luaL_checkint(L,1);
     byte red = (byte)luaL_checkint(L,1);
@@ -167,14 +148,6 @@ luaL_reg ColourbSetters[] =
     LUASETTER(Colourb,alpha)
     LUASETTER(Colourb,alpha)
     { NULL, NULL },
     { NULL, NULL },
 };
 };
-
-
-template<> const char* GetTClassName<Colourb>() { return "Colourb"; }
-template<> RegType<Colourb>* GetMethodTable<Colourb>() { return ColourbMethods; }
-template<> luaL_reg* GetAttrTable<Colourb>() { return ColourbGetters; }
-template<> luaL_reg* SetAttrTable<Colourb>() { return ColourbSetters; }
-
-
 }
 }
 }
 }
 }
 }

+ 11 - 8
Source/Core/Lua/Colourb.h

@@ -1,4 +1,5 @@
-#pragma once
+#ifndef ROCKETCORELUACOLOURB_H
+#define ROCKETCORELUACOLOURB_H
 /*
 /*
     Declares Colourb in the Lua global namespace. It implements the below (examples using Lua syntax) :
     Declares Colourb in the Lua global namespace. It implements the below (examples using Lua syntax) :
 
 
@@ -29,10 +30,10 @@
 #include "lua.hpp"
 #include "lua.hpp"
 #include <Rocket/Core/Types.h>
 #include <Rocket/Core/Types.h>
 
 
+using Rocket::Core::Colourb;
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-
 template<> void LuaType<Colourb>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<Colourb>::extra_init(lua_State* L, int metatable_index);
 int Colourb__call(lua_State* L);
 int Colourb__call(lua_State* L);
 int Colourb__eq(lua_State* L);
 int Colourb__eq(lua_State* L);
@@ -57,11 +58,13 @@ RegType<Colourb> ColourbMethods[];
 luaL_reg ColourbGetters[];
 luaL_reg ColourbGetters[];
 luaL_reg ColourbSetters[];
 luaL_reg ColourbSetters[];
 
 
-template<> const char* GetTClassName<Colourb>();
-template<> RegType<Colourb>* GetMethodTable<Colourb>();
-template<> luaL_reg* GetAttrTable<Colourb>();
-template<> luaL_reg* SetAttrTable<Colourb>();
-
+/*
+template<> const char* GetTClassName<Colourb>() { return "Colourb"; }
+template<> RegType<Colourb>* GetMethodTable<Colourb>() { return ColourbMethods; }
+template<> luaL_reg* GetAttrTable<Colourb>() { return ColourbGetters; }
+template<> luaL_reg* SetAttrTable<Colourb>() { return ColourbSetters; }
+*/
+}
 }
 }
 }
 }
-}
+#endif

+ 1 - 14
Source/Core/Lua/Colourf.cpp

@@ -7,16 +7,6 @@ namespace Core {
 namespace Lua {
 namespace Lua {
 
 
 //metamethods
 //metamethods
-template<> void LuaType<Colourf>::extra_init(lua_State* L, int metatable_index)
-{
-    lua_pushcfunction(L,Colourf__call);
-    lua_setfield(L,metatable_index,"__call");
-
-    lua_pushcfunction(L,Colourf__eq);
-    lua_setfield(L,metatable_index,"__eq");
-
-    return;
-}
 
 
 
 
 int Colourf__call(lua_State* L)
 int Colourf__call(lua_State* L)
@@ -141,10 +131,7 @@ luaL_reg ColourfSetters[] =
 };
 };
 
 
 
 
-template<> const char* GetTClassName<Colourf>() { return "Colourf"; }
-template<> RegType<Colourf>* GetMethodTable<Colourf>() { return ColourfMethods; }
-template<> luaL_reg* GetAttrTable<Colourf>() { return ColourfGetters; }
-template<> luaL_reg* SetAttrTable<Colourf>() { return ColourfSetters; }
+
 
 
 }
 }
 }
 }

+ 11 - 9
Source/Core/Lua/Colourf.h

@@ -27,13 +27,12 @@
 #include "LuaType.h"
 #include "LuaType.h"
 #include <Rocket/Core/Types.h>
 #include <Rocket/Core/Types.h>
 
 
-
+using Rocket::Core::Colourf;
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-
-//metamethods
 template<> void LuaType<Colourf>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<Colourf>::extra_init(lua_State* L, int metatable_index);
+//metamethods
 int Colourf__call(lua_State* L);
 int Colourf__call(lua_State* L);
 int Colourf__eq(lua_State* L);
 int Colourf__eq(lua_State* L);
 
 
@@ -54,11 +53,14 @@ RegType<Colourf> ColourfMethods[];
 luaL_reg ColourfGetters[];
 luaL_reg ColourfGetters[];
 luaL_reg ColourfSetters[];
 luaL_reg ColourfSetters[];
 
 
-template<> const char* GetTClassName<Colourf>();
-template<> RegType<Colourf>* GetMethodTable<Colourf>();
-template<> luaL_reg* GetAttrTable<Colourf>();
-template<> luaL_reg* SetAttrTable<Colourf>();
-
+/*
+template<> const char* GetTClassName<Colourf>() { return "Colourf"; }
+template<> RegType<Colourf>* GetMethodTable<Colourf>() { return ColourfMethods; }
+template<> luaL_reg* GetAttrTable<Colourf>() { return ColourfGetters; }
+template<> luaL_reg* SetAttrTable<Colourf>() { return ColourfSetters; }
+*/
+}
 }
 }
 }
 }
-}
+
+

+ 2 - 1
Source/Core/Lua/Context.cpp

@@ -208,11 +208,12 @@ luaL_reg ContextSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
+/*
 template<> const char* GetTClassName<Context>() { return "Context"; }
 template<> const char* GetTClassName<Context>() { return "Context"; }
 template<> RegType<Context>* GetMethodTable<Context>() { return ContextMethods; }
 template<> RegType<Context>* GetMethodTable<Context>() { return ContextMethods; }
 template<> luaL_reg* GetAttrTable<Context>() { return ContextGetters; }
 template<> luaL_reg* GetAttrTable<Context>() { return ContextGetters; }
 template<> luaL_reg* SetAttrTable<Context>() { return ContextSetters; }
 template<> luaL_reg* SetAttrTable<Context>() { return ContextSetters; }
-
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 2
Source/Core/Lua/Context.h

@@ -36,7 +36,6 @@
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-//class Rocket::Core::Context;
 
 
 //methods
 //methods
 int ContextAddEventListener(lua_State* L, Context* obj);
 int ContextAddEventListener(lua_State* L, Context* obj);
@@ -68,11 +67,12 @@ RegType<Context> ContextMethods[];
 luaL_reg ContextGetters[];
 luaL_reg ContextGetters[];
 luaL_reg ContextSetters[];
 luaL_reg ContextSetters[];
 
 
+/*
 template<> const char* GetTClassName<Context>();
 template<> const char* GetTClassName<Context>();
 template<> RegType<Context>* GetMethodTable<Context>();
 template<> RegType<Context>* GetMethodTable<Context>();
 template<> luaL_reg* GetAttrTable<Context>();
 template<> luaL_reg* GetAttrTable<Context>();
 template<> luaL_reg* SetAttrTable<Context>();
 template<> luaL_reg* SetAttrTable<Context>();
-
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 6
Source/Core/Lua/Document.cpp

@@ -6,11 +6,6 @@
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-template<> void LuaType<Document>::extra_init(lua_State* L, int metatable_index)
-{
-    //we will get all of the stuff from the "Element" class
-    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index - 1);
-}
 
 
 //methods
 //methods
 int DocumentPullToFront(lua_State* L, Document* obj)
 int DocumentPullToFront(lua_State* L, Document* obj)
@@ -116,11 +111,12 @@ luaL_reg DocumentSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-
+/*
 template<> const char* GetTClassName<Document>() { return "Document"; }
 template<> const char* GetTClassName<Document>() { return "Document"; }
 template<> RegType<Document>* GetMethodTable<Document>() { return DocumentMethods; }
 template<> RegType<Document>* GetMethodTable<Document>() { return DocumentMethods; }
 template<> luaL_reg* GetAttrTable<Document>() { return DocumentGetters; }
 template<> luaL_reg* GetAttrTable<Document>() { return DocumentGetters; }
 template<> luaL_reg* SetAttrTable<Document>() { return DocumentSetters; }
 template<> luaL_reg* SetAttrTable<Document>() { return DocumentSetters; }
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 0
Source/Core/Lua/Document.h

@@ -54,10 +54,12 @@ RegType<Document> DocumentMethods[];
 luaL_reg DocumentGetters[];
 luaL_reg DocumentGetters[];
 luaL_reg DocumentSetters[];
 luaL_reg DocumentSetters[];
 
 
+/*
 template<> const char* GetTClassName<Document>();
 template<> const char* GetTClassName<Document>();
 template<> RegType<Document>* GetMethodTable<Document>();
 template<> RegType<Document>* GetMethodTable<Document>();
 template<> luaL_reg* GetAttrTable<Document>();
 template<> luaL_reg* GetAttrTable<Document>();
 template<> luaL_reg* SetAttrTable<Document>();
 template<> luaL_reg* SetAttrTable<Document>();
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 2
Source/Core/Lua/Element.cpp

@@ -1,4 +1,3 @@
-#include "LuaType.h"
 #include "precompiled.h"
 #include "precompiled.h"
 #include "Element.h"
 #include "Element.h"
 #include <ElementStyle.h>
 #include <ElementStyle.h>
@@ -609,11 +608,12 @@ luaL_reg ElementSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-
+/*
 template<> const char* GetTClassName<Element>() { return "Element"; }
 template<> const char* GetTClassName<Element>() { return "Element"; }
 template<> RegType<Element>* GetMethodTable<Element>() { return ElementMethods; }
 template<> RegType<Element>* GetMethodTable<Element>() { return ElementMethods; }
 template<> luaL_reg* GetAttrTable<Element>() { return ElementGetters; }
 template<> luaL_reg* GetAttrTable<Element>() { return ElementGetters; }
 template<> luaL_reg* SetAttrTable<Element>() { return ElementSetters; }
 template<> luaL_reg* SetAttrTable<Element>() { return ElementSetters; }
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 0
Source/Core/Lua/Element.h

@@ -153,10 +153,12 @@ RegType<Element> ElementMethods[];
 luaL_reg ElementGetters[];
 luaL_reg ElementGetters[];
 luaL_reg ElementSetters[];
 luaL_reg ElementSetters[];
 
 
+/*
 template<> const char* GetTClassName<Element>();
 template<> const char* GetTClassName<Element>();
 template<> RegType<Element>* GetMethodTable<Element>();
 template<> RegType<Element>* GetMethodTable<Element>();
 template<> luaL_reg* GetAttrTable<Element>();
 template<> luaL_reg* GetAttrTable<Element>();
 template<> luaL_reg* SetAttrTable<Element>();
 template<> luaL_reg* SetAttrTable<Element>();
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 9
Source/Core/Lua/ElementStyle.cpp

@@ -8,14 +8,6 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 
 
-template<> void LuaType<ElementStyle>::extra_init(lua_State* L, int metatable_index)
-{
-    lua_pushcfunction(L,ElementStyle__index);
-    lua_setfield(L,metatable_index,"__index");
-
-    lua_pushcfunction(L,ElementStyle__newindex);
-    lua_setfield(L,metatable_index,"__newindex");
-}
 
 
 int ElementStyle__index(lua_State* L)
 int ElementStyle__index(lua_State* L)
 {
 {
@@ -118,11 +110,12 @@ luaL_reg ElementStyleSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-
+/*
 template<> const char* GetTClassName<ElementStyle>() { return "ElementStyle"; }
 template<> const char* GetTClassName<ElementStyle>() { return "ElementStyle"; }
 template<> RegType<ElementStyle>* GetMethodTable<ElementStyle>() { return ElementStyleMethods; }
 template<> RegType<ElementStyle>* GetMethodTable<ElementStyle>() { return ElementStyleMethods; }
 template<> luaL_reg* GetAttrTable<ElementStyle>() { return ElementStyleGetters; }
 template<> luaL_reg* GetAttrTable<ElementStyle>() { return ElementStyleGetters; }
 template<> luaL_reg* SetAttrTable<ElementStyle>() { return ElementStyleSetters; }
 template<> luaL_reg* SetAttrTable<ElementStyle>() { return ElementStyleSetters; }
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 3
Source/Core/Lua/ElementStyle.h

@@ -51,10 +51,7 @@
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-
 template<> void LuaType<ElementStyle>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<ElementStyle>::extra_init(lua_State* L, int metatable_index);
-//We are going to specialize the index/newindex to work with strings, otherwise just call the
-//generalized index/newindex
 int ElementStyle__index(lua_State* L);
 int ElementStyle__index(lua_State* L);
 int ElementStyle__newindex(lua_State* L);
 int ElementStyle__newindex(lua_State* L);
 
 
@@ -65,10 +62,12 @@ RegType<ElementStyle> ElementStyleMethods[];
 luaL_reg ElementStyleGetters[];
 luaL_reg ElementStyleGetters[];
 luaL_reg ElementStyleSetters[];
 luaL_reg ElementStyleSetters[];
 
 
+/*
 template<> const char* GetTClassName<ElementStyle>();
 template<> const char* GetTClassName<ElementStyle>();
 template<> RegType<ElementStyle>* GetMethodTable<ElementStyle>();
 template<> RegType<ElementStyle>* GetMethodTable<ElementStyle>();
 template<> luaL_reg* GetAttrTable<ElementStyle>();
 template<> luaL_reg* GetAttrTable<ElementStyle>();
 template<> luaL_reg* SetAttrTable<ElementStyle>();
 template<> luaL_reg* SetAttrTable<ElementStyle>();
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 2
Source/Core/Lua/Event.cpp

@@ -166,12 +166,12 @@ luaL_reg EventSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-
+/*
 template<> const char* GetTClassName<Event>() { return "Event"; }
 template<> const char* GetTClassName<Event>() { return "Event"; }
 template<> RegType<Event>* GetMethodTable<Event>() { return EventMethods; }
 template<> RegType<Event>* GetMethodTable<Event>() { return EventMethods; }
 template<> luaL_reg* GetAttrTable<Event>() { return EventGetters; }
 template<> luaL_reg* GetAttrTable<Event>() { return EventGetters; }
 template<> luaL_reg* SetAttrTable<Event>() { return EventSetters; }
 template<> luaL_reg* SetAttrTable<Event>() { return EventSetters; }
-
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 1
Source/Core/Lua/Event.h

@@ -37,11 +37,12 @@ RegType<Event> EventMethods[];
 luaL_reg EventGetters[];
 luaL_reg EventGetters[];
 luaL_reg EventSetters[];
 luaL_reg EventSetters[];
 
 
+/*
 template<> const char* GetTClassName<Event>();
 template<> const char* GetTClassName<Event>();
 template<> RegType<Event>* GetMethodTable<Event>();
 template<> RegType<Event>* GetMethodTable<Event>();
 template<> luaL_reg* GetAttrTable<Event>();
 template<> luaL_reg* GetAttrTable<Event>();
 template<> luaL_reg* SetAttrTable<Event>();
 template<> luaL_reg* SetAttrTable<Event>();
-
+*/
 }
 }
 }
 }
 }
 }

+ 6 - 0
Source/Core/Lua/Interpreter.cpp

@@ -12,6 +12,7 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 lua_State* Interpreter::_L = NULL;
 lua_State* Interpreter::_L = NULL;
+typedef Rocket::Core::ElementDocument Document;
 
 
 void Interpreter::Startup()
 void Interpreter::Startup()
 {
 {
@@ -161,6 +162,11 @@ void Interpreter::OnShutdown()
     lua_close(_L);
     lua_close(_L);
 }
 }
 
 
+void Interpreter::Initialise()
+{
+    Rocket::Core::RegisterPlugin(new Interpreter());
+}
+
 }
 }
 }
 }
 }
 }

+ 4 - 2
Source/Core/Lua/Interpreter.h

@@ -4,7 +4,7 @@
     This initializes the lua interpreter, and has functions to load the scripts
     This initializes the lua interpreter, and has functions to load the scripts
     A glorified namespace, but I want the lua_State to be unchangeable
     A glorified namespace, but I want the lua_State to be unchangeable
 */
 */
-
+#include "Header.h"
 #include <Rocket/Core/Lua/lua.hpp>
 #include <Rocket/Core/Lua/lua.hpp>
 #include <Rocket/Core/Plugin.h>
 #include <Rocket/Core/Plugin.h>
 
 
@@ -12,7 +12,7 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 
 
-class Interpreter : public Plugin
+class ROCKETLUA_API Interpreter : public Plugin
 {
 {
 public:
 public:
     static void LoadFile(const Rocket::Core::String& file);
     static void LoadFile(const Rocket::Core::String& file);
@@ -24,6 +24,8 @@ public:
     static void EndCall(int res = 0);
     static void EndCall(int res = 0);
 
 
     static lua_State* GetLuaState();
     static lua_State* GetLuaState();
+
+    static void Initialise();
     
     
     //From Plugin
     //From Plugin
     virtual int GetEventClasses();
     virtual int GetEventClasses();

+ 2 - 35
Source/Core/Lua/Log.cpp

@@ -7,40 +7,6 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 
 
-template<> void LuaType<Log>::extra_init(lua_State* L, int metatable_index)
-{
-    //due to they way that LuaType::Register is made, we know that the method table is at the index
-    //directly below the metatable
-    int method_index = metatable_index - 1;
-
-    lua_pushcfunction(L,Log__call);
-    lua_setfield(L,metatable_index, "__call");
-
-    //construct the "logtype" table, so that we can use the Rocket::Core::Log::Type enum like Log.logtype.always in Lua for Log::LT_ALWAYS
-    lua_newtable(L);
-    int logtype = lua_gettop(L);
-    lua_pushvalue(L,-1); //copy of the new table, so that the logtype index will stay valid
-    lua_setfield(L,method_index,"logtype");
-
-    lua_pushinteger(L,(int)Log::LT_ALWAYS);
-    lua_setfield(L,logtype,"always");
-
-    lua_pushinteger(L,(int)Log::LT_ERROR);
-    lua_setfield(L,logtype,"error");
-
-    lua_pushinteger(L,(int)Log::LT_WARNING);
-    lua_setfield(L,logtype,"warning");
-
-    lua_pushinteger(L,(int)Log::LT_INFO);
-    lua_setfield(L,logtype,"info");
-
-    lua_pushinteger(L,(int)Log::LT_DEBUG);
-    lua_setfield(L,logtype,"debug");
-
-    lua_pop(L,1); //pop the logtype table
-
-    return;
-}
 
 
 
 
 int Log__call(lua_State* L)
 int Log__call(lua_State* L)
@@ -68,11 +34,12 @@ luaL_reg LogSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
+/*
 template<> const char* GetTClassName<Log>() { return "Log"; }
 template<> const char* GetTClassName<Log>() { return "Log"; }
 template<> RegType<Log>* GetMethodTable<Log>() { return LogMethods; }
 template<> RegType<Log>* GetMethodTable<Log>() { return LogMethods; }
 template<> luaL_reg* GetAttrTable<Log>() { return LogGetters; }
 template<> luaL_reg* GetAttrTable<Log>() { return LogGetters; }
 template<> luaL_reg* SetAttrTable<Log>() { return LogSetters; }
 template<> luaL_reg* SetAttrTable<Log>() { return LogSetters; }
-
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 0
Source/Core/Lua/Log.h

@@ -28,10 +28,12 @@ RegType<Log> LogMethods[];
 luaL_reg LogGetters[];
 luaL_reg LogGetters[];
 luaL_reg LogSetters[];
 luaL_reg LogSetters[];
 
 
+/*
 template<> const char* GetTClassName<Log>();
 template<> const char* GetTClassName<Log>();
 template<> RegType<Log>* GetMethodTable<Log>();
 template<> RegType<Log>* GetMethodTable<Log>();
 template<> luaL_reg* GetAttrTable<Log>();
 template<> luaL_reg* GetAttrTable<Log>();
 template<> luaL_reg* SetAttrTable<Log>();
 template<> luaL_reg* SetAttrTable<Log>();
+*/
 }
 }
 }
 }
 }
 }

+ 5 - 10
Include/Rocket/Core/Lua/LuaType.inl → Source/Core/Lua/LuaType.cpp

@@ -1,17 +1,10 @@
 #include "precompiled.h"
 #include "precompiled.h"
-#include "LuaType.h"
-#include "Rocket.h"
-#include <Rocket/Core/Event.h>
-#include <Rocket/Core/Element.h>
-#include <Rocket/Core/ElementDocument.h>
-#include <Rocket/Core/ElementStyle.h>
-#include <Rocket/Core/Context.h>
-
+#include <Rocket/Controls/Controls.h>
+#include <Rocket/Core/Core.h>
 
 
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-typedef Rocket::Core::ElementDocument Document;
 
 
 template<typename T>
 template<typename T>
 void LuaType<T>::Register(lua_State* L)
 void LuaType<T>::Register(lua_State* L)
@@ -286,4 +279,6 @@ void LuaType<T>::_regfunctions(lua_State* L, int meta, int methods)
 
 
 }
 }
 }
 }
-}
+}
+
+#include "LuaTypeTemplateSpec.inl"

+ 21 - 8
Source/Core/Lua/LuaType.h

@@ -32,6 +32,20 @@ namespace Lua {
 #define CHECK_BOOL(L,narg) (lua_toboolean((L),(narg)) > 0 ? true : false )
 #define CHECK_BOOL(L,narg) (lua_toboolean((L),(narg)) > 0 ? true : false )
 #define LUACHECKOBJ(obj) if(obj == NULL) { lua_pushnil(L); return 1; }
 #define LUACHECKOBJ(obj) if(obj == NULL) { lua_pushnil(L); return 1; }
 
 
+//put this in the type.cpp file
+#define LUATYPEDEFINE(type) \
+    template<> const char* GetTClassName<type>() { return #type; } \
+    template<> RegType<type>* GetMethodTable<type>() { return type##Methods; } \
+    template<> luaL_reg* GetAttrTable<type>() { return type##Getters; } \
+    template<> luaL_reg* SetAttrTable<type>() { return type##Setters; } \
+
+//put this in the type.h file
+#define LUATYPEDECLARE(type) \
+    template<> const char* GetTClassName<type>(); \
+    template<> RegType<type>* GetMethodTable<type>(); \
+    template<> luaL_reg* GetAttrTable<type>(); \
+    template<> luaL_reg* SetAttrTable<type>(); \
+
 
 
 //replacement for luaL_reg that uses a different function pointer signature, but similar syntax
 //replacement for luaL_reg that uses a different function pointer signature, but similar syntax
 template<typename T>
 template<typename T>
@@ -42,13 +56,13 @@ struct ROCKETLUA_API RegType
 };
 };
 
 
 //this is for all of the methods available from Lua that call to the C functions
 //this is for all of the methods available from Lua that call to the C functions
-template<typename T> ROCKETLUA_API RegType<T>* GetMethodTable();
+template<typename T> ROCKETLUA_API inline RegType<T>* GetMethodTable();
 //this is for all of the function that 'get' an attribute/property
 //this is for all of the function that 'get' an attribute/property
-template<typename T> ROCKETLUA_API luaL_reg* GetAttrTable();
+template<typename T> ROCKETLUA_API inline luaL_reg* GetAttrTable();
 //this is for all of the functions that 'set' an attribute/property
 //this is for all of the functions that 'set' an attribute/property
-template<typename T> ROCKETLUA_API luaL_reg* SetAttrTable();
+template<typename T> ROCKETLUA_API inline luaL_reg* SetAttrTable();
 //String representation of the class
 //String representation of the class
-template<typename T> ROCKETLUA_API const char* GetTClassName();
+template<typename T> ROCKETLUA_API inline const char* GetTClassName();
 
 
 template<typename T>
 template<typename T>
 class ROCKETLUA_API LuaType
 class ROCKETLUA_API LuaType
@@ -80,17 +94,16 @@ public:
     //to call _regfunctions<superclass>, where method is metatable_index - 1. Anything
     //to call _regfunctions<superclass>, where method is metatable_index - 1. Anything
     //that has the same name in the subclass will be overwrite whatever had the 
     //that has the same name in the subclass will be overwrite whatever had the 
     //same name in the superclass.
     //same name in the superclass.
-    static inline void extra_init(lua_State* L, int metatable_index);
+    static  void extra_init(lua_State* L, int metatable_index);
     //Registers methods,getters,and setters to the type
     //Registers methods,getters,and setters to the type
-    static inline void _regfunctions(lua_State* L, int meta, int method);
+    static void _regfunctions(lua_State* L, int meta, int method);
 private:
 private:
     LuaType(); //hide constructor
     LuaType(); //hide constructor
 
 
 };
 };
-
 }
 }
 }
 }
 }
 }
 
 
-#include "LuaType.inl"
+//#include "LuaType.inl"
 #endif
 #endif

+ 0 - 289
Source/Core/Lua/LuaType.inl

@@ -1,289 +0,0 @@
-#include "precompiled.h"
-#include "LuaType.h"
-#include "Rocket.h"
-#include <Rocket/Core/Event.h>
-#include <Rocket/Core/Element.h>
-#include <Rocket/Core/ElementDocument.h>
-#include <Rocket/Core/ElementStyle.h>
-#include <Rocket/Core/Context.h>
-
-
-namespace Rocket {
-namespace Core {
-namespace Lua {
-typedef Rocket::Core::ElementDocument Document;
-
-template<typename T>
-void LuaType<T>::Register(lua_State* L)
-{
-    //for annotations, starting at 1, but it is a relative value, not always 1
-    lua_newtable(L); //[1] = table
-    int methods = lua_gettop(L); //methods = 1
-
-    luaL_newmetatable(L, GetTClassName<T>()); //[2] = metatable named <ClassName>, referred in here by ClassMT
-    int metatable = lua_gettop(L); //metatable = 2
-
-    luaL_newmetatable(L, "DO NOT TRASH"); //[3] = metatable named "DO NOT TRASH"
-    lua_pop(L,1); //remove the above metatable -> [-1 = 2]
-
-    //store method table in globals so that scripts can add functions written in Lua
-    lua_pushvalue(L, methods); //[methods = 1] -> [3] = copy (reference) of methods table
-    lua_setglobal(L, GetTClassName<T>()); // -> <ClassName> = [3 = 1], pop top [3]
-
-    //hide metatable from Lua getmetatable()
-    lua_pushvalue(L, methods); //[methods = 1] -> [3] = copy of methods table, including modifications above
-    lua_setfield(L, metatable, "__metatable"); //[metatable = 2] -> t[k] = v; t = [2 = ClassMT], k = "__metatable", v = [3 = 1]; pop [3]
-    
-    lua_pushcfunction(L, index); //index = cfunction -> [3] = cfunction
-    lua_setfield(L, metatable, "__index"); //[metatable = 2] -> t[k] = v; t = [2], k = "__index", v = cfunc; pop [3]
-
-    lua_pushcfunction(L, newindex);
-    lua_setfield(L, metatable, "__newindex");
-
-    lua_pushcfunction(L, gc_T);
-    lua_setfield(L, metatable, "__gc");
-
-    lua_pushcfunction(L, tostring_T);
-    lua_setfield(L, metatable, "__tostring");
-
-    extra_init(L,metatable); //imlemented by individual types
-
-    lua_newtable(L); //for method table -> [3] = this table
-    lua_setmetatable(L, methods); //[methods = 1] -> metatable for [1] is [3]; [3] is popped off, top = [2]
-
-    _regfunctions(L,metatable,methods);
-
-    lua_pop(L, 2); //remove the two items from the stack, [1 = methods] and [2 = metatable]
-}
-
-
-template<typename T>
-int LuaType<T>::push(lua_State *L, T* obj, bool gc)
-{
-    //for annotations, starting at index 1, but it is a relative number, not always 1
-    if (!obj) { lua_pushnil(L); return lua_gettop(L); }
-    luaL_getmetatable(L, GetTClassName<T>());  // lookup metatable in Lua registry ->[1] = metatable of <ClassName>
-    if (lua_isnil(L, -1)) luaL_error(L, "%s missing metatable", GetTClassName<T>());
-    int mt = lua_gettop(L); //mt = 1
-    T** ptrHold = (T**)lua_newuserdata(L,sizeof(T**)); //->[2] = empty userdata
-    int ud = lua_gettop(L); //ud = 2
-    if(ptrHold != NULL)
-    {
-        *ptrHold = obj; 
-        lua_pushvalue(L, mt); // ->[3] = copy of [1]
-        lua_setmetatable(L, -2); //[-2 = 2] -> [2]'s metatable = [3]; pop [3]
-        char name[32];
-        tostring(name,obj);
-        lua_getfield(L,LUA_REGISTRYINDEX,"DO NOT TRASH"); //->[3] = value returned from function
-        if(lua_isnil(L,-1) ) //if [3] hasn't been created yet, then create it
-        {
-            luaL_newmetatable(L,"DO NOT TRASH"); //[4] = the new metatable
-            lua_pop(L,1); //pop [4]
-        }
-        lua_getfield(L,LUA_REGISTRYINDEX,"DO NOT TRASH"); //->[3] = value returned from function
-        if(gc == false) //if we shouldn't garbage collect it, then put the name in to [3]
-        {
-            lua_pushboolean(L,1);// ->[4] = true
-            lua_setfield(L,-2,name); //represents t[k] = v, [-2 = 3] = t -> v = [4], k = <ClassName>; pop [4]
-        }
-        lua_pop(L,1); // -> pop [3]
-    }
-    lua_settop(L,ud); //[ud = 2] -> remove everything that is above 2, top = [2]
-    lua_replace(L, mt); //[mt = 1] -> move [2] to pos [1], and pop previous [1]
-    lua_settop(L, mt); //remove everything above [1]
-    return mt;  // index of userdata containing pointer to T object
-}
-
-
-template<typename T>
-T* LuaType<T>::check(lua_State* L, int narg)
-{
-    T** ptrHold = static_cast<T**>(lua_touserdata(L,narg));
-    if(ptrHold == NULL)
-        return NULL;
-    return (*ptrHold);
-}
-
-
-//private members
-
-template<typename T>
-int LuaType<T>::thunk(lua_State* L)
-{
-    // stack has userdata, followed by method args
-    T *obj = check(L, 1);  // get 'self', or if you prefer, 'this'
-    lua_remove(L, 1);  // remove self so member function args start at index 1
-    // get member function from upvalue
-    RegType *l = static_cast<RegType*>(lua_touserdata(L, lua_upvalueindex(1)));
-    // call member function
-    return l->func(L,obj);
-}
-
-
-template<typename T>
-void LuaType<T>::tostring(char* buff, void* obj)
-{
-    sprintf(buff,"%p",obj);
-}
-
-
-template<typename T>
-int LuaType<T>::gc_T(lua_State* L)
-{
-    T * obj = check(L,1); //[1] = this userdata
-    if(obj == NULL)
-        return 0;
-    lua_getfield(L,LUA_REGISTRYINDEX,"DO NOT TRASH"); //->[2] = return value from this
-    if(lua_istable(L,-1) ) //[-1 = 2], if it is a table
-    {
-        char name[32];
-        tostring(name,obj);
-        lua_getfield(L,-1, std::string(name).c_str()); //[-1 = 2] -> [3] = the value returned from if <ClassName> exists in the table to not gc
-        if(lua_isnil(L,-1) ) //[-1 = 3] if it doesn't exist, then we are free to garbage collect c++ side
-        {
-            delete obj;
-            obj = NULL;
-        }
-    }
-    lua_pop(L,3); //balance function
-    return 0;
-}
-
-
-template<typename T>
-int LuaType<T>::tostring_T(lua_State* L)
-{
-    char buff[32];
-    T** ptrHold = (T**)lua_touserdata(L,1);
-    T *obj = *ptrHold;
-    sprintf(buff, "%p", obj);
-    lua_pushfstring(L, "%s (%s)", GetTClassName<T>(), buff);
-    return 1;
-}
-
-
-
-template<typename T>
-int LuaType<T>::index(lua_State* L)
-{
-    /*the table obj and the missing key are currently on the stack(index 1 & 2) as defined by the Lua language*/
-    lua_getglobal(L,GetTClassName<T>()); //stack pos [3] (fairly important, just refered to as [3])
-    // string form of the key.
-	const char* key = luaL_checkstring(L,2);
-    if(lua_istable(L,-1) )  //[-1 = 3]
-    {
-        lua_pushvalue(L,2); //[2] = key, [4] = copy of key
-        lua_rawget(L,-2); //[-2 = 3] -> pop top and push the return value to top [4]
-        //If the key were looking for is not in the table, retrieve its' metatables' index value.
-        if(lua_isnil(L,-1)) //[-1 = 4] is value from rawget above
-        {
-            //try __getters
-            lua_pop(L,1); //remove top item (nil) from the stack
-            lua_pushstring(L, "__getters");
-            lua_rawget(L,-2); //[-2 = 3], <ClassName>._getters -> result to [4]
-            lua_pushvalue(L,2); //[2 = key] -> copy to [5]
-            lua_rawget(L,-2); //[-2 = __getters] -> __getters[key], result to [5]
-            if(lua_type(L,-1) == LUA_TFUNCTION) //[-1 = 5]
-            {
-                lua_pushvalue(L,1); //push the userdata to the stack [6]
-                lua_pcall(L,1,1,0); //remove one, result is at [6]
-            }
-            else
-            {
-                lua_settop(L,4); //forget everything we did above
-                lua_getmetatable(L,-2); //[-2 = 3] -> metatable from <ClassName> to top [5]
-                if(lua_istable(L,-1) ) //[-1 = 5] = the result of the above
-                {
-                    lua_getfield(L,-1,"__index"); //[-1 = 5] = check the __index metamethod for the metatable-> push result to [6]
-                    if(lua_isfunction(L,-1) ) //[-1 = 6] = __index metamethod
-                    {
-                        lua_pushvalue(L,1); //[1] = object -> [7] = object
-                        lua_pushvalue(L,2); //[2] = key -> [8] = key
-                        lua_pcall(L,2,1,0); //call function at top of stack (__index) -> pop top 2 as args; [7] = return value
-                    }
-                    else if(lua_istable(L,-1) )
-                        lua_getfield(L,-1,key); //shorthand version of above -> [7] = return value
-                    else
-                        lua_pushnil(L); //[7] = nil
-                }
-                else
-                    lua_pushnil(L); //[6] = nil
-            }
-        }
-        else if(lua_istable(L,-1) )//[-1 = 4] is value from rawget [3]
-        {
-            lua_pushvalue(L,2); //[2] = key, [5] = key
-            lua_rawget(L,-2); //[-2 = 3] = table of <ClassName> -> pop top and push the return value to top [5]
-        }
-    }
-    else
-        lua_pushnil(L); //[4] = nil
-
-    lua_insert(L,1); //top element to position 1 -> [1] = top element as calculated in the earlier rest of the function
-    lua_settop(L,1); // -> [1 = -1], removes the other elements
-    return 1;
-}
-
-
-
-template<typename T>
-int LuaType<T>::newindex(lua_State* L)
-{
-    //[1] = obj, [2] = key, [3] = value
-    //look for it in __setters
-    lua_getglobal(L,GetTClassName<T>()); //[4] = this table
-    lua_pushstring(L,"__setters"); //[5]
-    lua_rawget(L,-2); //[-2 = 4] -> <ClassName>.__setters to [5]
-    lua_pushvalue(L,2); //[2 = key] -> [6] = copy of key
-    lua_rawget(L,-2); //[-2 = __setters] -> __setters[key] to [6]
-    if(lua_type(L,-1) == LUA_TFUNCTION)
-    {
-        lua_pushvalue(L,1); //userdata at [7]
-        lua_pushvalue(L,3); //[8] = copy of [3]
-        lua_pcall(L,2,0,0); //call function, pop 2 off push 0 on
-    }
-    else
-        lua_pop(L,1); //not a setter function.
-    lua_pop(L,2); //pop __setters and the <Classname> table
-    return 0;
-}
-
-template<typename T>
-void LuaType<T>::extra_init(lua_State* L, int metatable_index)
-{
-    //empty, because it should be implemented by other types
-    return;
-}
-
-template<typename T>
-void LuaType<T>::_regfunctions(lua_State* L, int meta, int methods)
-{
-    //fill method table with methods.
-    for(RegType* m = (RegType*)GetMethodTable<T>(); m->name; m++)
-    {
-        lua_pushstring(L, m->name); // ->[3] = name of function Lua side
-        lua_pushlightuserdata(L, (void*)m); // ->[4] = pointer to the object containing the name and the function pointer as light userdata
-        lua_pushcclosure(L, thunk, 1); //thunk = function pointer -> pop 1 item from stack, [4] = closure
-        lua_settable(L, methods); // represents t[k] = v, t = [methods = 1] -> pop [4 = closure] to be v, pop [3 = name] to be k
-    }
-
-    lua_newtable(L); // -> table [3]
-    for(luaL_reg* m = (luaL_reg*)GetAttrTable<T>(); m->name; m++)
-    {
-        lua_pushcfunction(L,m->func); // -> [4] is this function
-        lua_setfield(L,-2,m->name); //[-2 = 3] -> table.name = function
-    }
-    lua_setfield(L,methods, "__getters"); //[methods = 1], methods.__getters = table, pop table
-
-    lua_newtable(L); // -> table [3]
-    for(luaL_reg* m = (luaL_reg*)SetAttrTable<T>(); m->name; m++)
-    {
-        lua_pushcfunction(L,m->func); // -> [4] is this function
-        lua_setfield(L,-2,m->name); //[-2 = 3] -> table.name = function
-    }
-    lua_setfield(L,methods, "__setters"); //[methods = 1], methods.__setters = table, pop table
-}
-
-}
-}
-}

+ 309 - 0
Source/Core/Lua/LuaTypeTemplateSpec.inl

@@ -0,0 +1,309 @@
+/*
+    Because all of the template specializations have to be compiled in the same translation unit, they have to 
+    exist in this file. It is included by LuaType.inl
+*/
+#include "precompiled.h"
+#include <Rocket/Core/Core.h>
+#include <Rocket/Controls/Controls.h>
+#include "LuaType.h"
+#include "Colourb.h"
+#include "Colourf.h"
+#include "Vector2f.h"
+#include "Vector2i.h"
+#include "ElementStyle.h"
+#include "Log.h"
+#include "Rocket.h"
+#include "Element.h"
+#include "Document.h"
+#include "Event.h"
+#include "Context.h"
+#include "ElementForm.h"
+#include "ElementFormControl.h"
+#include "ElementFormControlDataSelect.h"
+#include "ElementFormControlSelect.h"
+#include "ElementFormControlInput.h"
+#include "ElementFormControlTextArea.h"
+#include "ElementDataGrid.h"
+#include "ElementDataGridRow.h"
+#include "ElementTabSet.h"
+
+
+
+namespace Rocket {
+namespace Core {
+namespace Lua {
+
+
+LUATYPEDEFINE(Colourb)
+LUATYPEDEFINE(Colourf)
+LUATYPEDEFINE(Vector2f)
+LUATYPEDEFINE(Vector2i)
+LUATYPEDEFINE(Log)
+LUATYPEDEFINE(rocket)
+LUATYPEDEFINE(Element)
+LUATYPEDEFINE(Document)
+LUATYPEDEFINE(ElementStyle)
+LUATYPEDEFINE(Event)
+LUATYPEDEFINE(Context)
+LUATYPEDEFINE(ElementForm)
+LUATYPEDEFINE(ElementFormControl)
+LUATYPEDEFINE(ElementFormControlDataSelect)
+LUATYPEDEFINE(ElementFormControlSelect)
+LUATYPEDEFINE(ElementFormControlInput)
+LUATYPEDEFINE(ElementFormControlTextArea)
+LUATYPEDEFINE(ElementDataGrid)
+LUATYPEDEFINE(ElementDataGridRow)
+LUATYPEDEFINE(ElementTabSet)
+
+
+template class LuaType<Colourb>;
+template class LuaType<Colourf>;
+template class LuaType<Vector2f>;
+template class LuaType<Vector2i>;
+template class LuaType<Log>;
+template class LuaType<rocket>;
+template class LuaType<Element>;
+template class LuaType<Document>;
+template class LuaType<ElementStyle>;
+template class LuaType<Event>;
+template class LuaType<Context>;
+template class LuaType<ElementForm>;
+template class LuaType<ElementFormControl>;
+template class LuaType<ElementFormControlDataSelect>;
+template class LuaType<ElementFormControlSelect>;
+template class LuaType<ElementFormControlInput>;
+template class LuaType<ElementFormControlTextArea>;
+template class LuaType<ElementDataGrid>;
+template class LuaType<ElementDataGridRow>;
+template class LuaType<ElementTabSet>;
+
+
+
+template<> void LuaType<rocket>::extra_init(lua_State* L, int metatable_index)
+{
+    //because of the way LuaType::Register is done, we know that the methods table is directly
+    //before the metatable 
+    int method_index = metatable_index - 1;
+
+    lua_pushcfunction(L,rocketCreateContext);
+    lua_setfield(L,method_index,"CreateContext");
+
+    lua_pushcfunction(L,rocketLoadFontFace);
+    lua_setfield(L,method_index,"LoadFontFace");
+
+    lua_pushcfunction(L,rocketRegisterTag);
+    lua_setfield(L,method_index,"RegisterTag");
+
+    rocketEnumkey_identifier(L);
+    lua_setfield(L,method_index,"key_identifier");
+
+    lua_pushcfunction(L,rocketGetAttrcontexts);
+    lua_setfield(L,method_index,"contexts");
+
+    return;
+}
+
+/*
+    
+        Basic Types
+
+*/
+
+template<> void LuaType<Colourb>::extra_init(lua_State* L, int metatable_index)
+{
+    lua_pushcfunction(L,Colourb__call);
+    lua_setfield(L,metatable_index,"__call");
+
+    lua_pushcfunction(L,Colourb__eq);
+    lua_setfield(L,metatable_index,"__eq");
+
+    lua_pushcfunction(L,Colourb__add);
+    lua_setfield(L,metatable_index,"__add");
+
+    lua_pushcfunction(L,Colourb__mul);
+    lua_setfield(L,metatable_index,"__mul");
+
+    return;
+}
+
+
+template<> void LuaType<Colourf>::extra_init(lua_State* L, int metatable_index)
+{
+    lua_pushcfunction(L,Colourf__call);
+    lua_setfield(L,metatable_index,"__call");
+
+    lua_pushcfunction(L,Colourf__eq);
+    lua_setfield(L,metatable_index,"__eq");
+
+    return;
+}
+
+
+template<> 
+void LuaType<Vector2f>::extra_init(lua_State* L, int metatable_index)
+{
+    lua_pushcfunction(L,Vector2f__call);
+    lua_setfield(L,metatable_index,"__call");
+
+    lua_pushcfunction(L,Vector2f__mul);
+    lua_setfield(L,metatable_index,"__mul");
+
+    lua_pushcfunction(L,Vector2f__div);
+    lua_setfield(L,metatable_index,"__div");
+
+    lua_pushcfunction(L,Vector2f__add);
+    lua_setfield(L,metatable_index,"__add");
+
+    lua_pushcfunction(L,Vector2f__sub);
+    lua_setfield(L,metatable_index,"__sub");
+
+    lua_pushcfunction(L,Vector2f__eq);
+    lua_setfield(L,metatable_index,"__eq");
+
+    //stack is in the same state as it was before it entered this function
+    return;
+}
+
+template<> 
+void LuaType<Vector2i>::extra_init(lua_State* L, int metatable_index)
+{
+    lua_pushcfunction(L,Vector2i__call);
+    lua_setfield(L,metatable_index,"__call");
+
+    lua_pushcfunction(L,Vector2i__mul);
+    lua_setfield(L,metatable_index,"__mul");
+
+    lua_pushcfunction(L,Vector2i__div);
+    lua_setfield(L,metatable_index,"__div");
+
+    lua_pushcfunction(L,Vector2i__add);
+    lua_setfield(L,metatable_index,"__add");
+
+    lua_pushcfunction(L,Vector2i__sub);
+    lua_setfield(L,metatable_index,"__sub");
+
+    lua_pushcfunction(L,Vector2i__eq);
+    lua_setfield(L,metatable_index,"__eq");
+
+    //stack is in the same state as it was before it entered this function
+    return;
+}
+
+
+/*
+
+    Elements
+
+*/
+
+
+template<> void LuaType<Document>::extra_init(lua_State* L, int metatable_index)
+{
+    //we will inherit from Element
+    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index - 1);
+}
+
+
+template<> void LuaType<ElementStyle>::extra_init(lua_State* L, int metatable_index)
+{
+    lua_pushcfunction(L,ElementStyle__index);
+    lua_setfield(L,metatable_index,"__index");
+
+    lua_pushcfunction(L,ElementStyle__newindex);
+    lua_setfield(L,metatable_index,"__newindex");
+}
+
+
+template<> void LuaType<ElementForm>::extra_init(lua_State* L, int metatable_index)
+{
+    //inherit from Element
+    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
+}
+
+template<> void LuaType<ElementFormControl>::extra_init(lua_State* L, int metatable_index)
+{
+    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
+}
+
+template<> void LuaType<ElementFormControlDataSelect>::extra_init(lua_State* L, int metatable_index)
+{
+    //do whatever ElementFormControlSelect did as far as inheritance
+    LuaType<ElementFormControlSelect>::extra_init(L,metatable_index);
+    //then inherit from ElementFromControlSelect
+    LuaType<ElementFormControlSelect>::_regfunctions(L,metatable_index,metatable_index-1);
+}
+
+template<> void LuaType<ElementFormControlInput>::extra_init(lua_State* L, int metatable_index)
+{
+    LuaType<ElementFormControl>::extra_init(L,metatable_index);
+    LuaType<ElementFormControl>::_regfunctions(L,metatable_index,metatable_index-1);
+}
+
+template<> void LuaType<ElementFormControlSelect>::extra_init(lua_State* L, int metatable_index)
+{
+    //init whatever elementformcontrol did extra, like inheritance
+    LuaType<ElementFormControl>::extra_init(L,metatable_index);
+    //then inherit from elementformcontrol
+    LuaType<ElementFormControl>::_regfunctions(L,metatable_index,metatable_index-1);
+}
+
+template<> void LuaType<ElementFormControlTextArea>::extra_init(lua_State* L, int metatable_index)
+{
+    LuaType<ElementFormControl>::extra_init(L,metatable_index);
+    LuaType<ElementFormControl>::_regfunctions(L,metatable_index,metatable_index-1);
+}
+
+template<> void LuaType<ElementDataGrid>::extra_init(lua_State* L, int metatable_index)
+{
+    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
+}
+
+template<> void LuaType<ElementDataGridRow>::extra_init(lua_State* L, int metatable_index)
+{
+    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
+}
+
+template<> void LuaType<ElementTabSet>::extra_init(lua_State* L, int metatable_index)
+{
+    LuaType<Element>::_regfunctions(L,metatable_index,metatable_index-1);
+}
+
+
+template<> void LuaType<Log>::extra_init(lua_State* L, int metatable_index)
+{
+    //due to they way that LuaType::Register is made, we know that the method table is at the index
+    //directly below the metatable
+    int method_index = metatable_index - 1;
+
+    lua_pushcfunction(L,Log__call);
+    lua_setfield(L,metatable_index, "__call");
+
+    //construct the "logtype" table, so that we can use the Rocket::Core::Log::Type enum like Log.logtype.always in Lua for Log::LT_ALWAYS
+    lua_newtable(L);
+    int logtype = lua_gettop(L);
+    lua_pushvalue(L,-1); //copy of the new table, so that the logtype index will stay valid
+    lua_setfield(L,method_index,"logtype");
+
+    lua_pushinteger(L,(int)Log::LT_ALWAYS);
+    lua_setfield(L,logtype,"always");
+
+    lua_pushinteger(L,(int)Log::LT_ERROR);
+    lua_setfield(L,logtype,"error");
+
+    lua_pushinteger(L,(int)Log::LT_WARNING);
+    lua_setfield(L,logtype,"warning");
+
+    lua_pushinteger(L,(int)Log::LT_INFO);
+    lua_setfield(L,logtype,"info");
+
+    lua_pushinteger(L,(int)Log::LT_DEBUG);
+    lua_setfield(L,logtype,"debug");
+
+    lua_pop(L,1); //pop the logtype table
+
+    return;
+}
+
+}
+}
+}

+ 2 - 22
Source/Core/Lua/Rocket.cpp

@@ -7,26 +7,6 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 
 
-template<> void LuaType<rocket>::extra_init(lua_State* L, int metatable_index)
-{
-    //because of the way LuaType::Register is done, we know that the methods table is directly
-    //before the metatable 
-    int method_index = metatable_index - 1;
-
-    lua_pushcfunction(L,rocketCreateContext);
-    lua_setfield(L,method_index,"CreateContext");
-
-    lua_pushcfunction(L,rocketLoadFontFace);
-    lua_setfield(L,method_index,"LoadFontFace");
-
-    lua_pushcfunction(L,rocketRegisterTag);
-    lua_setfield(L,method_index,"RegisterTag");
-
-    rocketEnumkey_identifier(L);
-
-    return;
-}
-
 int rocketCreateContext(lua_State* L)
 int rocketCreateContext(lua_State* L)
 {
 {
     const char* name = luaL_checkstring(L,1);
     const char* name = luaL_checkstring(L,1);
@@ -275,12 +255,12 @@ luaL_reg rocketSetters[] =
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-
+/*
 template<> const char* GetTClassName<rocket>() { return "rocket"; }
 template<> const char* GetTClassName<rocket>() { return "rocket"; }
 template<> RegType<rocket>* GetMethodTable<rocket>() { return rocketMethods; }
 template<> RegType<rocket>* GetMethodTable<rocket>() { return rocketMethods; }
 template<> luaL_reg* GetAttrTable<rocket>() { return rocketGetters; }
 template<> luaL_reg* GetAttrTable<rocket>() { return rocketGetters; }
 template<> luaL_reg* SetAttrTable<rocket>() { return rocketSetters; }
 template<> luaL_reg* SetAttrTable<rocket>() { return rocketSetters; }
-
+*/
 }
 }
 }
 }
 }
 }

+ 2 - 1
Source/Core/Lua/Rocket.h

@@ -37,11 +37,12 @@ RegType<rocket> rocketMethods[];
 luaL_reg rocketGetters[];
 luaL_reg rocketGetters[];
 luaL_reg rocketSetters[];
 luaL_reg rocketSetters[];
 
 
+/*
 template<> const char* GetTClassName<rocket>();
 template<> const char* GetTClassName<rocket>();
 template<> RegType<rocket>* GetMethodTable<rocket>();
 template<> RegType<rocket>* GetMethodTable<rocket>();
 template<> luaL_reg* GetAttrTable<rocket>();
 template<> luaL_reg* GetAttrTable<rocket>();
 template<> luaL_reg* SetAttrTable<rocket>();
 template<> luaL_reg* SetAttrTable<rocket>();
-
+*/
 }
 }
 }
 }
 }
 }

+ 0 - 27
Source/Core/Lua/Vector2f.cpp

@@ -6,30 +6,7 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 
 
-template<> 
-void LuaType<Vector2f>::extra_init(lua_State* L, int metatable_index)
-{
-    lua_pushcfunction(L,Vector2f__call);
-    lua_setfield(L,metatable_index,"__call");
-
-    lua_pushcfunction(L,Vector2f__mul);
-    lua_setfield(L,metatable_index,"__mul");
-
-    lua_pushcfunction(L,Vector2f__div);
-    lua_setfield(L,metatable_index,"__div");
-
-    lua_pushcfunction(L,Vector2f__add);
-    lua_setfield(L,metatable_index,"__add");
 
 
-    lua_pushcfunction(L,Vector2f__sub);
-    lua_setfield(L,metatable_index,"__sub");
-
-    lua_pushcfunction(L,Vector2f__eq);
-    lua_setfield(L,metatable_index,"__eq");
-
-    //stack is in the same state as it was before it entered this function
-    return;
-}
 
 
 int Vector2f__call(lua_State* L)
 int Vector2f__call(lua_State* L)
 {
 {
@@ -197,10 +174,6 @@ luaL_reg Vector2fSetters[]=
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-template<> const char* GetTClassName<Vector2f>() { return "Vector2f"; }
-template<> RegType<Vector2f>* GetMethodTable<Vector2f>() { return Vector2fMethods; }
-template<> luaL_reg* GetAttrTable<Vector2f>() { return Vector2fGetters; }
-template<> luaL_reg* SetAttrTable<Vector2f>() { return Vector2fSetters; }
 }
 }
 }
 }
 }
 }

+ 8 - 6
Source/Core/Lua/Vector2f.h

@@ -30,10 +30,10 @@
 #include "LuaType.h"
 #include "LuaType.h"
 #include <Rocket/Core/Types.h>
 #include <Rocket/Core/Types.h>
 
 
+using Rocket::Core::Vector2f;
 namespace Rocket {
 namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
-
 template<> void LuaType<Vector2f>::extra_init(lua_State* L, int metatable_index);
 template<> void LuaType<Vector2f>::extra_init(lua_State* L, int metatable_index);
 int Vector2f__call(lua_State* L);
 int Vector2f__call(lua_State* L);
 int Vector2f__mul(lua_State* L);
 int Vector2f__mul(lua_State* L);
@@ -58,10 +58,12 @@ RegType<Vector2f> Vector2fMethods[];
 luaL_reg Vector2fGetters[];
 luaL_reg Vector2fGetters[];
 luaL_reg Vector2fSetters[];
 luaL_reg Vector2fSetters[];
 
 
-template<> const char* GetTClassName<Vector2f>();
-template<> RegType<Vector2f>* GetMethodTable<Vector2f>();
-template<> luaL_reg* GetAttrTable<Vector2f>();
-template<> luaL_reg* SetAttrTable<Vector2f>();
+/*
+template<> const char* GetTClassName<Vector2f>() { return "Vector2f"; }
+template<> RegType<Vector2f>* GetMethodTable<Vector2f>() { return Vector2fMethods; }
+template<> luaL_reg* GetAttrTable<Vector2f>() { return Vector2fGetters; }
+template<> luaL_reg* SetAttrTable<Vector2f>() { return Vector2fSetters; }
+*/
+}
 }
 }
 }
 }
-}

+ 0 - 28
Source/Core/Lua/Vector2i.cpp

@@ -6,30 +6,6 @@ namespace Rocket {
 namespace Core {
 namespace Core {
 namespace Lua {
 namespace Lua {
 
 
-template<> 
-void LuaType<Vector2i>::extra_init(lua_State* L, int metatable_index)
-{
-    lua_pushcfunction(L,Vector2i__call);
-    lua_setfield(L,metatable_index,"__call");
-
-    lua_pushcfunction(L,Vector2i__mul);
-    lua_setfield(L,metatable_index,"__mul");
-
-    lua_pushcfunction(L,Vector2i__div);
-    lua_setfield(L,metatable_index,"__div");
-
-    lua_pushcfunction(L,Vector2i__add);
-    lua_setfield(L,metatable_index,"__add");
-
-    lua_pushcfunction(L,Vector2i__sub);
-    lua_setfield(L,metatable_index,"__sub");
-
-    lua_pushcfunction(L,Vector2i__eq);
-    lua_setfield(L,metatable_index,"__eq");
-
-    //stack is in the same state as it was before it entered this function
-    return;
-}
 
 
 int Vector2i__call(lua_State* L)
 int Vector2i__call(lua_State* L)
 {
 {
@@ -163,10 +139,6 @@ luaL_reg Vector2iSetters[]=
     { NULL, NULL },
     { NULL, NULL },
 };
 };
 
 
-template<> const char* GetTClassName<Vector2i>() { return "Vector2i"; }
-template<> RegType<Vector2i>* GetMethodTable<Vector2i>() { return Vector2iMethods; }
-template<> luaL_reg* GetAttrTable<Vector2i>() { return Vector2iGetters; }
-template<> luaL_reg* SetAttrTable<Vector2i>() { return Vector2iSetters; }
 }
 }
 }
 }
 }
 }

Some files were not shown because too many files changed in this diff