Merge in default

--HG--
branch : minor
This commit is contained in:
Bart van Strien
2012-10-14 17:23:35 +02:00
49 changed files with 773 additions and 236 deletions
+18 -2
View File
@@ -8,8 +8,12 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
A5474CEF1624903B00C8EEAC /* math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5474CEE1624903B00C8EEAC /* math.cpp */; };
A901B882143B65C500D77063 /* DrawQable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A901B880143B65C400D77063 /* DrawQable.cpp */; }; A901B882143B65C500D77063 /* DrawQable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A901B880143B65C400D77063 /* DrawQable.cpp */; };
A901B885143B661400D77063 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A901B883143B661300D77063 /* Quad.cpp */; }; A901B885143B661400D77063 /* Quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A901B883143B661300D77063 /* Quad.cpp */; };
A911D2DB15DFECC8005B7EB8 /* Module.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A911D2DA15DFECC8005B7EB8 /* Module.cpp */; };
A911D3C815DFF24D005B7EB8 /* Game_Music_Emu.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A911D3C715DFF24D005B7EB8 /* Game_Music_Emu.framework */; };
A911D3C915DFF25D005B7EB8 /* Game_Music_Emu.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A911D3C715DFF24D005B7EB8 /* Game_Music_Emu.framework */; };
A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E4810420B4A007D418B /* FreeType.framework */; }; A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E4810420B4A007D418B /* FreeType.framework */; };
A9255DD21043183600BA1496 /* SDL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5210420B57007D418B /* SDL.framework */; }; A9255DD21043183600BA1496 /* SDL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5210420B57007D418B /* SDL.framework */; };
A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5310420B57007D418B /* Lua.framework */; }; A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5310420B57007D418B /* Lua.framework */; };
@@ -252,6 +256,7 @@
A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */, A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */,
A9255DD21043183600BA1496 /* SDL.framework in Copy Frameworks */, A9255DD21043183600BA1496 /* SDL.framework in Copy Frameworks */,
A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */, A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */,
A911D3C915DFF25D005B7EB8 /* Game_Music_Emu.framework in Copy Frameworks */,
); );
name = "Copy Frameworks"; name = "Copy Frameworks";
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -261,10 +266,13 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
8D1107320486CEB800E47090 /* love.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = love.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8D1107320486CEB800E47090 /* love.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = love.app; sourceTree = BUILT_PRODUCTS_DIR; };
A5474CEE1624903B00C8EEAC /* math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = math.cpp; sourceTree = "<group>"; };
A901B880143B65C400D77063 /* DrawQable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DrawQable.cpp; sourceTree = "<group>"; }; A901B880143B65C400D77063 /* DrawQable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DrawQable.cpp; sourceTree = "<group>"; };
A901B881143B65C400D77063 /* DrawQable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawQable.h; sourceTree = "<group>"; }; A901B881143B65C400D77063 /* DrawQable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DrawQable.h; sourceTree = "<group>"; };
A901B883143B661300D77063 /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = "<group>"; }; A901B883143B661300D77063 /* Quad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Quad.cpp; sourceTree = "<group>"; };
A901B884143B661300D77063 /* Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = "<group>"; }; A901B884143B661300D77063 /* Quad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quad.h; sourceTree = "<group>"; };
A911D2DA15DFECC8005B7EB8 /* Module.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Module.cpp; sourceTree = "<group>"; };
A911D3C715DFF24D005B7EB8 /* Game_Music_Emu.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Game_Music_Emu.framework; path = /Library/Frameworks/Game_Music_Emu.framework; sourceTree = "<absolute>"; };
A9255DEA1043188D00BA1496 /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMain.m; sourceTree = "<group>"; }; A9255DEA1043188D00BA1496 /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMain.m; sourceTree = "<group>"; };
A9255DEB1043188D00BA1496 /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMain.h; sourceTree = "<group>"; }; A9255DEB1043188D00BA1496 /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMain.h; sourceTree = "<group>"; };
A9255E021043195A00BA1496 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = "<absolute>"; }; A9255E021043195A00BA1496 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = "<absolute>"; };
@@ -740,11 +748,11 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
A9255F461043247300BA1496 /* IL.framework in Frameworks */,
A9255EE810431BD000BA1496 /* Vorbis.framework in Frameworks */,
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
A93E6E4910420B4A007D418B /* OpenAL.framework in Frameworks */, A93E6E4910420B4A007D418B /* OpenAL.framework in Frameworks */,
A93E6E4A10420B4A007D418B /* OpenGL.framework in Frameworks */, A93E6E4A10420B4A007D418B /* OpenGL.framework in Frameworks */,
A9255F461043247300BA1496 /* IL.framework in Frameworks */,
A9255EE810431BD000BA1496 /* Vorbis.framework in Frameworks */,
A93E6E4B10420B4A007D418B /* FreeType.framework in Frameworks */, A93E6E4B10420B4A007D418B /* FreeType.framework in Frameworks */,
A93E6E5410420B57007D418B /* SDL.framework in Frameworks */, A93E6E5410420B57007D418B /* SDL.framework in Frameworks */,
A93E6E5510420B57007D418B /* Lua.framework in Frameworks */, A93E6E5510420B57007D418B /* Lua.framework in Frameworks */,
@@ -752,6 +760,7 @@
A9D307EA106635C3004FEDF8 /* physfs.framework in Frameworks */, A9D307EA106635C3004FEDF8 /* physfs.framework in Frameworks */,
A9F16927109E7BAD00FC83D1 /* libmodplug.framework in Frameworks */, A9F16927109E7BAD00FC83D1 /* libmodplug.framework in Frameworks */,
A9F169A7109E824900FC83D1 /* mpg123.framework in Frameworks */, A9F169A7109E824900FC83D1 /* mpg123.framework in Frameworks */,
A911D3C815DFF24D005B7EB8 /* Game_Music_Emu.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -761,6 +770,7 @@
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
A911D3C715DFF24D005B7EB8 /* Game_Music_Emu.framework */,
A9F169A6109E824900FC83D1 /* mpg123.framework */, A9F169A6109E824900FC83D1 /* mpg123.framework */,
A9F16926109E7BAD00FC83D1 /* libmodplug.framework */, A9F16926109E7BAD00FC83D1 /* libmodplug.framework */,
A9D307E9106635C3004FEDF8 /* physfs.framework */, A9D307E9106635C3004FEDF8 /* physfs.framework */,
@@ -852,11 +862,13 @@
A93E69E010420ABF007D418B /* Exception.cpp */, A93E69E010420ABF007D418B /* Exception.cpp */,
A93E69E110420ABF007D418B /* Exception.h */, A93E69E110420ABF007D418B /* Exception.h */,
A9A5BE4C14A2D2D000D9931C /* int.h */, A9A5BE4C14A2D2D000D9931C /* int.h */,
A5474CEE1624903B00C8EEAC /* math.cpp */,
A93E69E210420ABF007D418B /* math.h */, A93E69E210420ABF007D418B /* math.h */,
A93E69E310420ABF007D418B /* Matrix.cpp */, A93E69E310420ABF007D418B /* Matrix.cpp */,
A93E69E410420ABF007D418B /* Matrix.h */, A93E69E410420ABF007D418B /* Matrix.h */,
A9D5C47C142E32ED0044ECF7 /* Memoizer.cpp */, A9D5C47C142E32ED0044ECF7 /* Memoizer.cpp */,
A9D5C47B142E31350044ECF7 /* Memoizer.h */, A9D5C47B142E31350044ECF7 /* Memoizer.h */,
A911D2DA15DFECC8005B7EB8 /* Module.cpp */,
A93E69E710420ABF007D418B /* Module.h */, A93E69E710420ABF007D418B /* Module.h */,
A93E69E810420ABF007D418B /* Object.cpp */, A93E69E810420ABF007D418B /* Object.cpp */,
A93E69E910420ABF007D418B /* Object.h */, A93E69E910420ABF007D418B /* Object.h */,
@@ -1943,6 +1955,8 @@
A9642D7514D1A66000CE0B02 /* OpenGL.cpp in Sources */, A9642D7514D1A66000CE0B02 /* OpenGL.cpp in Sources */,
A9F6E6AE15A1080D00C86200 /* love.cpp in Sources */, A9F6E6AE15A1080D00C86200 /* love.cpp in Sources */,
A9F6E6B115A1099C00C86200 /* GmeDecoder.cpp in Sources */, A9F6E6B115A1099C00C86200 /* GmeDecoder.cpp in Sources */,
A911D2DB15DFECC8005B7EB8 /* Module.cpp in Sources */,
A5474CEF1624903B00C8EEAC /* math.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -1959,6 +1973,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = love_Prefix.pch; GCC_PREFIX_HEADER = love_Prefix.pch;
INSTALL_PATH = "$(HOME)/Applications"; INSTALL_PATH = "$(HOME)/Applications";
OTHER_CFLAGS = "-DLOVE_SUPPORT_GME=1";
PRODUCT_NAME = love; PRODUCT_NAME = love;
}; };
name = Debug; name = Debug;
@@ -1971,6 +1986,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = love_Prefix.pch; GCC_PREFIX_HEADER = love_Prefix.pch;
INSTALL_PATH = "$(HOME)/Applications"; INSTALL_PATH = "$(HOME)/Applications";
OTHER_CFLAGS = "-DLOVE_SUPPORT_GME=1";
PRODUCT_NAME = love; PRODUCT_NAME = love;
}; };
name = Release; name = Release;
+2
View File
@@ -296,8 +296,10 @@
<ClCompile Include="..\..\src\common\b64.cpp" /> <ClCompile Include="..\..\src\common\b64.cpp" />
<ClCompile Include="..\..\src\common\delay.cpp" /> <ClCompile Include="..\..\src\common\delay.cpp" />
<ClCompile Include="..\..\src\common\Exception.cpp" /> <ClCompile Include="..\..\src\common\Exception.cpp" />
<ClCompile Include="..\..\src\common\math.cpp" />
<ClCompile Include="..\..\src\common\Matrix.cpp" /> <ClCompile Include="..\..\src\common\Matrix.cpp" />
<ClCompile Include="..\..\src\common\Memoizer.cpp" /> <ClCompile Include="..\..\src\common\Memoizer.cpp" />
<ClCompile Include="..\..\src\common\Module.cpp" />
<ClCompile Include="..\..\src\common\Object.cpp" /> <ClCompile Include="..\..\src\common\Object.cpp" />
<ClCompile Include="..\..\src\common\Reference.cpp" /> <ClCompile Include="..\..\src\common\Reference.cpp" />
<ClCompile Include="..\..\src\common\runtime.cpp" /> <ClCompile Include="..\..\src\common\runtime.cpp" />
@@ -738,6 +738,12 @@
<ClCompile Include="..\..\src\modules\love\love.cpp"> <ClCompile Include="..\..\src\modules\love\love.cpp">
<Filter>modules\love</Filter> <Filter>modules\love</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\common\Module.cpp">
<Filter>common</Filter>
</ClCompile>
<ClCompile Include="..\..\src\common\math.cpp">
<Filter>common</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\src\scripts\boot.lua"> <None Include="..\..\src\scripts\boot.lua">
+12 -12
View File
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 11.00 Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010 # Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "love", "love.vcxproj", "{0078B97A-F6DB-E014-BED9-BE378D93CEA4}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "love", "love.vcxproj", "{B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8} = {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8} {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8} = {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}
EndProjectSection EndProjectSection
@@ -18,17 +18,17 @@ Global
Release Static|x64 = Release Static|x64 Release Static|x64 = Release Static|x64
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0078B97A-F6DB-E014-BED9-BE378D93CEA4}.Debug Dynamic|Win32.ActiveCfg = Debug Dynamic|Win32 {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug Dynamic|Win32.ActiveCfg = Debug Dynamic|Win32
{0078B97A-F6DB-E014-BED9-BE378D93CEA4}.Debug Dynamic|Win32.Build.0 = Debug Dynamic|Win32 {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug Dynamic|Win32.Build.0 = Debug Dynamic|Win32
{0078B97A-F6DB-E014-BED9-BE378D93CEA4}.Debug Dynamic|x64.ActiveCfg = Debug Dynamic|x64 {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Debug Dynamic|x64.ActiveCfg = Debug Dynamic|x64
{0078B97A-F6DB-E014-BED9-BE378D93CEA4}.Release Dynamic|Win32.ActiveCfg = Release Dynamic|Win32 {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Dynamic|Win32.ActiveCfg = Release Dynamic|Win32
{0078B97A-F6DB-E014-BED9-BE378D93CEA4}.Release Dynamic|Win32.Build.0 = Release Dynamic|Win32 {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Dynamic|Win32.Build.0 = Release Dynamic|Win32
{0078B97A-F6DB-E014-BED9-BE378D93CEA4}.Release Dynamic|x64.ActiveCfg = Release Dynamic|x64 {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Dynamic|x64.ActiveCfg = Release Dynamic|x64
{0078B97A-F6DB-E014-BED9-BE378D93CEA4}.Release Dynamic|x64.Build.0 = Release Dynamic|x64 {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Dynamic|x64.Build.0 = Release Dynamic|x64
{0078B97A-F6DB-E014-BED9-BE378D93CEA4}.Release Static|Win32.ActiveCfg = Release Static|Win32 {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Static|Win32.ActiveCfg = Release Static|Win32
{0078B97A-F6DB-E014-BED9-BE378D93CEA4}.Release Static|Win32.Build.0 = Release Static|Win32 {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Static|Win32.Build.0 = Release Static|Win32
{0078B97A-F6DB-E014-BED9-BE378D93CEA4}.Release Static|x64.ActiveCfg = Release Static|x64 {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Static|x64.ActiveCfg = Release Static|x64
{0078B97A-F6DB-E014-BED9-BE378D93CEA4}.Release Static|x64.Build.0 = Release Static|x64 {B496CCF6-9B6D-0794-8F41-67A6EC86B4AA}.Release Static|x64.Build.0 = Release Static|x64
{A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug Dynamic|Win32.ActiveCfg = Debug Dynamic|Win32 {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug Dynamic|Win32.ActiveCfg = Debug Dynamic|Win32
{A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug Dynamic|Win32.Build.0 = Debug Dynamic|Win32 {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug Dynamic|Win32.Build.0 = Debug Dynamic|Win32
{A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug Dynamic|x64.ActiveCfg = Debug Dynamic|x64 {A3FCC735-3E18-4D6B-9DA9-01D9E910B7F8}.Debug Dynamic|x64.ActiveCfg = Debug Dynamic|x64
+6 -6
View File
@@ -125,7 +125,7 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>include;include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation> <MultiProcessorCompilation>
</MultiProcessorCompilation> </MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
@@ -146,7 +146,7 @@
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>include;include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation> <MultiProcessorCompilation>
</MultiProcessorCompilation> </MultiProcessorCompilation>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
@@ -165,7 +165,7 @@
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level1</WarningLevel> <WarningLevel>Level1</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>include;include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OmitFramePointers>true</OmitFramePointers> <OmitFramePointers>true</OmitFramePointers>
<StringPooling>true</StringPooling> <StringPooling>true</StringPooling>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
@@ -189,7 +189,7 @@
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level1</WarningLevel> <WarningLevel>Level1</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>include;include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OmitFramePointers>true</OmitFramePointers> <OmitFramePointers>true</OmitFramePointers>
<StringPooling>true</StringPooling> <StringPooling>true</StringPooling>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
@@ -208,7 +208,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|Win32'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>include;include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OmitFramePointers>true</OmitFramePointers> <OmitFramePointers>true</OmitFramePointers>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling> <StringPooling>true</StringPooling>
@@ -227,7 +227,7 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Static|x64'">
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>include;include\SDL;..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<OmitFramePointers>true</OmitFramePointers> <OmitFramePointers>true</OmitFramePointers>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling> <StringPooling>true</StringPooling>
+1 -1
View File
@@ -18,7 +18,7 @@ AUTOMAKE=$(which automake)
[[ -x ${AUTOMAKE} ]] || die "Could not find automake." [[ -x ${AUTOMAKE} ]] || die "Could not find automake."
automagic() { automagic() {
cp platform/unix/configure.in . cp platform/unix/configure.ac .
cp platform/unix/Makefile.am . cp platform/unix/Makefile.am .
if ! sh platform/unix/gen-makefile; then if ! sh platform/unix/gen-makefile; then
@@ -6,7 +6,7 @@ AC_CONFIG_SRCDIR([src/love.cpp])
AM_INIT_AUTOMAKE([foreign -Wall foreign tar-ustar silent-rules]) AM_INIT_AUTOMAKE([foreign -Wall foreign tar-ustar silent-rules])
AM_SILENT_RULES AM_SILENT_RULES
AC_PREFIX_DEFAULT([/usr]) AC_PREFIX_DEFAULT([/usr])
AM_PROG_AR m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_LIBTOOL AC_PROG_LIBTOOL
AC_PROG_CC AC_PROG_CC
AC_PROG_CXX AC_PROG_CXX
+65
View File
@@ -0,0 +1,65 @@
/**
* Copyright (c) 2006-2012 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "Module.h"
#include "Exception.h"
// std
#include <map>
#include <utility>
#include <string>
namespace
{
std::map<std::string, love::Module*> registry;
} // anonymous namespace
namespace love
{
void Module::registerInstance(Module *instance)
{
if (instance == NULL)
throw Exception("Module instance is NULL");
std::string name(instance->getName());
std::map<std::string, Module*>::iterator it = registry.find(name);
if (registry.end() != it)
{
if (it->second == instance)
return;
throw Exception("Module %s already registered!", instance->getName());
}
registry.insert(make_pair(name, instance));
}
Module *Module::getInstance(const char *name)
{
std::map<std::string, Module*>::iterator it = registry.find(std::string(name));
if (registry.end() == it)
return NULL;
return it->second;
}
} // namespace love
+15
View File
@@ -48,6 +48,21 @@ public:
**/ **/
virtual const char *getName() const = 0; virtual const char *getName() const = 0;
/**
* Add module to internal registry. To be used /only/ in
* runtime.cpp:luax_register_module()
* @param instance The module instance.
*/
static void registerInstance(Module *instance);
/**
* Retrieve module instance from internal registry. May return NULL
* if module not registered.
* @param name The full name of the module.
* @returns Module instance of NULL if the module is not registered.
*/
static Module *getInstance(const char *name);
}; // Module }; // Module
} // love } // love
+33
View File
@@ -0,0 +1,33 @@
#include "math.h"
#include <limits>
#include <cmath>
namespace
{
// The BoxMuller transform generates two random numbers, one of which we
// cache here. A value of +infinity is used to signal the cache is invalid
// and that new numbers have to be generated.
float last_randnormal = std::numeric_limits<float>::infinity();
}
namespace love
{
float random_normal(float o)
{
// number in cache?
if (last_randnormal != std::numeric_limits<float>::infinity())
{
float r = last_randnormal;
last_randnormal = std::numeric_limits<float>::infinity();
return r * o;
}
// else: generate numbers using the Box-Muller transform
float a = sqrt(-2.0f * log(random()));
float b = float(LOVE_M_PI) * 2.0f * random();
last_randnormal = a * cos(b);
return a * sin(b) * o;
}
} // namespace love
+37
View File
@@ -22,6 +22,7 @@
#define LOVE_MATH_H #define LOVE_MATH_H
#include <climits> // for CHAR_BIT #include <climits> // for CHAR_BIT
#include <cstdlib> // for rand() and RAND_MAX
/* Definitions of useful mathematical constants /* Definitions of useful mathematical constants
* M_E - e * M_E - e
@@ -80,6 +81,42 @@ inline float next_p2(float x)
return static_cast<float>(next_p2(static_cast<int>(x))); return static_cast<float>(next_p2(static_cast<int>(x)));
} }
/**
* Draws a random number from a uniform distribution.
* @returns Uniformly distributed random number in [0:1).
*/
inline float random()
{
// to satisfy picky compilers...
return float(double(rand() % RAND_MAX) / double(RAND_MAX));
}
/**
* Draws a random number from a uniform distribution.
* @return Uniformly distributed random number in [0:max).
*/
inline float random(float max)
{
return random() * max;
}
/**
* Draws a random number from a uniform distribution.
* @return Uniformly distributed random number in [min:max).
*/
inline float random(float min, float max)
{
return random(max - min) + min;
}
/**
* Draws a random number from a normal/gaussian distribution.
* @param o Standard deviation of the distribution.
* @returns Normal distributed random number with mean 0 and variance o^2.
*/
float random_normal(float o = 1.);
#define random_gaussian random_normal
} // love } // love
#endif // LOVE_MATH_H #endif // LOVE_MATH_H
+3
View File
@@ -196,6 +196,9 @@ int luax_register_module(lua_State *L, const WrappedModule &m)
lua_setfield(L, -3, m.name); // love.graphics = table lua_setfield(L, -3, m.name); // love.graphics = table
lua_remove(L, -2); // love lua_remove(L, -2); // love
// Register module instance
Module::registerInstance(m.module);
return 1; return 1;
} }
+16 -14
View File
@@ -91,22 +91,24 @@ Message *Event::convert(SDL_Event &e)
switch (e.type) switch (e.type)
{ {
case SDL_KEYDOWN: case SDL_KEYDOWN:
if (keys.find(e.key.keysym.sym, key) && love::event::Event::keys.find(key, txt)) if (!keys.find(e.key.keysym.sym, key))
{ key = love::keyboard::Keyboard::KEY_UNKNOWN;
arg1 = new Variant(txt, strlen(txt)); if (!love::event::Event::keys.find(key, txt))
arg2 = new Variant((double) e.key.keysym.unicode); txt = "unknown";
msg = new Message("keypressed", arg1, arg2); arg1 = new Variant(txt, strlen(txt));
arg1->release(); arg2 = new Variant((double) e.key.keysym.unicode);
arg2->release(); msg = new Message("keypressed", arg1, arg2);
} arg1->release();
arg2->release();
break; break;
case SDL_KEYUP: case SDL_KEYUP:
if (keys.find(e.key.keysym.sym, key) && love::event::Event::keys.find(key, txt)) if (!keys.find(e.key.keysym.sym, key))
{ key = love::keyboard::Keyboard::KEY_UNKNOWN;
arg1 = new Variant(txt, strlen(txt)); if (!love::event::Event::keys.find(key, txt))
msg = new Message("keyreleased", arg1); txt = "unknown";
arg1->release(); arg1 = new Variant(txt, strlen(txt));
} msg = new Message("keyreleased", arg1);
arg1->release();
break; break;
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
+2 -1
View File
@@ -29,6 +29,7 @@
#include "common/Object.h" #include "common/Object.h"
#include "common/StringMap.h" #include "common/StringMap.h"
#include "common/int.h" #include "common/int.h"
#include "FileData.h"
namespace love namespace love
{ {
@@ -93,7 +94,7 @@ public:
* @param size The number of bytes to attempt reading, or -1 for EOF. * @param size The number of bytes to attempt reading, or -1 for EOF.
* @return A newly allocated Data object. * @return A newly allocated Data object.
**/ **/
virtual Data *read(int64 size = ALL) = 0; virtual FileData *read(int64 size = ALL) = 0;
/** /**
* Reads data into the destination buffer. * Reads data into the destination buffer.
+1 -1
View File
@@ -111,7 +111,7 @@ int64 File::getSize()
} }
Data *File::read(int64 size) FileData *File::read(int64 size)
{ {
bool isOpen = (file != 0); bool isOpen = (file != 0);
+1 -1
View File
@@ -69,7 +69,7 @@ public:
bool open(Mode mode); bool open(Mode mode);
bool close(); bool close();
int64 getSize(); int64 getSize();
Data *read(int64 size = ALL); FileData *read(int64 size = ALL);
int64 read(void *dst, int64 size); int64 read(void *dst, int64 size);
bool write(const void *data, int64 size); bool write(const void *data, int64 size);
bool write(const Data *data, int64 size = ALL); bool write(const Data *data, int64 size = ALL);
+10
View File
@@ -131,6 +131,16 @@ void ImageRasterizer::load()
widths[c] = (end - start); widths[c] = (end - start);
} }
// Find spacing of last glyph
if (length > 0)
{
start = end;
while (start < imgw && equal(pixels[start], spacer))
++start;
spacing[glyphs[length - 1]] = (start > end) ? (start - end) : 0;
}
// Replace spacer color with an empty pixel // Replace spacer color with an empty pixel
for (unsigned int i = 0; i < imgs; ++i) for (unsigned int i = 0; i < imgs; ++i)
{ {
+1
View File
@@ -156,6 +156,7 @@ StringMap<Graphics::PointStyle, Graphics::POINT_MAX_ENUM> Graphics::pointStyles(
StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM>::Entry Graphics::supportEntries[] = StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM>::Entry Graphics::supportEntries[] =
{ {
{ "canvas", Graphics::SUPPORT_CANVAS }, { "canvas", Graphics::SUPPORT_CANVAS },
{ "hdrcanvas", Graphics::SUPPORT_HDR_CANVAS },
{ "pixeleffect", Graphics::SUPPORT_PIXELEFFECT }, { "pixeleffect", Graphics::SUPPORT_PIXELEFFECT },
{ "npot", Graphics::SUPPORT_NPOT }, { "npot", Graphics::SUPPORT_NPOT },
{ "subtractive", Graphics::SUPPORT_SUBTRACTIVE }, { "subtractive", Graphics::SUPPORT_SUBTRACTIVE },
+1
View File
@@ -85,6 +85,7 @@ public:
enum Support enum Support
{ {
SUPPORT_CANVAS = 1, SUPPORT_CANVAS = 1,
SUPPORT_HDR_CANVAS,
SUPPORT_PIXELEFFECT, SUPPORT_PIXELEFFECT,
SUPPORT_NPOT, SUPPORT_NPOT,
SUPPORT_SUBTRACTIVE, SUPPORT_SUBTRACTIVE,
-5
View File
@@ -50,11 +50,6 @@ public:
virtual void flip(bool x, bool y) = 0; virtual void flip(bool x, bool y) = 0;
/**
* Mirror texture coordinates around 0.5
*/
virtual void mirror(bool x, bool y) = 0;
/** /**
* Gets a pointer to the vertices. * Gets a pointer to the vertices.
**/ **/
+148 -39
View File
@@ -42,9 +42,10 @@ struct FramebufferStrategy
* @param[out] img Texture name * @param[out] img Texture name
* @param[in] width Width of framebuffer * @param[in] width Width of framebuffer
* @param[in] height Height of framebuffer * @param[in] height Height of framebuffer
* @param[in] texture_type Type of the canvas texture.
* @return Creation status * @return Creation status
*/ */
virtual GLenum createFBO(GLuint &, GLuint &, GLuint &, int, int) virtual GLenum createFBO(GLuint &, GLuint &, GLuint &, int, int, Canvas::TextureType)
{ {
return GL_FRAMEBUFFER_UNSUPPORTED; return GL_FRAMEBUFFER_UNSUPPORTED;
} }
@@ -60,7 +61,7 @@ struct FramebufferStrategy
struct FramebufferStrategyGL3 : public FramebufferStrategy struct FramebufferStrategyGL3 : public FramebufferStrategy
{ {
virtual GLenum createFBO(GLuint &framebuffer, GLuint &depth_stencil, GLuint &img, int width, int height) virtual GLenum createFBO(GLuint &framebuffer, GLuint &depth_stencil, GLuint &img, int width, int height, Canvas::TextureType texture_type)
{ {
// get currently bound fbo to reset to it later // get currently bound fbo to reset to it later
GLint current_fbo; GLint current_fbo;
@@ -75,27 +76,41 @@ struct FramebufferStrategyGL3 : public FramebufferStrategy
glBindRenderbuffer(GL_RENDERBUFFER, depth_stencil); glBindRenderbuffer(GL_RENDERBUFFER, depth_stencil);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_RENDERBUFFER, depth_stencil); GL_RENDERBUFFER, depth_stencil);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depth_stencil); GL_RENDERBUFFER, depth_stencil);
// generate texture save target // generate texture save target
GLint internalFormat;
GLenum format;
switch (texture_type)
{
case Canvas::TYPE_HDR:
internalFormat = GL_RGBA16F;
format = GL_FLOAT;
break;
case Canvas::TYPE_NORMAL:
default:
internalFormat = GL_RGBA8;
format = GL_UNSIGNED_BYTE;
}
glGenTextures(1, &img); glGenTextures(1, &img);
bindTexture(img); bindTexture(img);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 0, GL_RGBA, format, NULL);
bindTexture(0); bindTexture(0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, img, 0); GL_TEXTURE_2D, img, 0);
// check status // check status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
// unbind framebuffer // unbind framebuffer
glBindRenderbuffer(GL_RENDERBUFFER, 0); glBindRenderbuffer(GL_RENDERBUFFER, 0);
glBindFramebuffer(GL_FRAMEBUFFER, (GLuint)current_fbo); glBindFramebuffer(GL_FRAMEBUFFER, (GLuint) current_fbo);
return status; return status;
} }
virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil, GLuint img) virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil, GLuint img)
@@ -111,10 +126,9 @@ struct FramebufferStrategyGL3 : public FramebufferStrategy
} }
}; };
struct FramebufferStrategyEXT : public FramebufferStrategy struct FramebufferStrategyPackedEXT : public FramebufferStrategy
{ {
virtual GLenum createFBO(GLuint &framebuffer, GLuint &depth_stencil, GLuint &img, int width, int height, Canvas::TextureType texture_type)
virtual GLenum createFBO(GLuint &framebuffer, GLuint &depth_stencil, GLuint &img, int width, int height)
{ {
GLint current_fbo; GLint current_fbo;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &current_fbo); glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &current_fbo);
@@ -126,29 +140,45 @@ struct FramebufferStrategyEXT : public FramebufferStrategy
// create stencil buffer // create stencil buffer
glGenRenderbuffersEXT(1, &depth_stencil); glGenRenderbuffersEXT(1, &depth_stencil);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_stencil);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, width, height); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT,
width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, depth_stencil); GL_RENDERBUFFER_EXT, depth_stencil);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, depth_stencil); GL_RENDERBUFFER_EXT, depth_stencil);
// generate texture save target // generate texture save target
GLint internalFormat;
GLenum format;
switch (texture_type)
{
case Canvas::TYPE_HDR:
internalFormat = GL_RGBA16F;
format = GL_FLOAT;
break;
case Canvas::TYPE_NORMAL:
default:
internalFormat = GL_RGBA8;
format = GL_UNSIGNED_BYTE;
}
glGenTextures(1, &img); glGenTextures(1, &img);
bindTexture(img); bindTexture(img);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height,
0, GL_RGBA, format, NULL);
bindTexture(0); bindTexture(0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, img, 0); GL_TEXTURE_2D, img, 0);
// check status // check status
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
// unbind framebuffer // unbind framebuffer
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (GLuint)current_fbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (GLuint) current_fbo);
return status; return status;
} }
@@ -165,45 +195,112 @@ struct FramebufferStrategyEXT : public FramebufferStrategy
} }
}; };
struct FramebufferStrategyEXT : public FramebufferStrategyPackedEXT
{
virtual GLenum createFBO(GLuint &framebuffer, GLuint &stencil, GLuint &img, int width, int height, Canvas::TextureType texture_type)
{
GLint current_fbo;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING_EXT, &current_fbo);
// create framebuffer
glGenFramebuffersEXT(1, &framebuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer);
// create stencil buffer
glGenRenderbuffersEXT(1, &stencil);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX,
width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
GL_RENDERBUFFER_EXT, stencil);
// generate texture save target
GLint internalFormat;
GLenum format;
switch (texture_type)
{
case Canvas::TYPE_HDR:
internalFormat = GL_RGBA16F;
format = GL_FLOAT;
break;
case Canvas::TYPE_NORMAL:
default:
internalFormat = GL_RGBA8;
format = GL_UNSIGNED_BYTE;
}
glGenTextures(1, &img);
bindTexture(img);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height,
0, GL_RGBA, format, NULL);
bindTexture(0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, img, 0);
// check status
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
// unbind framebuffer
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (GLuint) current_fbo);
return status;
}
bool isSupported()
{
GLuint fb, stencil, img;
GLenum status = createFBO(fb, stencil, img, 2, 2, Canvas::TYPE_NORMAL);
deleteFBO(fb, stencil, img);
return status == GL_FRAMEBUFFER_COMPLETE;
}
};
FramebufferStrategy *strategy = NULL; FramebufferStrategy *strategy = NULL;
FramebufferStrategy strategyNone; FramebufferStrategy strategyNone;
FramebufferStrategyGL3 strategyGL3; FramebufferStrategyGL3 strategyGL3;
FramebufferStrategyPackedEXT strategyPackedEXT;
FramebufferStrategyEXT strategyEXT; FramebufferStrategyEXT strategyEXT;
Canvas *Canvas::current = NULL; Canvas *Canvas::current = NULL;
static void loadStrategy() static void getStrategy()
{ {
if (!strategy) if (!strategy)
{ {
if (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object) if (GLEE_VERSION_3_0 || GLEE_ARB_framebuffer_object)
strategy = &strategyGL3; strategy = &strategyGL3;
else if (GLEE_EXT_framebuffer_object && GLEE_EXT_packed_depth_stencil) else if (GLEE_EXT_framebuffer_object && GLEE_EXT_packed_depth_stencil)
strategy = &strategyPackedEXT;
else if (GLEE_EXT_framebuffer_object && strategyEXT.isSupported())
strategy = &strategyEXT; strategy = &strategyEXT;
else else
strategy = &strategyNone; strategy = &strategyNone;
} }
} }
Canvas::Canvas(int width, int height) Canvas::Canvas(int width, int height, TextureType texture_type)
: width(width) : width(width)
, height(height) , height(height)
, texture_type(texture_type)
{ {
float w = static_cast<float>(width); float w = static_cast<float>(width);
float h = static_cast<float>(height); float h = static_cast<float>(height);
// world coordinates // world coordinates
vertices[0].x = 0; vertices[0].x = 0;
vertices[0].y = 0; vertices[0].y = h;
vertices[1].x = 0; vertices[1].x = 0;
vertices[1].y = h; vertices[1].y = 0;
vertices[2].x = w; vertices[2].x = w;
vertices[2].y = h; vertices[2].y = 0;
vertices[3].x = w; vertices[3].x = w;
vertices[3].y = 0; vertices[3].y = h;
// texture coordinates // texture coordinates
vertices[0].s = 0; vertices[0].s = 0;
@@ -215,7 +312,7 @@ Canvas::Canvas(int width, int height)
vertices[3].s = 1; vertices[3].s = 1;
vertices[3].t = 1; vertices[3].t = 1;
loadStrategy(); getStrategy();
loadVolatile(); loadVolatile();
} }
@@ -231,10 +328,15 @@ Canvas::~Canvas()
bool Canvas::isSupported() bool Canvas::isSupported()
{ {
loadStrategy(); getStrategy();
return (strategy != &strategyNone); return (strategy != &strategyNone);
} }
bool Canvas::isHdrSupported()
{
return GLEE_VERSION_3_0 || GLEE_ARB_texture_float;
}
void Canvas::bindDefaultCanvas() void Canvas::bindDefaultCanvas()
{ {
if (current != NULL) if (current != NULL)
@@ -262,7 +364,7 @@ void Canvas::startGrab()
glLoadIdentity(); glLoadIdentity();
// Set up orthographic view (no depth) // Set up orthographic view (no depth)
glOrtho(0.0, width, height, 0.0, -1.0, 1.0); glOrtho(0.0, width, 0.0, height, -1.0, 1.0);
// Switch back to modelview matrix // Switch back to modelview matrix
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
@@ -312,12 +414,10 @@ void Canvas::draw(float x, float y, float angle, float sx, float sy, float ox, f
void Canvas::drawq(love::graphics::Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const void Canvas::drawq(love::graphics::Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
{ {
static Matrix t; static Matrix t;
quad->mirror(false, true);
const vertex *v = quad->getVertices(); const vertex *v = quad->getVertices();
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
drawv(t, v); drawv(t, v);
quad->mirror(false, true);
} }
love::image::ImageData *Canvas::getImageData(love::image::Image *image) love::image::ImageData *Canvas::getImageData(love::image::Image *image)
@@ -325,7 +425,6 @@ love::image::ImageData *Canvas::getImageData(love::image::Image *image)
int row = 4 * width; int row = 4 * width;
int size = row * height; int size = row * height;
GLubyte *pixels = new GLubyte[size]; GLubyte *pixels = new GLubyte[size];
GLubyte *screenshot = new GLubyte[size];
strategy->bindFBO(fbo); strategy->bindFBO(fbo);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
@@ -334,15 +433,8 @@ love::image::ImageData *Canvas::getImageData(love::image::Image *image)
else else
strategy->bindFBO(0); strategy->bindFBO(0);
GLubyte *src = pixels - row; // second line of source image love::image::ImageData *img = image->newImageData(width, height, (void *)pixels);
GLubyte *dst = screenshot + size; // last row of destination image
for (int i = 0; i < height; ++i)
memcpy(dst -= row, src += row, row);
love::image::ImageData *img = image->newImageData(width, height, (void *)screenshot);
delete[] screenshot;
delete[] pixels; delete[] pixels;
return img; return img;
@@ -399,7 +491,7 @@ Image::Wrap Canvas::getWrap() const
bool Canvas::loadVolatile() bool Canvas::loadVolatile()
{ {
status = strategy->createFBO(fbo, depth_stencil, img, width, height); status = strategy->createFBO(fbo, depth_stencil, img, width, height, texture_type);
if (status != GL_FRAMEBUFFER_COMPLETE) if (status != GL_FRAMEBUFFER_COMPLETE)
return false; return false;
@@ -447,6 +539,23 @@ void Canvas::drawv(const Matrix &t, const vertex *v) const
glPopMatrix(); glPopMatrix();
} }
bool Canvas::getConstant(const char *in, Canvas::TextureType &out)
{
return textureTypes.find(in, out);
}
bool Canvas::getConstant(Canvas::TextureType in, const char *&out)
{
return textureTypes.find(in, out);
}
StringMap<Canvas::TextureType, Canvas::TYPE_MAX_ENUM>::Entry Canvas::textureTypeEntries[] =
{
{"normal", Canvas::TYPE_NORMAL},
{"hdr", Canvas::TYPE_HDR},
};
StringMap<Canvas::TextureType, Canvas::TYPE_MAX_ENUM> Canvas::textureTypes(Canvas::textureTypeEntries, sizeof(Canvas::textureTypeEntries));
} // opengl } // opengl
} // graphics } // graphics
} // love } // love
+31 -12
View File
@@ -42,19 +42,15 @@ namespace opengl
class Canvas : public DrawQable, public Volatile class Canvas : public DrawQable, public Volatile
{ {
public: public:
Canvas(int width, int height); enum TextureType {
TYPE_NORMAL,
TYPE_HDR,
TYPE_MAX_ENUM
};
Canvas(int width, int height, TextureType texture_type = TYPE_NORMAL);
virtual ~Canvas(); virtual ~Canvas();
static bool isSupported();
unsigned int getStatus() const
{
return status;
}
static Canvas *current;
static void bindDefaultCanvas();
void startGrab(); void startGrab();
void stopGrab(); void stopGrab();
@@ -78,9 +74,27 @@ public:
int getWidth(); int getWidth();
int getHeight(); int getHeight();
unsigned int getStatus() const
{
return status;
}
TextureType getTextureType() const
{
return texture_type;
}
bool loadVolatile(); bool loadVolatile();
void unloadVolatile(); void unloadVolatile();
static bool isSupported();
static bool isHdrSupported();
static bool getConstant(const char *in, TextureType &out);
static bool getConstant(TextureType in, const char *&out);
static Canvas *current;
static void bindDefaultCanvas();
private: private:
friend class PixelEffect; friend class PixelEffect;
GLuint getTextureName() const GLuint getTextureName() const
@@ -94,6 +108,8 @@ private:
GLuint depth_stencil; GLuint depth_stencil;
GLuint img; GLuint img;
TextureType texture_type;
vertex vertices[4]; vertex vertices[4];
GLenum status; GLenum status;
@@ -101,10 +117,13 @@ private:
struct struct
{ {
Image::Filter filter; Image::Filter filter;
Image::Wrap wrap; Image::Wrap wrap;
} settings; } settings;
void drawv(const Matrix &t, const vertex *v) const; void drawv(const Matrix &t, const vertex *v) const;
static StringMap<TextureType, TYPE_MAX_ENUM>::Entry textureTypeEntries[];
static StringMap<TextureType, TYPE_MAX_ENUM> textureTypes;
}; };
} // opengl } // opengl
+10 -4
View File
@@ -400,9 +400,15 @@ ParticleSystem *Graphics::newParticleSystem(Image *image, int size)
return new ParticleSystem(image, size); return new ParticleSystem(image, size);
} }
Canvas *Graphics::newCanvas(int width, int height) Canvas *Graphics::newCanvas(int width, int height, Canvas::TextureType texture_type)
{ {
Canvas *canvas = new Canvas(width, height); if (texture_type == Canvas::TYPE_HDR && !Canvas::isHdrSupported())
throw Exception("HDR Canvases are not supported by your OpenGL implementation");
while (GL_NO_ERROR != glGetError())
/* clear opengl error flag */;
Canvas *canvas = new Canvas(width, height, texture_type);
GLenum err = canvas->getStatus(); GLenum err = canvas->getStatus();
// everything ok, return canvas (early out) // everything ok, return canvas (early out)
@@ -543,7 +549,7 @@ void Graphics::setBlendMode(Graphics::BlendMode mode)
if (mode == BLEND_ALPHA) if (mode == BLEND_ALPHA)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
else if (mode == BLEND_MULTIPLICATIVE) else if (mode == BLEND_MULTIPLICATIVE)
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_DST_COLOR, GL_ZERO);
else if (mode == BLEND_PREMULTIPLIED) else if (mode == BLEND_PREMULTIPLIED)
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
else // mode == BLEND_ADDITIVE || mode == BLEND_SUBTRACTIVE else // mode == BLEND_ADDITIVE || mode == BLEND_SUBTRACTIVE
@@ -582,7 +588,7 @@ Graphics::BlendMode Graphics::getBlendMode()
return BLEND_ADDITIVE; return BLEND_ADDITIVE;
else if (src == GL_SRC_ALPHA && dst == GL_ONE_MINUS_SRC_ALPHA) // && equation == GL_FUNC_ADD else if (src == GL_SRC_ALPHA && dst == GL_ONE_MINUS_SRC_ALPHA) // && equation == GL_FUNC_ADD
return BLEND_ALPHA; return BLEND_ALPHA;
else if (src == GL_DST_COLOR && dst == GL_ONE_MINUS_SRC_ALPHA) // && equation == GL_FUNC_ADD else if (src == GL_DST_COLOR && dst == GL_ZERO) // && equation == GL_FUNC_ADD
return BLEND_MULTIPLICATIVE; return BLEND_MULTIPLICATIVE;
else if (src == GL_ONE && dst == GL_ONE_MINUS_SRC_ALPHA) // && equation == GL_FUNC_ADD else if (src == GL_ONE && dst == GL_ONE_MINUS_SRC_ALPHA) // && equation == GL_FUNC_ADD
return BLEND_PREMULTIPLIED; return BLEND_PREMULTIPLIED;
+1 -1
View File
@@ -267,7 +267,7 @@ public:
ParticleSystem *newParticleSystem(Image *image, int size); ParticleSystem *newParticleSystem(Image *image, int size);
Canvas *newCanvas(int width, int height); Canvas *newCanvas(int width, int height, Canvas::TextureType texture_type = Canvas::TYPE_NORMAL);
PixelEffect *newPixelEffect(const std::string &code); PixelEffect *newPixelEffect(const std::string &code);
+61 -10
View File
@@ -45,10 +45,18 @@ float calculate_variation(float inner, float outer, float var)
{ {
float low = inner - (outer/2.0f)*var; float low = inner - (outer/2.0f)*var;
float high = inner + (outer/2.0f)*var; float high = inner + (outer/2.0f)*var;
float r = (rand() / (float(RAND_MAX)+1)); float r = random();
return low*(1-r)+high*r; return low*(1-r)+high*r;
} }
StringMap<ParticleSystem::AreaSpreadDistribution, ParticleSystem::DISTRIBUTION_MAX_ENUM>::Entry ParticleSystem::distributionsEntries[] = {
{ "none", ParticleSystem::DISTRIBUTION_NONE },
{ "uniform", ParticleSystem::DISTRIBUTION_UNIFORM },
{ "normal", ParticleSystem::DISTRIBUTION_NORMAL },
};
StringMap<ParticleSystem::AreaSpreadDistribution, ParticleSystem::DISTRIBUTION_MAX_ENUM> ParticleSystem::distributions(ParticleSystem::distributionsEntries, sizeof(ParticleSystem::distributionsEntries));
ParticleSystem::ParticleSystem(Image *sprite, unsigned int buffer) ParticleSystem::ParticleSystem(Image *sprite, unsigned int buffer)
: pStart(0) : pStart(0)
@@ -57,6 +65,7 @@ ParticleSystem::ParticleSystem(Image *sprite, unsigned int buffer)
, active(true) , active(true)
, emissionRate(0) , emissionRate(0)
, emitCounter(0) , emitCounter(0)
, areaSpreadDistribution(DISTRIBUTION_NONE)
, lifetime(-1) , lifetime(-1)
, life(0) , life(0)
, particleLifeMin(0) , particleLifeMin(0)
@@ -108,45 +117,60 @@ void ParticleSystem::add()
if (min == max) if (min == max)
pLast->life = min; pLast->life = min;
else else
pLast->life = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; pLast->life = random(min, max);
pLast->lifetime = pLast->life; pLast->lifetime = pLast->life;
pLast->position[0] = position.getX(); pLast->position[0] = position.getX();
pLast->position[1] = position.getY(); pLast->position[1] = position.getY();
switch (areaSpreadDistribution)
{
case DISTRIBUTION_UNIFORM:
pLast->position[0] += random(-areaSpread.getX(), areaSpread.getX());
pLast->position[1] += random(-areaSpread.getY(), areaSpread.getY());
break;
case DISTRIBUTION_NORMAL:
pLast->position[0] += random_normal(areaSpread.getX());
pLast->position[1] += random_normal(areaSpread.getY());
break;
case DISTRIBUTION_NONE:
default:
break;
}
min = direction - spread/2.0f; min = direction - spread/2.0f;
max = direction + spread/2.0f; max = direction + spread/2.0f;
pLast->direction = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; pLast->direction = random(min, max);
pLast->origin = position; pLast->origin = position;
min = speedMin; min = speedMin;
max = speedMax; max = speedMax;
float speed = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; float speed = random(min, max);
pLast->speed = love::Vector(cos(pLast->direction), sin(pLast->direction)); pLast->speed = love::Vector(cos(pLast->direction), sin(pLast->direction));
pLast->speed *= speed; pLast->speed *= speed;
min = gravityMin; min = gravityMin;
max = gravityMax; max = gravityMax;
pLast->gravity = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; pLast->gravity = random(min, max);
min = radialAccelerationMin; min = radialAccelerationMin;
max = radialAccelerationMax; max = radialAccelerationMax;
pLast->radialAcceleration = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; pLast->radialAcceleration = random(min, max);
min = tangentialAccelerationMin; min = tangentialAccelerationMin;
max = tangentialAccelerationMax; max = tangentialAccelerationMax;
pLast->tangentialAcceleration = (rand() / (float(RAND_MAX)+1)) * (max - min) + min; pLast->tangentialAcceleration = random(min, max);
pLast->sizeOffset = (rand() / (float(RAND_MAX)+1)) * sizeVariation; // time offset for size change pLast->sizeOffset = random(sizeVariation); // time offset for size change
pLast->sizeIntervalSize = (1.0f - (rand() / (float(RAND_MAX)+1)) * sizeVariation) - pLast->sizeOffset; pLast->sizeIntervalSize = (1.0f - random(sizeVariation)) - pLast->sizeOffset;
pLast->size = sizes[(size_t)(pLast->sizeOffset - .5f) * (sizes.size() - 1)]; pLast->size = sizes[(size_t)(pLast->sizeOffset - .5f) * (sizes.size() - 1)];
min = rotationMin; min = rotationMin;
max = rotationMax; max = rotationMax;
pLast->spinStart = calculate_variation(spinStart, spinEnd, spinVariation); pLast->spinStart = calculate_variation(spinStart, spinEnd, spinVariation);
pLast->spinEnd = calculate_variation(spinEnd, spinStart, spinVariation); pLast->spinEnd = calculate_variation(spinEnd, spinStart, spinVariation);
pLast->rotation = (rand() / (float(RAND_MAX)+1)) * (max - min) + min;; pLast->rotation = random(min, max);
pLast->color = colors[0]; pLast->color = colors[0];
@@ -204,6 +228,13 @@ void ParticleSystem::setPosition(float x, float y)
position = love::Vector(x, y); position = love::Vector(x, y);
} }
void ParticleSystem::setAreaSpread(AreaSpreadDistribution distribution, float x, float y)
{
areaSpread = love::Vector(x, y);
areaSpreadDistribution = distribution;
}
void ParticleSystem::setDirection(float direction) void ParticleSystem::setDirection(float direction)
{ {
this->direction = direction; this->direction = direction;
@@ -349,6 +380,16 @@ const love::Vector &ParticleSystem::getPosition() const
return position; return position;
} }
ParticleSystem::AreaSpreadDistribution ParticleSystem::getAreaSpreadDistribution() const
{
return areaSpreadDistribution;
}
const love::Vector &ParticleSystem::getAreaSpreadParameters() const
{
return areaSpread;
}
float ParticleSystem::getDirection() const float ParticleSystem::getDirection() const
{ {
return direction; return direction;
@@ -543,6 +584,16 @@ void ParticleSystem::update(float dt)
} // while } // while
} }
bool ParticleSystem::getConstant(const char *in, AreaSpreadDistribution &out)
{
return distributions.find(in, out);
}
bool ParticleSystem::getConstant(AreaSpreadDistribution in, const char *&out)
{
return distributions.find(in, out);
}
} // opengl } // opengl
} // graphics } // graphics
} // love } // love
@@ -72,6 +72,16 @@ struct particle
class ParticleSystem : public Drawable class ParticleSystem : public Drawable
{ {
public: public:
/**
* Type of distribution new particles are drawn from: None, uniform, normal.
*/
enum AreaSpreadDistribution
{
DISTRIBUTION_NONE,
DISTRIBUTION_UNIFORM,
DISTRIBUTION_NORMAL,
DISTRIBUTION_MAX_ENUM,
};
/** /**
* Creates a particle system with the specified buffersize and sprite. * Creates a particle system with the specified buffersize and sprite.
@@ -122,6 +132,19 @@ public:
**/ **/
void setPosition(float x, float y); void setPosition(float x, float y);
/**
* Sets the emission area spread parameters and distribution type. The interpretation of
* the parameters depends on the distribution type:
*
* * None: Parameters are ignored. No area spread.
* * Uniform: Parameters denote maximal (symmetric) displacement from emitter position.
* * Normal: Parameters denote the standard deviation in x and y direction. x and y are assumed to be uncorrelated.
* @param x First parameter. Interpretation depends on distribution type.
* @param y Second parameter. Interpretation depends on distribution type.
* @param distribution Distribution type
* */
void setAreaSpread(AreaSpreadDistribution distribution, float x, float y);
/** /**
* Sets the direction and the spread of the particle emitter. * Sets the direction and the spread of the particle emitter.
* @param direction The direction (in degrees). * @param direction The direction (in degrees).
@@ -285,6 +308,16 @@ public:
**/ **/
const love::Vector &getPosition() const; const love::Vector &getPosition() const;
/**
* Returns area spread distribution type.
*/
AreaSpreadDistribution getAreaSpreadDistribution() const;
/**
* Returns area spread parameters.
*/
const love::Vector &getAreaSpreadParameters() const;
/** /**
* Returns the direction of the emitter (in degrees). * Returns the direction of the emitter (in degrees).
**/ **/
@@ -357,6 +390,9 @@ public:
* @param dt Time since last update. * @param dt Time since last update.
**/ **/
void update(float dt); void update(float dt);
static bool getConstant(const char *in, AreaSpreadDistribution &out);
static bool getConstant(AreaSpreadDistribution in, const char *&out);
protected: protected:
// The max amount of particles. // The max amount of particles.
@@ -386,6 +422,10 @@ protected:
// The relative position of the particle emitter. // The relative position of the particle emitter.
love::Vector position; love::Vector position;
// Emission area spread.
AreaSpreadDistribution areaSpreadDistribution;
love::Vector areaSpread;
// The lifetime of the particle emitter (-1 means infinite) and the life it has left. // The lifetime of the particle emitter (-1 means infinite) and the life it has left.
float lifetime; float lifetime;
float life; float life;
@@ -439,6 +479,9 @@ protected:
void add(); void add();
void remove(particle *p); void remove(particle *p);
static StringMap<AreaSpreadDistribution, DISTRIBUTION_MAX_ENUM>::Entry distributionsEntries[];
static StringMap<AreaSpreadDistribution, DISTRIBUTION_MAX_ENUM> distributions;
}; };
} // opengl } // opengl
+9 -6
View File
@@ -20,6 +20,7 @@
#include "PixelEffect.h" #include "PixelEffect.h"
#include "GLee.h" #include "GLee.h"
#include "Graphics.h"
namespace namespace
{ {
@@ -134,6 +135,7 @@ bool PixelEffect::loadVolatile()
} }
glDeleteShader(shader); glDeleteShader(shader);
return true; return true;
} }
@@ -149,24 +151,25 @@ void PixelEffect::unloadVolatile()
std::string PixelEffect::getGLSLVersion() std::string PixelEffect::getGLSLVersion()
{ {
// GL_SHADING_LANGUAGE_VERSION is not available in OpenGL < 2.1. // GL_SHADING_LANGUAGE_VERSION may not be available in OpenGL < 2.0.
// Be very pessimistic about the GLSL version in that case. const char *tmp = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
if (!GLEE_VERSION_2_1) if (NULL == tmp)
return "0.0"; return "0.0";
// the version string always begins with a version number of the format // the version string always begins with a version number of the format
// major_number.minor_number // major_number.minor_number
// or // or
// major_number.minor_number.release_number // major_number.minor_number.release_number
std::string versionString((const char *)glGetString(GL_SHADING_LANGUAGE_VERSION)); // we can keep release_number, since it does not affect the check below.
size_t minorEndPos = versionString.find(" "); std::string versionString(tmp);
size_t minorEndPos = versionString.find(' ');
return versionString.substr(0, minorEndPos); return versionString.substr(0, minorEndPos);
} }
bool PixelEffect::isSupported() bool PixelEffect::isSupported()
{ {
return GLEE_VERSION_2_0 && GLEE_ARB_shader_objects && GLEE_ARB_fragment_shader && getGLSLVersion() >= "1.2"; return GLEE_VERSION_2_0 && getGLSLVersion() >= "1.2";
} }
std::string PixelEffect::getWarnings() const std::string PixelEffect::getWarnings() const
-11
View File
@@ -113,17 +113,6 @@ void Quad::flip(bool x, bool y)
} }
} }
void Quad::mirror(bool x, bool y)
{
for (size_t i = 0; i < NUM_VERTICES; ++i)
{
if (x)
vertices[i].s = 1.0f - vertices[i].s;
if (y)
vertices[i].t = 1.0f - vertices[i].t;
}
}
const vertex *Quad::getVertices() const const vertex *Quad::getVertices() const
{ {
return vertices; return vertices;
-1
View File
@@ -54,7 +54,6 @@ public:
Viewport getViewport() const; Viewport getViewport() const;
void flip(bool x, bool y); void flip(bool x, bool y);
void mirror(bool x, bool y);
/** /**
* Gets a pointer to the vertices. * Gets a pointer to the vertices.
@@ -181,6 +181,16 @@ int w_Canvas_getHeight(lua_State *L)
return 1; return 1;
} }
int w_Canvas_getType(lua_State *L)
{
Canvas *canvas = luax_checkcanvas(L, 1);
Canvas::TextureType type = canvas->getTextureType();
const char *str;
Canvas::getConstant(type, str);
lua_pushstring(L, str);
return 1;
}
static const luaL_Reg functions[] = static const luaL_Reg functions[] =
{ {
{ "renderTo", w_Canvas_renderTo }, { "renderTo", w_Canvas_renderTo },
@@ -192,6 +202,7 @@ static const luaL_Reg functions[] =
{ "clear", w_Canvas_clear }, { "clear", w_Canvas_clear },
{ "getWidth", w_Canvas_getWidth }, { "getWidth", w_Canvas_getWidth },
{ "getHeight", w_Canvas_getHeight }, { "getHeight", w_Canvas_getHeight },
{ "getType", w_Canvas_getType },
{ 0, 0 } { 0, 0 }
}; };
@@ -43,6 +43,7 @@ int w_Canvas_getWrap(lua_State *L);
int w_Canvas_clear(lua_State *L); int w_Canvas_clear(lua_State *L);
int w_Canvas_getWidth(lua_State *L); int w_Canvas_getWidth(lua_State *L);
int w_Canvas_getHeight(lua_State *L); int w_Canvas_getHeight(lua_State *L);
int w_Canvas_getType(lua_State *L);
extern "C" int luaopen_canvas(lua_State *L); extern "C" int luaopen_canvas(lua_State *L);
} // opengl } // opengl
+19 -7
View File
@@ -361,6 +361,9 @@ int w_newImageFont(lua_State *L)
Image::Filter img_filter; Image::Filter img_filter;
bool setFilter = false; bool setFilter = false;
// For the filter modes..
int startIndex = 2;
// Convert to ImageData if necessary. // Convert to ImageData if necessary.
if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T) || (luax_istype(L, 1, DATA_T) && !luax_istype(L, 1, IMAGE_IMAGE_DATA_T))) if (lua_isstring(L, 1) || luax_istype(L, 1, FILESYSTEM_FILE_T) || (luax_istype(L, 1, DATA_T) && !luax_istype(L, 1, IMAGE_IMAGE_DATA_T)))
luax_convobj(L, 1, "image", "newImageData"); luax_convobj(L, 1, "image", "newImageData");
@@ -379,16 +382,17 @@ int w_newImageFont(lua_State *L)
{ {
int idxs[] = {1, 2}; int idxs[] = {1, 2};
luax_convobj(L, idxs, 2, "font", "newRasterizer"); luax_convobj(L, idxs, 2, "font", "newRasterizer");
startIndex = 3; // There's a glyphs args in there, move up
} }
love::font::Rasterizer *rasterizer = luax_checktype<love::font::Rasterizer>(L, 1, "Rasterizer", FONT_RASTERIZER_T); love::font::Rasterizer *rasterizer = luax_checktype<love::font::Rasterizer>(L, 1, "Rasterizer", FONT_RASTERIZER_T);
if (lua_isstring(L, 2) && lua_isstring(L, 3)) if (lua_isstring(L, startIndex) && lua_isstring(L, startIndex+1))
{ {
Image::FilterMode min; Image::FilterMode min;
Image::FilterMode mag; Image::FilterMode mag;
const char *minstr = luaL_checkstring(L, 2); const char *minstr = luaL_checkstring(L, startIndex);
const char *magstr = luaL_checkstring(L, 3); const char *magstr = luaL_checkstring(L, startIndex+1);
if (!Image::getConstant(minstr, min)) if (!Image::getConstant(minstr, min))
return luaL_error(L, "Invalid filter mode: %s", minstr); return luaL_error(L, "Invalid filter mode: %s", minstr);
if (!Image::getConstant(magstr, mag)) if (!Image::getConstant(magstr, mag))
@@ -449,14 +453,18 @@ int w_newParticleSystem(lua_State *L)
int w_newCanvas(lua_State *L) int w_newCanvas(lua_State *L)
{ {
// check if width and height are given. else default to screen dimensions. // check if width and height are given. else default to screen dimensions.
int width = luaL_optint(L, 1, instance->getWidth()); int width = luaL_optint(L, 1, instance->getWidth());
int height = luaL_optint(L, 2, instance->getHeight()); int height = luaL_optint(L, 2, instance->getHeight());
glGetError(); // clear opengl error flag const char *str = luaL_optstring(L, 3, "normal");
Canvas::TextureType texture_type;
if (!Canvas::getConstant(str, texture_type))
return luaL_error(L, "Invalid canvas type: %s", str);
Canvas *canvas = NULL; Canvas *canvas = NULL;
try try
{ {
canvas = instance->newCanvas(width, height); canvas = instance->newCanvas(width, height, texture_type);
} }
catch(Exception &e) catch(Exception &e)
{ {
@@ -874,6 +882,10 @@ int w_isSupported(lua_State *L)
if (!Canvas::isSupported()) if (!Canvas::isSupported())
supported = false; supported = false;
break; break;
case Graphics::SUPPORT_HDR_CANVAS:
if (!Canvas::isHdrSupported())
supported = false;
break;
case Graphics::SUPPORT_PIXELEFFECT: case Graphics::SUPPORT_PIXELEFFECT:
if (!PixelEffect::isSupported()) if (!PixelEffect::isSupported())
supported = false; supported = false;
@@ -86,6 +86,24 @@ int w_ParticleSystem_setPosition(lua_State *L)
return 0; return 0;
} }
int w_ParticleSystem_setAreaSpread(lua_State *L)
{
ParticleSystem *t = luax_checkparticlesystem(L, 1);
ParticleSystem::AreaSpreadDistribution distribution;
const char *str = luaL_checkstring(L, 2);
if (!ParticleSystem::getConstant(str, distribution))
return luaL_error(L, "Invalid distribution: '%s'", str);
float x = (float)luaL_checknumber(L, 3);
float y = (float)luaL_checknumber(L, 4);
if (x < 0.0f || y < 0.0f)
return luaL_error(L, "Invalid area spread parameters (must be >= 0)");
t->setAreaSpread(distribution, x, y);
return 0;
}
int w_ParticleSystem_setDirection(lua_State *L) int w_ParticleSystem_setDirection(lua_State *L)
{ {
ParticleSystem *t = luax_checkparticlesystem(L, 1); ParticleSystem *t = luax_checkparticlesystem(L, 1);
@@ -273,6 +291,21 @@ int w_ParticleSystem_getPosition(lua_State *L)
return 2; return 2;
} }
int w_ParticleSystem_getAreaSpread(lua_State *L)
{
ParticleSystem *t = luax_checkparticlesystem(L, 1);
ParticleSystem::AreaSpreadDistribution distribution = t-> getAreaSpreadDistribution();
const char *str;
ParticleSystem::getConstant(distribution, str);
const love::Vector &p = t->getAreaSpreadParameters();
lua_pushstring(L, str);
lua_pushnumber(L, p.x);
lua_pushnumber(L, p.y);
return 3;
}
int w_ParticleSystem_getDirection(lua_State *L) int w_ParticleSystem_getDirection(lua_State *L)
{ {
ParticleSystem *t = luax_checkparticlesystem(L, 1); ParticleSystem *t = luax_checkparticlesystem(L, 1);
@@ -373,6 +406,7 @@ static const luaL_Reg functions[] =
{ "setLifetime", w_ParticleSystem_setLifetime }, { "setLifetime", w_ParticleSystem_setLifetime },
{ "setParticleLife", w_ParticleSystem_setParticleLife }, { "setParticleLife", w_ParticleSystem_setParticleLife },
{ "setPosition", w_ParticleSystem_setPosition }, { "setPosition", w_ParticleSystem_setPosition },
{ "setAreaSpread", w_ParticleSystem_setAreaSpread },
{ "setDirection", w_ParticleSystem_setDirection }, { "setDirection", w_ParticleSystem_setDirection },
{ "setSpread", w_ParticleSystem_setSpread }, { "setSpread", w_ParticleSystem_setSpread },
{ "setRelativeDirection", w_ParticleSystem_setRelativeDirection }, { "setRelativeDirection", w_ParticleSystem_setRelativeDirection },
@@ -390,6 +424,7 @@ static const luaL_Reg functions[] =
{ "getX", w_ParticleSystem_getX }, { "getX", w_ParticleSystem_getX },
{ "getY", w_ParticleSystem_getY }, { "getY", w_ParticleSystem_getY },
{ "getPosition", w_ParticleSystem_getPosition }, { "getPosition", w_ParticleSystem_getPosition },
{ "getAreaSpread", w_ParticleSystem_getAreaSpread },
{ "getDirection", w_ParticleSystem_getDirection }, { "getDirection", w_ParticleSystem_getDirection },
{ "getSpread", w_ParticleSystem_getSpread }, { "getSpread", w_ParticleSystem_getSpread },
{ "getOffsetX", w_ParticleSystem_getOffsetX }, { "getOffsetX", w_ParticleSystem_getOffsetX },
@@ -143,19 +143,38 @@ int w_SpriteBatch_getImage(lua_State *L)
int w_SpriteBatch_setColor(lua_State *L) int w_SpriteBatch_setColor(lua_State *L)
{ {
SpriteBatch *t = luax_checkspritebatch(L, 1); SpriteBatch *t = luax_checkspritebatch(L, 1);
Color c;
if (lua_gettop(L) <= 1) if (lua_gettop(L) <= 1)
{
t->setColor(); t->setColor();
return 0;
}
else if (lua_istable(L, 2))
{
lua_rawgeti(L, 2, 1);
c.r = (unsigned char) luaL_checkint(L, -1);
lua_pop(L, 1);
lua_rawgeti(L, 2, 2);
c.g = (unsigned char) luaL_checkint(L, -1);
lua_pop(L, 1);
lua_rawgeti(L, 2, 3);
c.b = (unsigned char) luaL_checkint(L, -1);
lua_pop(L, 1);
lua_rawgeti(L, 2, 4);
c.a = (unsigned char) luaL_optint(L, -1, 255);
lua_pop(L, 1);
}
else else
{ {
Color c;
c.r = (unsigned char)luaL_checkint(L, 2); c.r = (unsigned char)luaL_checkint(L, 2);
c.g = (unsigned char)luaL_checkint(L, 3); c.g = (unsigned char)luaL_checkint(L, 3);
c.b = (unsigned char)luaL_checkint(L, 4); c.b = (unsigned char)luaL_checkint(L, 4);
c.a = (unsigned char)luaL_optint(L, 5, 255); c.a = (unsigned char)luaL_optint(L, 5, 255);
t->setColor(c);
} }
t->setColor(c);
return 0; return 0;
} }
+15 -1
View File
@@ -39,7 +39,21 @@ Contact::Contact(b2Contact *contact)
Contact::~Contact() Contact::~Contact()
{ {
Memoizer::remove(contact); invalidate();
}
void Contact::invalidate()
{
if (contact != NULL)
{
Memoizer::remove(contact);
contact = NULL;
}
}
bool Contact::isValid()
{
return contact != NULL ? true : false;
} }
int Contact::getPositions(lua_State *L) int Contact::getPositions(lua_State *L)
+12
View File
@@ -59,6 +59,18 @@ public:
virtual ~Contact(); virtual ~Contact();
/**
* Removes the b2Contact pointer from Memoizer and sets it
* to null on the Contact.
**/
void invalidate();
/**
* Returns if the Contact still points to a valid b2Contact.
* @return True if the contact is still valid or false if it has been destroyed.
**/
bool isValid();
/** /**
* Gets the position of each point of contact. * Gets the position of each point of contact.
* @return The position along the x-axis. * @return The position along the x-axis.
+25 -14
View File
@@ -77,9 +77,13 @@ void World::ContactCallback::process(b2Contact *contact, const b2ContactImpulse
throw love::Exception("A fixture has escaped Memoizer!"); throw love::Exception("A fixture has escaped Memoizer!");
} }
Contact *c = new Contact(contact); Contact *cobj = (Contact *)Memoizer::find(contact);
if (!cobj)
cobj = new Contact(contact);
else
cobj->retain();
luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void *)c); luax_newtype(L, "Contact", (PHYSICS_CONTACT_T), (void *)cobj);
int args = 3; int args = 3;
if (impulse) if (impulse)
@@ -117,12 +121,12 @@ bool World::ContactFilter::process(Fixture *a, Fixture *b)
a->getFilterData(filterA); a->getFilterData(filterA);
b->getFilterData(filterB); b->getFilterData(filterB);
if (filterA[2] != 0 && // 0 is the default group, so this does not count if (filterA[2] != 0 && // 0 is the default group, so this does not count
filterA[2] == filterB[2]) // if they are in the same group filterA[2] == filterB[2]) // if they are in the same group
return filterA[2] > 0; // Negative indexes mean you don't collide return filterA[2] > 0; // Negative indexes mean you don't collide
if ((filterA[1] & filterB[0]) == 0 || if ((filterA[1] & filterB[0]) == 0 ||
(filterB[1] & filterA[0]) == 0) (filterB[1] & filterA[0]) == 0)
return false; // A and B aren't set to collide return false; // A and B aren't set to collide
if (ref != 0) if (ref != 0)
@@ -290,6 +294,11 @@ void World::BeginContact(b2Contact *contact)
void World::EndContact(b2Contact *contact) void World::EndContact(b2Contact *contact)
{ {
end.process(contact); end.process(contact);
// Letting the Contact know that the b2Contact will be destroyed any second.
Contact *c = (Contact *)Memoizer::find(contact);
if (c != NULL)
c->invalidate();
} }
void World::PreSolve(b2Contact *contact, const b2Manifold *oldManifold) void World::PreSolve(b2Contact *contact, const b2Manifold *oldManifold)
@@ -332,19 +341,19 @@ int World::setCallbacks(lua_State *L)
case 4: case 4:
if (postsolve.ref) if (postsolve.ref)
delete postsolve.ref; delete postsolve.ref;
postsolve.ref = luax_refif (L, LUA_TFUNCTION); postsolve.ref = luax_refif(L, LUA_TFUNCTION);
case 3: case 3:
if (presolve.ref) if (presolve.ref)
delete presolve.ref; delete presolve.ref;
presolve.ref = luax_refif (L, LUA_TFUNCTION); presolve.ref = luax_refif(L, LUA_TFUNCTION);
case 2: case 2:
if (end.ref) if (end.ref)
delete end.ref; delete end.ref;
end.ref = luax_refif (L, LUA_TFUNCTION); end.ref = luax_refif(L, LUA_TFUNCTION);
case 1: case 1:
if (begin.ref) if (begin.ref)
delete begin.ref; delete begin.ref;
begin.ref = luax_refif (L, LUA_TFUNCTION); begin.ref = luax_refif(L, LUA_TFUNCTION);
} }
return 0; return 0;
@@ -364,7 +373,7 @@ int World::setContactFilter(lua_State *L)
luax_assert_argc(L, 1); luax_assert_argc(L, 1);
if (filter.ref) if (filter.ref)
delete filter.ref; delete filter.ref;
filter.ref = luax_refif (L, LUA_TFUNCTION); filter.ref = luax_refif(L, LUA_TFUNCTION);
return 0; return 0;
} }
@@ -468,8 +477,10 @@ int World::getContactList(lua_State *L) const
{ {
if (!c) break; if (!c) break;
Contact *contact = (Contact *)Memoizer::find(c); Contact *contact = (Contact *)Memoizer::find(c);
if (!contact) throw love::Exception("A contact has escaped Memoizer!"); if (!contact)
contact->retain(); contact = new Contact(c);
else
contact->retain();
luax_newtype(L, "Contact", PHYSICS_CONTACT_T, (void *)contact); luax_newtype(L, "Contact", PHYSICS_CONTACT_T, (void *)contact);
lua_rawseti(L, -2, i); lua_rawseti(L, -2, i);
i++; i++;
@@ -494,7 +505,7 @@ int World::queryBoundingBox(lua_State *L)
box.lowerBound = Physics::scaleDown(b2Vec2(lx, ly)); box.lowerBound = Physics::scaleDown(b2Vec2(lx, ly));
box.upperBound = Physics::scaleDown(b2Vec2(ux, uy)); box.upperBound = Physics::scaleDown(b2Vec2(ux, uy));
if (query.ref) delete query.ref; if (query.ref) delete query.ref;
query.ref = luax_refif (L, LUA_TFUNCTION); query.ref = luax_refif(L, LUA_TFUNCTION);
world->QueryAABB(&query, box); world->QueryAABB(&query, box);
return 0; return 0;
} }
@@ -510,7 +521,7 @@ int World::rayCast(lua_State *L)
b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2)); b2Vec2 v2 = Physics::scaleDown(b2Vec2(x2, y2));
if (raycast.ref) if (raycast.ref)
delete raycast.ref; delete raycast.ref;
raycast.ref = luax_refif (L, LUA_TFUNCTION); raycast.ref = luax_refif(L, LUA_TFUNCTION);
world->RayCast(&raycast, v1, v2); world->RayCast(&raycast, v1, v2);
return 0; return 0;
} }
+4 -1
View File
@@ -29,7 +29,10 @@ namespace box2d
Contact *luax_checkcontact(lua_State *L, int idx) Contact *luax_checkcontact(lua_State *L, int idx)
{ {
return luax_checktype<Contact>(L, idx, "Contact", PHYSICS_CONTACT_T); Contact *c = luax_checktype<Contact>(L, idx, "Contact", PHYSICS_CONTACT_T);
if (!c->isValid())
luaL_error(L, "Attempt to use destroyed contact.");
return c;
} }
int w_Contact_getPositions(lua_State *L) int w_Contact_getPositions(lua_State *L)
+1 -1
View File
@@ -39,7 +39,7 @@ int w_World_update(lua_State *L)
{ {
World *t = luax_checkworld(L, 1); World *t = luax_checkworld(L, 1);
float dt = (float)luaL_checknumber(L, 2); float dt = (float)luaL_checknumber(L, 2);
t->update(dt); ASSERT_GUARD(t->update(dt);)
return 0; return 0;
} }
+2 -2
View File
@@ -74,11 +74,11 @@ public:
* @param sampleRate Samples per second, or quality of the audio. 44100 is a good value. * @param sampleRate Samples per second, or quality of the audio. 44100 is a good value.
* @return A Decoder object on success, or zero if no decoder could be found. * @return A Decoder object on success, or zero if no decoder could be found.
**/ **/
virtual Decoder *newDecoder(filesystem::File *file, int bufferSize) = 0; virtual Decoder *newDecoder(filesystem::FileData *file, int bufferSize) = 0;
}; // Sound }; // Sound
} // sound } // sound
} // love } // love
#endif // LOVE_SOUND_SOUND_H #endif // LOVE_SOUND_SOUND_H
+12 -4
View File
@@ -46,11 +46,19 @@ GmeDecoder::GmeDecoder(Data *data, const std::string &ext, int bufferSize)
num_tracks = gme_track_count(emu); num_tracks = gme_track_count(emu);
if (num_tracks <= 0) try
throw love::Exception("Game music file has no tracks"); {
if (num_tracks <= 0)
throw love::Exception("Game music file has no tracks");
if (gme_start_track(emu, cur_track) != 0) if (gme_start_track(emu, cur_track) != 0)
throw love::Exception("Could not start game music playback"); throw love::Exception("Could not start game music playback");
}
catch (love::Exception &)
{
gme_delete(emu);
throw;
}
} }
GmeDecoder::~GmeDecoder() GmeDecoder::~GmeDecoder()
+4
View File
@@ -27,7 +27,11 @@
#include "common/Data.h" #include "common/Data.h"
#include "Decoder.h" #include "Decoder.h"
#ifdef LOVE_MACOSX
#include <Game_Music_Emu/gme.h>
#else
#include <gme.h> #include <gme.h>
#endif
namespace love namespace love
{ {
+2 -5
View File
@@ -51,10 +51,9 @@ const char *Sound::getName() const
return "love.sound.lullaby"; return "love.sound.lullaby";
} }
sound::Decoder *Sound::newDecoder(love::filesystem::File *file, int bufferSize) sound::Decoder *Sound::newDecoder(love::filesystem::FileData *data, int bufferSize)
{ {
Data *data = file->read(); std::string ext = data->getExtension();
std::string ext = file->getExtension();
sound::Decoder *decoder = 0; sound::Decoder *decoder = 0;
@@ -76,8 +75,6 @@ sound::Decoder *Sound::newDecoder(love::filesystem::File *file, int bufferSize)
// else if (OtherDecoder::accept(ext)) // else if (OtherDecoder::accept(ext))
data->release();
return decoder; return decoder;
} }
+2 -2
View File
@@ -59,7 +59,7 @@ public:
const char *getName() const; const char *getName() const;
/// @copydoc love::sound::Sound::newDecoder /// @copydoc love::sound::Sound::newDecoder
sound::Decoder *newDecoder(love::filesystem::File *file, int bufferSize); sound::Decoder *newDecoder(love::filesystem::FileData *file, int bufferSize);
}; // Sound }; // Sound
@@ -67,4 +67,4 @@ public:
} // sound } // sound
} // love } // love
#endif // LOVE_SOUND_LULLABY_SOUND_H #endif // LOVE_SOUND_LULLABY_SOUND_H
+16 -3
View File
@@ -83,18 +83,31 @@ int w_newDecoder(lua_State *L)
if (lua_isstring(L, 1)) if (lua_isstring(L, 1))
luax_convobj(L, 1, "filesystem", "newFile"); luax_convobj(L, 1, "filesystem", "newFile");
love::filesystem::File *file = luax_checktype<love::filesystem::File>(L, 1, "File", FILESYSTEM_FILE_T); love::filesystem::FileData *data;
if (luax_istype(L, 1, FILESYSTEM_FILE_T))
{
love::filesystem::File *file = luax_checktype<love::filesystem::File>(L, 1, "File", FILESYSTEM_FILE_T);
data = file->read();
}
else
{
data = luax_checktype<love::filesystem::FileData>(L, 1, "FileData", FILESYSTEM_FILE_DATA_T);
data->retain();
}
int bufferSize = luaL_optint(L, 2, Decoder::DEFAULT_BUFFER_SIZE); int bufferSize = luaL_optint(L, 2, Decoder::DEFAULT_BUFFER_SIZE);
try try
{ {
Decoder *t = instance->newDecoder(file, bufferSize); Decoder *t = instance->newDecoder(data, bufferSize);
data->release();
if (t == 0) if (t == 0)
return luaL_error(L, "Extension \"%s\" not supported.", file->getExtension().c_str()); return luaL_error(L, "Extension \"%s\" not supported.", data->getExtension().c_str());
luax_newtype(L, "Decoder", SOUND_DECODER_T, (void *)t); luax_newtype(L, "Decoder", SOUND_DECODER_T, (void *)t);
} }
catch(love::Exception &e) catch(love::Exception &e)
{ {
data->release();
return luaL_error(L, e.what()); return luaL_error(L, e.what());
} }
+1 -1
View File
@@ -430,8 +430,8 @@ function love.run()
if love.draw then love.draw() end if love.draw then love.draw() end
end end
if love.timer then love.timer.sleep(0.001) end
if love.graphics then love.graphics.present() end if love.graphics then love.graphics.present() end
if love.timer then love.timer.sleep(0.001) end
end end
+3 -3
View File
@@ -737,12 +737,12 @@ const unsigned char boot_lua[] =
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x20, 0x74, 0x68, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x20, 0x74, 0x68,
0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x74, 0x68,
0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x65, 0x65,
0x70, 0x28, 0x30, 0x2e, 0x30, 0x30, 0x31, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x73,
0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63,
0x73, 0x2e, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a, 0x73, 0x2e, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x20, 0x74, 0x68,
0x65, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x73, 0x6c, 0x65, 0x65,
0x70, 0x28, 0x30, 0x2e, 0x30, 0x30, 0x31, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x65, 0x6e, 0x64, 0x0a, 0x65, 0x6e, 0x64, 0x0a,
0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+15 -18
View File
@@ -1284,24 +1284,20 @@ do
end end
-- PIXEL EFFECTS -- PIXEL EFFECTS
local GLSL_HEADER_LINE_COUNT = 6
local GLSL_HEADER = [[#version 120
#define number float
#define Image sampler2D
#define extern uniform
#define Texel texture2D
uniform sampler2D _tex0_;]]
local GLSL_FOOTER = [[void main() {
// fix weird crashing issue in OSX when _tex0_ is unused within effect()
float dummy = texture2D(_tex0_, vec2(.5)).r;
gl_FragColor = effect(gl_Color, _tex0_, gl_TexCoord[0].xy, gl_FragCoord.xy);
}]]
function love.graphics._effectCodeToGLSL(code) function love.graphics._effectCodeToGLSL(code)
local header = [[#version 120 return table.concat{GLSL_HEADER, "\n", code, GLSL_FOOTER}
#define number float
#define Image sampler2D
#define extern uniform
#define Texel texture2D
uniform sampler2D _tex0_;]]
local footer = [[void main() {
// fix weird crashing issue in OSX when _tex0_ is unused within effect()
float dummy = texture2D(_tex0_, vec2(.5)).r;
gl_FragColor = effect(gl_Color, _tex0_, gl_TexCoord[0].xy, gl_FragCoord.xy);
}]]
local function include(quoted_path) return (love.filesystem.read(quoted_path:sub(2,-2))) end
code = code:gsub("#include (%b'')", include)
code = code:gsub('#include (%b"")', include)
return table.concat{header, "\n", code, footer}
end end
function love.graphics._transformGLSLErrorMessages(message) function love.graphics._transformGLSLErrorMessages(message)
@@ -1317,7 +1313,8 @@ do
linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$") linenumber, what, message = l:match("^%w+: 0:(%d+):%s*(%w+)%([^%)]+%)%s*(.+)$")
end end
if linenumber and what and message then if linenumber and what and message then
lines[#lines+1] = ("Line %d: %s: %s"):format(linenumber - 5, what, message) linenumber = linenumber - GLSL_HEADER_LINE_COUNT
lines[#lines+1] = ("Line %d: %s: %s"):format(linenumber, what, message)
end end
end end
-- did not match any known error messages -- did not match any known error messages
+38 -44
View File
@@ -6260,52 +6260,43 @@ const unsigned char graphics_lua[] =
0x69, 0x6e, 0x74, 0x66, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x69, 0x6e, 0x74, 0x66, 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x2d, 0x2d, 0x20, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x20, 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x53, 0x0a, 0x09, 0x2d, 0x2d, 0x20, 0x50, 0x49, 0x58, 0x45, 0x4c, 0x20, 0x45, 0x46, 0x46, 0x45, 0x43, 0x54, 0x53, 0x0a,
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52,
0x5f, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x20, 0x3d, 0x20, 0x36, 0x0a,
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52,
0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x32, 0x30, 0x0a,
0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x66, 0x6c,
0x6f, 0x61, 0x74, 0x0a,
0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x73, 0x61, 0x6d,
0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x0a,
0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x75, 0x6e,
0x69, 0x66, 0x6f, 0x72, 0x6d, 0x0a,
0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x78,
0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x0a,
0x09, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44,
0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x3b, 0x5d, 0x5d, 0x0a,
0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x46, 0x4f, 0x4f, 0x54, 0x45, 0x52,
0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a,
0x09, 0x09, 0x2f, 0x2f, 0x20, 0x66, 0x69, 0x78, 0x20, 0x77, 0x65, 0x69, 0x72, 0x64, 0x20, 0x63, 0x72, 0x61,
0x73, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x4f, 0x53, 0x58,
0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x20, 0x69, 0x73, 0x20, 0x75, 0x6e,
0x75, 0x73, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74,
0x28, 0x29, 0x0a,
0x09, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x74, 0x65,
0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76, 0x65,
0x63, 0x32, 0x28, 0x2e, 0x35, 0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
0x09, 0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x65,
0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x67, 0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x5f, 0x74,
0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x67, 0x6c, 0x5f, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x5b,
0x30, 0x5d, 0x2e, 0x78, 0x79, 0x2c, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72,
0x64, 0x2e, 0x78, 0x79, 0x29, 0x3b, 0x0a,
0x09, 0x7d, 0x5d, 0x5d, 0x0a,
0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61,
0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x5f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x54, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x5f, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x54,
0x6f, 0x47, 0x4c, 0x53, 0x4c, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a, 0x6f, 0x47, 0x4c, 0x53, 0x4c, 0x28, 0x63, 0x6f, 0x64, 0x65, 0x29, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x5b,
0x5b, 0x23, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x32, 0x30, 0x0a,
0x09, 0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x66,
0x6c, 0x6f, 0x61, 0x74, 0x0a,
0x09, 0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x20, 0x73, 0x61,
0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x0a,
0x09, 0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x75,
0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x0a,
0x09, 0x09, 0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x54, 0x65, 0x78, 0x65, 0x6c, 0x20, 0x74, 0x65,
0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x0a,
0x09, 0x09, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32,
0x44, 0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x3b, 0x5d, 0x5d, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x5b,
0x5b, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x20, 0x7b, 0x0a,
0x09, 0x09, 0x09, 0x2f, 0x2f, 0x20, 0x66, 0x69, 0x78, 0x20, 0x77, 0x65, 0x69, 0x72, 0x64, 0x20, 0x63, 0x72,
0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x4f, 0x53,
0x58, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x20, 0x69, 0x73, 0x20, 0x75,
0x6e, 0x75, 0x73, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x20, 0x65, 0x66, 0x66, 0x65, 0x63,
0x74, 0x28, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x64, 0x75, 0x6d, 0x6d, 0x79, 0x20, 0x3d, 0x20, 0x74,
0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x32, 0x44, 0x28, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x76,
0x65, 0x63, 0x32, 0x28, 0x2e, 0x35, 0x29, 0x29, 0x2e, 0x72, 0x3b, 0x0a,
0x09, 0x09, 0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20,
0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x28, 0x67, 0x6c, 0x5f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x5f,
0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x67, 0x6c, 0x5f, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64,
0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, 0x2c, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f,
0x72, 0x64, 0x2e, 0x78, 0x79, 0x29, 0x3b, 0x0a,
0x09, 0x09, 0x7d, 0x5d, 0x5d, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69,
0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x28, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x61, 0x74, 0x68,
0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x69, 0x6c,
0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x28, 0x71, 0x75, 0x6f, 0x74, 0x65,
0x64, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x3a, 0x73, 0x75, 0x62, 0x28, 0x32, 0x2c, 0x2d, 0x32, 0x29, 0x29, 0x29,
0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x3a, 0x67, 0x73, 0x75, 0x62,
0x28, 0x22, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x28, 0x25, 0x62, 0x27, 0x27, 0x29, 0x22,
0x2c, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x29, 0x0a,
0x09, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x3a, 0x67, 0x73, 0x75, 0x62,
0x28, 0x27, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x28, 0x25, 0x62, 0x22, 0x22, 0x29, 0x27,
0x2c, 0x20, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x29, 0x0a,
0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6e, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6e,
0x63, 0x61, 0x74, 0x7b, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2c, 0x20, 0x22, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x63, 0x61, 0x74, 0x7b, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x2c, 0x20, 0x22,
0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x7d, 0x0a, 0x5c, 0x6e, 0x22, 0x2c, 0x20, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x46, 0x4f,
0x4f, 0x54, 0x45, 0x52, 0x7d, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61, 0x09, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x72, 0x61,
0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x47, 0x4c, 0x70, 0x68, 0x69, 0x63, 0x73, 0x2e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x47, 0x4c,
@@ -6350,11 +6341,14 @@ const unsigned char graphics_lua[] =
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x61,
0x6e, 0x64, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x6e, 0x64, 0x20, 0x77, 0x68, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x6c,
0x69, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x2d, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x5f, 0x48,
0x45, 0x41, 0x44, 0x45, 0x52, 0x5f, 0x4c, 0x49, 0x4e, 0x45, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x5b, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2b, 0x31, 0x09, 0x09, 0x09, 0x09, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x5b, 0x23, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2b, 0x31,
0x5d, 0x20, 0x3d, 0x20, 0x28, 0x22, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x25, 0x64, 0x3a, 0x20, 0x25, 0x73, 0x3a, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x22, 0x4c, 0x69, 0x6e, 0x65, 0x20, 0x25, 0x64, 0x3a, 0x20, 0x25, 0x73, 0x3a,
0x20, 0x25, 0x73, 0x22, 0x29, 0x3a, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x6e, 0x20, 0x25, 0x73, 0x22, 0x29, 0x3a, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x6e,
0x75, 0x6d, 0x62, 0x65, 0x72, 0x20, 0x2d, 0x20, 0x35, 0x2c, 0x20, 0x77, 0x68, 0x61, 0x74, 0x2c, 0x20, 0x6d, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x20, 0x77, 0x68, 0x61, 0x74, 0x2c, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x29, 0x0a, 0x67, 0x65, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x09, 0x09, 0x2d, 0x2d, 0x20, 0x64, 0x69, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68,